बकवास से भरी किताबें: लिमरिक्स की पहचान करें


15

जैसा कि हम सभी जानते हैं कि लिमरिक, एएबीबीए कविता योजना और एक एनापस्टिक मीटर (जो भी हो) के साथ छोटी-छोटी, पाँच-पंक्ति वाली, कभी-कभी-छोटी कविताएँ होती हैं:

एक लिमरिक की बेतुकी
लाइन एक और लाइन पांच कविता को शब्द में लिखना
और जैसा कि आपने माना है कि
वे दूसरी
पंक्ति के साथ गाया जाता है चौथी पंक्ति को तीसरे के साथ गाया जाना चाहिए

आपको सबसे छोटा प्रोग्राम लिखने का काम सौंपा जाता है, जब एक इनपुट टेक्स्ट खिलाया जाता है, तो यह प्रिंट करता है कि क्या यह सोचता है कि इनपुट एक वैध लिमिस्टिक है। इनपुट या तो कमांड लाइन पर या मानक इनपुट के माध्यम से आपके विकल्प पर हो सकता है, और आउटपुट आपके विकल्प पर फिर से एक सरल "Y" / "N" या एक आत्मविश्वास स्कोर हो सकता है।

यहाँ एक सही लिमरिक का एक और उदाहरण दिया गया है:

एक यंग लेडी थी जिसकी आंखें
रंग और आकार के रूप में अद्वितीय
थीं जब उसने उन्हें चौड़ा किया तो
लोगों ने सभी को एक तरफ कर दिया
और आश्चर्य में पड़ गए

लेकिन नीचे की कविता स्पष्ट रूप से एक सीमा नहीं है, क्योंकि यह कविता नहीं है:

सेंट मधुमक्खियों का एक बूढ़ा आदमी
था जो एक ततैया द्वारा हाथ में डंक मार रहा था।
जब पूछा गया, "क्या यह चोट लगी है?"
उसने जवाब दिया, "नहीं, यह नहीं है,
मुझे बहुत खुशी है कि यह एक सींग नहीं था।"

न ही यह एक है, क्योंकि मीटर सभी गलत है:

मैंने बर्लिन के एक शख्स के बारे में सुना,
जिसने उस कमरे से नफरत की थी,
जब मैंने पूछा था कि
वह यह क्यों कहता है कि वह एक व्यंग के साथ कहेगा:
"ठीक है, तुम देखो, कल रात को वहाँ कुछ हुडलूम थे, जो चारों ओर जश्न मना रहे थे, जो डर्स को जीत रहे थे। विश्व कप, और वे वास्तव में बहुत जोर से थे इसलिए मैं डिनर के कारण सो नहीं सका। "

सुराग

यहां कुछ सुराग दिए गए हैं जिनका उपयोग आप यह तय करने के लिए कर सकते हैं कि आपका इनपुट लिमरिक है या नहीं:

  • लाइमिक्स हमेशा पांच पंक्तियाँ लंबी होती हैं।
  • लाइन्स 1, 2 और 5 को तुकबंदी करनी चाहिए।
  • लाइन्स 3 और 4 को तुकबंदी करनी चाहिए।
  • लाइन्स 1, 2 और 5 में लगभग 3x3 = 9 सिलेबल्स हैं, जबकि तीसरे और चौथे में 2x3 = 6 सिलेबल्स हैं

ध्यान दें कि इनमें से कोई भी पहला हार्ड-एंड-फास्ट के अलावा नहीं है: 100% शुद्धता की रेटिंग असंभव है।

नियम

  • आपका प्रवेश एक निर्धारक फैशन में 3 के माध्यम से उदाहरण 1 को बहुत कम सही ढंग से वर्गीकृत करना चाहिए ।

  • आप कर रहे हैं , निश्चित रूप प्रोग्रामिंग भाषाओं विशेष रूप से (देखें इस प्रतियोगिता के लिए तैयार किया गया है के अलावा किसी भी प्रोग्रामिंग भाषा आप चाहते हैं उपयोग करने की अनुमति यहाँ )।

  • आपको अपनी प्रोग्रामिंग भाषा के मानक प्रसाद को छोड़कर किसी भी पुस्तकालय का उपयोग करने की अनुमति नहीं है

  • आप कर रहे हैं माना कि अनुमति इस फाइल , CMU स्फिंक्स pronounciation शब्दकोश, मौजूदा निर्देशिका में कहा जाता है 'सी' एक फ़ाइल में है।

  • आपको परीक्षण इनपुट के लिए हार्ड-कोड की अनुमति नहीं है: आपका कार्यक्रम एक सामान्य लिमरिक श्रेणीबद्धक होना चाहिए।

  • आप कर रहे हैं , माना कि इनपुट ASCII है की अनुमति किसी विशेष प्रारूपण के बिना (उदाहरण में) की तरह है, लेकिन अपने कार्यक्रम interpunction से नहीं भ्रमित किया जाना चाहिए।

बोनस

निम्नलिखित बोनस उपलब्ध हैं:

  • आपका कार्यक्रम एक लाइमेरिक के रूप में अपने परिणाम का उत्पादन करता है? 150 वर्ण लंबाई बोनस घटाएँ !
  • आपका कार्यक्रम भी सोननेट्स की सही पहचान करता है? 150 वर्ण अतिरिक्त लंबाई बोनस घटाएँ !
  • जब सॉनेट पर उपयोग किया जाता है तो आपका प्रोग्राम इसके परिणाम को सॉनेट के रूप में प्रदर्शित करता है? 100 वर्ण अतिरिक्त अतिरिक्त लंबाई बोनस घटाएँ !

आखिरकार...

यह याद रखना कि आप किस बोनस के लिए सोचते हैं कि आप पात्र हैं, यदि कोई है, और अपने स्कोर पर आने के लिए अपने वर्णों के बोनस को घटाएं। यह एक कोड गोल्फ प्रतियोगिता है: सबसे छोटी प्रविष्टि (यानी सबसे कम स्कोर वाली प्रविष्टि) जीतती है।

यदि आपको अधिक (सकारात्मक) परीक्षण डेटा की आवश्यकता है, तो OEDILF या बुक ऑफ नॉनसेंस देखें । नकारात्मक परीक्षण डेटा का निर्माण आसान होना चाहिए।

सौभाग्य!


यह code-challengeबोनस की वजह से होना चाहिए । कृपया टैग विवरण पढ़ें
user80551

2
@ user80551 मेटा पर आम सहमति अन्यथा प्रतीत होती है।
दरवाज़े

मैंने बोनस की प्रकृति को स्पष्ट किया है, मुझे आशा है कि भ्रम को साफ करता है।
वांडर नौटा

2
गूहूओ भालू!
अल्वोनेलोस

मुझे बोनस की समझ नहीं है। मैं एक लिमरिक के रूप में "Y" आउटपुट करने वाला कैसे हूं?
r3mainer

जवाबों:


8

अजगर: 400 - 150 - 150 = 100

सबसे छोटी स्क्रिप्ट जो मैं आ सकता था, वह है ...

import re,sys;f,e,c=re.findall,lambda l,w:f('^'+w.upper()+'  (.+)',l),lambda*v:all([a[i]==a[v[0]]for i in v]);a=[sum([[e(l,w)[0].split()for l in open('c')if e(l,w)][0]for w in f(r'\w+',v)],[])[-2:]for v in sys.stdin];n=len(a);print n==14and c(0,3,4,7)*c(1,2,5,6)*c(8,11)*c(9,12)*c(10,13)*"Sonnet"or"For a critic\nOf limerick\nWell-equipped\nIs this script.\n%s limerick!"%(n==5and c(0,1,4)and c(2,3))

... लेकिन यह भी कोशिश मत करो। यह मिलने वाले हर शब्द के लिए प्रदान किए गए शब्दकोश को पार्स करता है, इस प्रकार यह बहुत धीमा है। जब भी कोई शब्द शब्दकोश में नहीं होता है, तो भी एक त्रुटि उत्पन्न होती है।

हालांकि यह कोड अभी भी आवश्यकताओं को पूरा करता है: यह पहचानना कि क्या स्टड के माध्यम से पारित पाठ एक लिमरिक, एक सॉनेट या उन में से कोई भी नहीं है।

केवल 20 और वर्णों के साथ, यहाँ अनुकूलित संस्करण है:

import re,sys;f,e,c=re.findall,lambda l:f(r'^(\w+)  (.+)',l),lambda*v:all([a[i]==a[v[0]]for i in v]);d={e(l)[0][0]:e(l)[0][1].split()for l in open('c')if e(l)};a=[sum([d.get(w.upper(),[])for w in f(r'\w+',v)],[])[-2:]for v in sys.stdin];n=len(a);print n==14and c(0,3,4,7)*c(1,2,5,6)*c(8,11)*c(9,12)*c(10,13)*"Sonnet"or"For a critic\nOf limerick\nWell-equipped\nIs this script.\n%s limerick!"%(n==5and c(0,1,4)and c(2,3))

विशेषताएं

  • सोननेट्स को पहचानने में सक्षम (-150)
  • एक चूने वाले के साथ जवाब (-150)
  • अपेक्षाकृत तेज़: निष्पादन के लिए केवल एक फ़ाइल पार्सिंग

प्रयोग

cat poem.txt | python poem-check.py

3 अलग-अलग आउटपुट संभव हैं:

  • अगर यह मामला है तो एक लिमरिक इनपुट एक है
  • अगर यह मामला है तो एक लिमरिक यह कहना कि इनपुट एक नहीं है
  • "सॉनेट" यदि इनपुट को इस तरह से मान्यता प्राप्त है

स्पष्टीकरण के साथ विस्तारित कोड

import re, sys

# just a shortened version of the 're.findall' function...
f = re.findall
# function used to parse a line of the dictionary
e = lambda l:f(r'^(\w+)  (.+)', l)

# create a cache of the dictionary, where each word is associated with the list of phonemes it contains
d = {e(l)[0][0]:e(l)[0][1].split(' ') for l in open('c') if e(l)}

# for each verse (line) 'v' found in the input 'sys.stdin', create a list of the phoneme it contains;
# the result array 'a' contains a list, each item of it corresponding to the last two phonemes of a verse
a = [sum([d.get(w.upper(), []) for w in f(r'\w+',v)],[])[-2:] for v in sys.stdin]

# let's store the length of 'a' in 'n'; it is actually the number of verses in the input
n = len(a)
# function used to compare the rhymes of the lines which indexes are passed as arguments
c = lambda*v:all([a[i] == a[v[0]] for i in v])

# test if the input is a sonnet, aka: it has 14 verses, verses 0, 3, 4 and 7 rhyme together, verses 1, 2, 5 and 6 rhyme together, verses 8 and 11 rhyme together, verses 9 and 12 rhyme together, verses 10 and 13 rhyme together
if n==14 and c(0,3,4,7) and c(1,2,5,6) and c(8,11) and c(9,12) and c(10,13):
    print("Sonnet")
else:
    # test if the input is a limerick, aka: it has 5 verses, verses 0, 1 and 4 rhyme together, verses 2 and 3 rhyme together
    is_limerick = n==5 and c(0,1,4) and c(2,3)
    print("For critics\nOf limericks,\nWell-equipped\nIs this script.\n%s limerick!", is_limmerick)

सुंदर दिखाई देता है! मैंने अभी तक इसका परीक्षण नहीं किया है, लेकिन क्या आपको यकीन है कि यह "कमांड लाइन पर या मानक इनपुट के माध्यम से" इनपुट लेता है (प्रश्न देखें)? यदि नहीं, तो आपको इसे जोड़ना चाहिए (शायद sys.stdin.read()या open(sys.argv[1]).read()कहीं और) और पुनरावृत्ति करें।
वांडर नौटा

ठीक है! इसे सही किया :)
मैथ्यू रोडिक

एल्गोरिदम कैसे तुकबंदी के लिए जाँच करता है?
डेविड मार्क

प्रश्न में वांडर नौटा द्वारा प्रदान की गई फ़ाइल की मदद से! यह वास्तव में मदद की।
मैथ्यू रोडिक

1
साफ! एक शर्म की बात है कि मैं आपको दो बार परेशान नहीं कर सकता।
वांडर नौटा

2

ECMAScript 6 (138 अंक; फ़ायरफ़ॉक्स में प्रयास करें):

288- 150लिमेरिक (@ मैथियोरोडिक से पिन किए गए) सहित बोनस अंक।

a=i.split(d=/\r?\n/).map(x=>x.split(' '));b=/^\W?(\w+) .*? (\w+\d( [A-Z]+)*)$/;c.split('\r\n').map(x=>b.test(x)&&eval(x.replace(b,'d["$1"]="$2"')));e=f=>d[a[f][a[f].length-1]];alert('For critics\nOf limericks,\nWell-equipped\nIs this script.\n'+(a[4]&&e(0)==e(1)&e(0)==e(4))+' limerick!')

टिप्पणियाँ:

cडिक्शनरी फ़ाइल की सामग्रियों को शामिल करने के लिए वैरिएबल की अपेक्षा करता है , क्योंकि आप सादे ईसीएमएस्क्रिप्ट में फाइल नहीं पढ़ सकते हैं।

ECMAScript में मानक इनपुट नहीं है, लेकिन promptआम तौर पर इसे "मानक इनपुट" माना जाता है; हालाँकि, promptअधिकांश स्थानों (यदि सभी नहीं) ब्राउज़रों में रेखाएँ परिवर्तित होती हैं, तो मैं चर से इनपुट स्वीकार कर रहा हूँ i

अघोषित कोड:

// If you paste a string with multiple lines into a `prompt`, the browser replaces each line break with a space, for some reason.
//input = prompt();

// Split into lines, with each line split into words
lines = input.split('\n').map(x => x.split(' '));

dictionaryEntryRegEx = /^\W?(\w+) .*? (\w+\d( [A-Z]+)*)$/;
dictionary = {};
// Split it into
c.split(/\r?\n/).map(x => dictionaryEntryRegEx && eval(x.replace(dictionaryEntryRegEx, 'dictionary["$1"] = "$2"')));

// Get the last word in the line
getLastWordOfLine = (lineNumber) => dictionary[line[lineNumber][line[lineNumber].length - 1]]

alert('For critics\nOf limericks,\nWell-equipped\nIs this script.\n' + (lines[4] && getLastWordOfLine(0) === getLastWordOfLine(1) && getLastWordOfLine(0) === getLastWordOfLine(4)) + ' limerick!');

साफ! यह 'कमांड लाइन पर या मानक इनपुट के माध्यम से इनपुट' नहीं लेता है, हालांकि, जो प्रश्न द्वारा आवश्यक है। शायद आप इसे Node.js या कुछ और का उपयोग करने के लिए फिर से लिख सकते हैं।
वांडर नौटा

@WanderNauta धन्यवाद। कृपया नवीनतम संपादन देखें, क्योंकि मैं समझाता हूं कि मैं मानक इनपुट का उपयोग क्यों नहीं कर रहा हूं।
टूथब्रश
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.