आत्मनिरीक्षण प्रोग्रामिंग: कोड जो इसके स्रोत और इसके आउटपुट का विश्लेषण करता है


13

एक प्रोग्राम लिखें जो वर्णों की कुल संख्या और उसके स्रोत और उसके आउटपुट में प्रत्येक वर्ण की आवृत्ति को आउटपुट करता है। आपको उदाहरण में चित्रित प्रारूप का पालन करना चाहिए।

उदाहरण

अगर आपका कोड था

abb1

इसका उत्पादन करना होगा

My source has 4 characters.
1 is "a"
2 are "b"
1 is "1"
Besides unquoted numbers, my output has 383 characters.
34 are "
"
79 are " "
63 are """
2 are "'"
2 are ","
4 are "."
2 are "1"
2 are "B"
2 are "I"
2 are "M"
39 are "a"
4 are "b"
6 are "c"
4 are "d"
38 are "e"
3 are "g"
5 are "h"
4 are "i"
4 are "m"
3 are "n"
8 are "o"
3 are "p"
2 are "q"
38 are "r"
12 are "s"
8 are "t"
7 are "u"
3 are "y"
It's good to be a program.

(आउटपुट को stdout में जाना चाहिए।)

सूचना, उदाहरण के लिए, कि आउटपुट में दो पूंजीकृत मी होते हैं। एक के लिए Myऔर एक के लिए 2 are "M"। यह सभी वर्णों के लिए सही होना चाहिए ताकि आउटपुट किसी भी तरह से विरोधाभास न हो।

असंतृप्त आवृत्ति सेटों से बचने के लिए आउटपुट में अयोग्य संख्याओं को अनदेखा किया जाता है। उदाहरण के लिए, 1 is "1"दोनों 1 गिने जाते हैं तो गलत है। इसे पढ़ना चाहिए 2 are "1", लेकिन फिर एक 1 फिर से है।

प्रारूप स्पष्टीकरण

  • "" का उपयोग एकल चरित्र घटनाओं के लिए किया जाना चाहिए।

  • "हैं" का उपयोग कई वर्ण आवृत्तियों के लिए किया जाना चाहिए।

  • "यह" आउटपुट वर्णों की सूची में कभी भी प्रकट नहीं होना चाहिए क्योंकि यह बहुत ही अच्छा होगा। 1 is 'Z'अपने आप में जेड को संदर्भित करता है, इसलिए पूरी लाइन को हटाया जा सकता है।

  • तीन पूर्ण-वाक्य वाक्यांशों को वर्ण आवृत्ति सूचियों के साथ क्रम में प्रकट होना चाहिए (उदाहरण के रूप में दिखाता है)। तो आपका आउटपुट के साथ शुरू My source...और खत्म होगा ...be a program.। ध्यान दें कि आउटपुट के अंत में कोई नई रेखा नहीं है।

  • चरित्र आवृत्ति स्वयं किसी भी क्रम में हो सकती है।

  • न्यूलाइन्स को एक वर्ण के रूप में गिना जाता है (यदि वे \ r \ n हैं तो)।

प्रारूप चेकर

निम्नलिखित पायथन स्क्रिप्ट आपके कोड और उसके आउटपुट को स्ट्रिंग्स के रूप में लेती है और दावा करती है कि आउटपुट में कोई विरोधाभास नहीं है। यदि कुछ गलत है, तो यह एक उपयोगी त्रुटि संदेश प्रदान करता है। आप इसे ऑनलाइन डाउनलोड कर सकते हैं http://ideone.com/6H0ldu , इसे फोर्क करके, CODE और OUTPUT स्ट्रिंग्स को बदलकर, फिर इसे चलाकर। यह कभी भी झूठी सकारात्मकता या नकारात्मकता नहीं देगा (अपनी त्रुटि मुक्त मानकर)।

#Change the CODE and OUTPUT strings to test your program

CODE = r'''abb1'''

OUTPUT = r'''My source has 4 characters.
1 is "a"
2 are "b"
1 is "1"
Besides unquoted numbers, my output has 383 characters.
34 are "
"
79 are " "
63 are """
2 are "'"
2 are ","
4 are "."
2 are "1"
2 are "B"
2 are "I"
2 are "M"
39 are "a"
4 are "b"
6 are "c"
4 are "d"
38 are "e"
3 are "g"
5 are "h"
4 are "i"
4 are "m"
3 are "n"
8 are "o"
3 are "p"
2 are "q"
38 are "r"
12 are "s"
8 are "t"
7 are "u"
3 are "y"
It's good to be a program.'''

#######################################################

import re

amountPattern = r'(\d+) (is|are) "(.)"\n'

class IntrospectionException(Exception):
    pass

def getClaimedAmounts(string, errorOnIs):
    groups = re.findall(amountPattern, string, re.DOTALL)

    for amount, verb, char in groups:
        if verb == 'is':
            if errorOnIs:
                raise IntrospectionException('\'1 is "%s"\' is unnecessary' % char)
            elif amount != '1':
                raise IntrospectionException('At "%s", %s must use "are"' % (char, amount))
        elif verb == 'are' and amount == '1':
            raise IntrospectionException('At "%s", 1 must use "is"' % char)

    amounts = {}
    for amount, verb, char in groups:
        if char in amounts:
            raise IntrospectionException('Duplicate "%s" found' % char)
        amounts[char] = int(amount)
    return amounts

def getActualAmounts(string):
    amounts = {}
    for char in string:
        if char in amounts:
            amounts[char] += 1
        else:
            amounts[char] = 1
    return amounts

def compareAmounts(claimed, actual):
    for char in actual:
        if char not in claimed:
            raise IntrospectionException('The amounts list is missing "%s"' % char)
    for char in actual: #loop separately so missing character errors are all found first
        if claimed[char] != actual[char]:
            raise IntrospectionException('The amount of "%s" characters is %d, not %d' % (char, actual[char], claimed[char]))
    if claimed != actual:
        raise IntrospectionException('The amounts are somehow incorrect')

def isCorrect(code, output):
    p1 = r'^My source has (\d+) characters\.\n'
    p2 = r'Besides unquoted numbers, my output has (\d+) characters\.\n'
    p3 = r"It's good to be a program\.$"
    p4 = '%s(%s)*%s(%s)*%s' % (p1, amountPattern, p2, amountPattern, p3)

    for p in [p1, p2, p3, p4]:
        if re.search(p, output, re.DOTALL) == None:
            raise IntrospectionException('Did not match the regex "%s"' % p)

    claimedCodeSize = int(re.search(p1, output).groups()[0])
    actualCodeSize = len(code)
    if claimedCodeSize != actualCodeSize:
        raise IntrospectionException('The code length is %d, not %d' % (actualCodeSize, claimedCodeSize))

    filteredOutput = re.sub(r'([^"])\d+([^"])', r'\1\2', output)

    claimedOutputSize = int(re.search(p2, output).groups()[0])
    actualOutputSize = len(filteredOutput)
    if claimedOutputSize != actualOutputSize:
        raise IntrospectionException('The output length (excluding unquoted numbers) is %d, not %d' % (actualOutputSize, claimedOutputSize))

    splitIndex = re.search(p2, output).start()

    claimedCodeAmounts = getClaimedAmounts(output[:splitIndex], False)
    actualCodeAmounts = getActualAmounts(code)
    compareAmounts(claimedCodeAmounts, actualCodeAmounts)

    claimedOutputAmounts = getClaimedAmounts(output[splitIndex:], True)
    actualOutputAmounts = getActualAmounts(filteredOutput)
    compareAmounts(claimedOutputAmounts, actualOutputAmounts)

def checkCorrectness():
    try:
        isCorrect(CODE, OUTPUT)
        print 'Everything is correct!'
    except IntrospectionException as e:
        print 'Failed: %s.' % e

checkCorrectness()

स्कोरिंग

यह कोड-गोल्फ है। सबसे कम पात्रों के साथ सबमिशन जीतता है। सबमिशन को मान्य होने के लिए प्रारूप चेकर को पास करना होगा। मानक कमियां लागू होती हैं, हालांकि आप अपना स्वयं का स्रोत कोड पढ़ सकते हैं और / या अपना आउटपुट हार्डकोड कर सकते हैं


क्या आपके स्वयं के स्रोत फ़ाइल को पढ़ने की अनुमति है?
वेंटरो

@MrLore अन्य त्रुटियाँ हो सकती हैं, लेकिन मुझे अभी पता चला है कि ट्रिपल उद्धरण ('' ') अभी भी बैकलैश के साथ चीजों से बचता है। यह आपकी समस्या से संबंधित हो सकता है। मैं अब इसे ठीक कर रहा हूं।
केल्विन के शौक

@ वेंटरो निश्चित रूप से!
केल्विन के

@MrLore regexps कुछ झूठी सकारात्मक अनुमति देता है, हाँ। ट्रिपल उद्धरण के अंदर बैकस्लैश के साथ समस्या को ठीक करने के लिए, कच्चे तार ( r'''CODE''') का उपयोग करें ।
वेंटरो

1
@ मर्लोर फिक्स्ड अनसैप्ड डॉट्स। ध्यान देने के लिए धन्यवाद!
केल्विन के शौक 3

जवाबों:


2

सीजाम - 189

{`"_~"+:T;"Besides unquoted numbers, my output has &It's good to be a program.&My source has & characters.
"'&/~_]:X2=T,X3=3i({T_&:B{TI/,(" are ":AM`I*N}fIXK=]o
XBA`N+f+2*+s:T,X3=}fK'q];}_~

इसे http://cjam.aditsu.net/ पर आज़माएं

आउटपुट:

My source has 189 characters.
3 are "{"
3 are "`"
6 are """
4 are "_"
3 are "~"
4 are "+"
5 are ":"
5 are "T"
2 are ";"
3 are "B"
8 are "e"
9 are "s"
2 are "i"
3 are "d"
17 are " "
6 are "u"
2 are "n"
2 are "q"
8 are "o"
6 are "t"
3 are "m"
2 are "b"
7 are "r"
4 are ","
2 are "y"
2 are "p"
3 are "h"
7 are "a"
5 are "&"
4 are "I"
3 are "'"
2 are "g"
2 are "."
2 are "M"
3 are "c"
2 are "
"
2 are "/"
3 are "]"
5 are "X"
2 are "2"
4 are "="
3 are "3"
2 are "("
2 are "A"
2 are "*"
2 are "N"
3 are "}"
3 are "f"
2 are "K"
Besides unquoted numbers, my output has 988 characters.
3 are "B"
108 are "e"
11 are "s"
3 are "i"
5 are "d"
214 are " "
8 are "u"
4 are "n"
3 are "q"
9 are "o"
9 are "t"
5 are "m"
4 are "b"
108 are "r"
3 are ","
4 are "y"
4 are "p"
6 are "h"
108 are "a"
3 are "I"
3 are "'"
4 are "g"
5 are "."
3 are "M"
7 are "c"
102 are "
"
2 are "{"
198 are """
2 are "`"
2 are "_"
2 are "~"
2 are "+"
2 are ":"
2 are "T"
2 are ";"
2 are "&"
2 are "/"
2 are "]"
2 are "X"
2 are "2"
2 are "="
2 are "3"
2 are "("
2 are "A"
2 are "*"
2 are "N"
2 are "}"
2 are "f"
2 are "K"
It's good to be a program.

11

रूबी, 269 (311, 367) अक्षर

इस चुनौती के लिए मेरे पास तीन अलग-अलग समाधान हैं। उनमें से प्रत्येक चाल के एक अलग सेट का उपयोग करता है:

"उचित" समाधान, 367 वर्ण:

सबसे लंबा समाधान कमोबेश अवधारणा का एक प्रमाण है कि बिना किसी चाल के इस चुनौती को हल करना संभव है - और लगभग पूरी तरह से गोल्फ नहीं है। यह एक सच्ची क्वीन है (यानी यह एक फ़ाइल से पढ़ने के बजाय अपना स्वयं का सोर्स कोड बनाता है) और वास्तव में यह सभी संख्याओं की गणना करता है (कोड लंबाई, आउटपुट लंबाई, वर्ण आवृत्तियों)। जिस तरह से क्वीन काम करता है, उसके कारण सभी कोड एक लाइन पर और एक स्ट्रिंग शाब्दिक के अंदर होना चाहिए।

eval r="S='eval r=%p'%r;O=-~$.;q=\"My source has \#{S.size}\"+(X=' characters.\n')+S.chars.uniq.map{|c|[k=S.count(c),k>O ? :are: :is,?\"+c+?\"]*' '}*$/+'\nBesides unquoted numbers, my output has ';r=(w=q+X+s=\"It's good to be a program.\").scan(D=/\\D/).uniq;$><<q<<(w+v=r.map{|c|j=' are \"\n\"';(-~(w+j*r.size).count(c)).to_s+(j[~O]=c;j)}*$/+$/).scan(D).size<<X+v+s"

आंशिक रूप से हार्डकोडेड आउटपुट, 311 वर्ण:

अगला सबसे छोटा समाधान दो तरकीबों का उपयोग करता है, लेकिन अभी भी एक सच्चा क्वीन है: - स्रोत कोड में कोई भी चरित्र एक बार नहीं होता है। इस तरह, मुझे यह तय करने की ज़रूरत नहीं है कि मुझे आउटपुट के पहले आधे हिस्से में प्रिंट करना चाहिए isया नहीं are। यह कुल आउटपुट आकार की गणना करना थोड़ा आसान बनाता है (हालांकि मुझे वास्तव में ऐसा करने की आवश्यकता नहीं है)। - कुल आउटपुट आकार हार्डकोड है। चूंकि यह केवल स्रोत कोड में अलग-अलग वर्णों की संख्या पर निर्भर करता है (और सामान्य स्थिति में, उनमें से कितने वर्ण केवल एक बार होते हैं), यह आसानी से अग्रिम में गणना करना है।

ध्यान दें कि कोड दो बहुत महत्वपूर्ण newlines द्वारा पूर्ववर्ती है, जो StackExchange कोड ब्लॉक में नहीं दिखाएगा। इस कारण से, मैंने उन न्यूलाइन्स के सामने एक अतिरिक्त लाइन जोड़ी है, जो कोड का हिस्सा नहीं है

#


eval R="I=$/+$/+'eval R=%p'%R;?\\4>w='%d are \"%s\"';B=\"My source has \#{I.size}\#{X=\" characters.\n\"}\#{z=(m=I.chars.uniq).map{|x|w%[I.count(x),x]}*$/}\nBesides unquoted numbers, my output has 1114\"+X;$><<B+m.map{|c|w%[(B+z+$M=\"\nIt's good to be a program.\").gsub!(/\\d++(?!\")/,'').count(c),c]}*$/+$M"

सबसे छोटा समाधान, 269 वर्ण:

सबसे छोटा समाधान अतिरिक्त रूप से अपनी स्रोत लंबाई को हार्डकोड करता है। चर नामों का उपयोग करके, जो / पहले से ही स्रोत कोड का हिस्सा नहीं हैं, यह एक "फिक्स पॉइंट" ढूंढना संभव है, जहां स्रोत कोड के सभी वर्ण (हार्डकोड किए गए लंबाई से अंक सहित!) कम से कम दो बार होते हैं।

यह समाधान केवल कुछ स्रोत को कोड फ़ाइल से अपने स्वयं के स्रोत कोड को पढ़ने के बजाय सहेजने के बजाय सहेजता है। एक अच्छे साइड इफेक्ट के रूप में, यह कोड को और अधिक "पठनीय" बनाता है (लेकिन में पठनीय कोड के बारे में कौन परवाह करता है ...), क्योंकि अब कोड को स्ट्रिंग स्ट्रिंग के अंदर नहीं होना चाहिए।

U='%d are "%s"'
O=IO.read$0
?\126>B="My source has 269#{X=" characters.
"}#{z=(m=O.chars.uniq).map{|c|U%[O.count(c),c]}*$/}
Besides unquoted numbers, my output has 1096"+X
$><<B+m.map{|c|U%[(B+z+$M="
It's good to be a program.").gsub!(/\d++(?!")/,"").count(c),c]}*$/+$M

कोड की जांच करने के लिए आवश्यक कॉपी-पेस्टिंग को कम करने के लिए मैंने टेस्ट स्क्रिप्ट को थोड़ा संशोधित किया। के साथ CODEऔर की परिभाषाओं की जगहOUTPUT

import subprocess

CODE = open("packed.rb").read()
OUTPUT = subprocess.check_output(["ruby", "packed.rb"])

print CODE
print len(CODE)

स्क्रिप्ट अब स्वचालित रूप से मेरा कोड चलाता है, उसका आउटपुट पढ़ता है, और कोड फ़ाइल से स्रोत कोड को पकड़ता है।


यहां सबसे छोटे कोड द्वारा जनरेट किया गया आउटपुट है:

My source has 269 characters.
3 are "U"
7 are "="
3 are "'"
4 are "%"
6 are "d"
17 are " "
11 are "a"
9 are "r"
9 are "e"
11 are """
11 are "s"
6 are "
"
4 are "O"
2 are "I"
10 are "."
6 are "$"
2 are "0"
2 are "?"
2 are "\"
2 are "1"
2 are "2"
3 are "6"
2 are ">"
4 are "B"
3 are "M"
2 are "y"
9 are "o"
10 are "u"
12 are "c"
4 are "h"
2 are "9"
2 are "#"
4 are "{"
2 are "X"
8 are "t"
4 are "}"
2 are "z"
6 are "("
7 are "m"
5 are "n"
2 are "i"
2 are "q"
6 are ")"
4 are "p"
4 are "|"
2 are "["
4 are ","
2 are "]"
2 are "*"
4 are "/"
3 are "b"
7 are "+"
2 are "<"
3 are "g"
2 are "!"
Besides unquoted numbers, my output has 1096 characters.
2 are "U"
2 are "="
3 are "'"
2 are "%"
5 are "d"
238 are " "
120 are "a"
120 are "r"
120 are "e"
222 are """
11 are "s"
114 are "
"
2 are "O"
3 are "I"
5 are "."
2 are "$"
2 are "0"
2 are "?"
2 are "\"
2 are "1"
2 are "2"
2 are "6"
2 are ">"
3 are "B"
3 are "M"
4 are "y"
9 are "o"
8 are "u"
7 are "c"
6 are "h"
2 are "9"
2 are "#"
2 are "{"
2 are "X"
9 are "t"
2 are "}"
2 are "z"
2 are "("
5 are "m"
4 are "n"
3 are "i"
3 are "q"
2 are ")"
4 are "p"
2 are "|"
2 are "["
3 are ","
2 are "]"
2 are "*"
2 are "/"
4 are "b"
2 are "+"
2 are "<"
4 are "g"
2 are "!"
It's good to be a program.

क्या आप अपने कोड और आउटपुट की एक निश्चित प्रति पोस्ट कर सकते हैं ताकि मैं आसानी से इसका परीक्षण कर सकूं? कोड स्वयं आउटपुट नहीं होना चाहिए और आउटपुट एक नई अवधि में समाप्त होना चाहिए।
केल्विन के

@ केल्विन हॉबीज पहला कोड ब्लॉक मेरा वास्तविक कोड है। यह आउटपुट को अंतिम न्यूलाइन के साथ प्रिंट करता है, इसलिए मुझे इसे ठीक करने के लिए कुछ मिनट दें (यह एक ऐसी चीज है जिसका आपको निश्चित रूप से उल्लेख करना चाहिए)।
वेंटरो

यकीन है कि बात है, मैं सिर्फ कल्पना को अद्यतन किया।
केल्विन के शौक

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