क्या मैं ठीक से गोल्फ कर रहा हूं?


12

मैं उत्सुक हूँ अगर मैं ठीक से कोड गोल्फ कर रहा हूँ। मैंने पायथन में एक एकल कथन में एक छोटे से हैशिंग कार्यक्रम बनाने के लिए खुद को चुनौती दी। मैंने पहली बार शुरुआत की:

from itertools import permutations
from string import ascii_lowercase
from random import sample

def test():
    chars = sample(ascii_lowercase, 9)
    sums = list(map(h, permutations(chars)))
    if len(set(sums)) == len(sums):
       print("unique results for permutations of given string")
    else:
       print("duplicate entries present in test results")

def h(s):
    r = 0
    for i in range(len(s)):
        r += ord(s[i]) << (i * len(s))
    return r

test()

मैंने फिर फ़ंक्शन को पुनरावर्ती बनाया:

def h(s, i=0):
    if i < len(s) - 1: return h(s, i+1) + ord(s[i]) << (i * len(s))
    else: return ord(s[i]) << (i * len(s))

मैंने इसे कोड दोहराने के लिए एक मेमने के साथ छोटा करने की कोशिश की (यह काम नहीं किया):

def h(s, i=0, f=lambda s,i: ord(s[i]) << (i * len(s))):
    if i < len(s) - 1: return h(s, i+1) + f(s,i)
    else: return f(s,i)

अंत में मैं एक मेमने के साथ समाप्त हुआ:

h=lambda s,i=0:h(s,i+1)+ord(s[i])<<(i*len(s))if i<len(s)-1 else ord(s[i])<<(i*len(s))

मैं चाहता था कि कार्यक्रम एक बयान हो, इसलिए सबसे पहले मैं आया:

def test():
    chars = sample(ascii_lowercase, 9)
    sums = list(map((lambda s,i=0,f=lambda s,i,f:f(s,i+1,f)+ord(s[i])<<(i*len(s))if i<len(s)-1 else ord(s[i])<<(i*len(s)):f(s,i,f)), permutations(chars)))
    if len(set(sums)) == len(sums):
       print("unique results for permutations of given string")
    else:
       print("duplicate entries present in test results")

और अंत में मैं के साथ समाप्त हो गया:

print((lambda x=list(map((lambda s,i=0,f=lambda s,i,f:f(s,i+1,f)+ord(s[i])<<(i*len(s))if i<len(s)-1 else ord(s[i])<<(i*len(s)):f(s,i,f)), permutations(sample(ascii_lowercase, 9)))): "unique results for permutations of given string" if len(set(x)) == len(x) else "duplicate entries present in test results")())

क्या यह कैसे कोडगुल्ला समस्याओं पर काम किया जाता है? मैंने वास्तव में इस तरह का काम कभी नहीं किया है, इसलिए अभी मैं सिर्फ यह जानना चाहता हूं कि क्या मैं इसे सही कर रहा हूं।

संशोधन: यह कार्यक्रम आपके लिए सभी काम करता है; इसलिए मैं यहां फ़ंक्शन का संदर्भ दूंगा: इनपुट के रूप में, प्रोग्राम किसी दिए गए स्ट्रिंग के सभी क्रमपरिवर्तन में लेता है; यहाँ स्ट्रिंग नौ अक्षरों को बेतरतीब ढंग से उठाया गया है ascii_lowercase। आउटपुट एक मानव-पठनीय स्ट्रिंग है जो यह परिभाषित करता है कि दिए गए स्ट्रिंग के प्रत्येक क्रमपरिवर्तन का परिणाम किसी भिन्न स्ट्रिंग के लिए किसी अन्य परिणाम का डुप्लिकेट है या नहीं। यदि सभी क्रमपरिवर्तन के लिए कोई डुप्लिकेट नहीं हैं, तो कार्यक्रम सफलता का संकेत देता है। नौ पात्रों को मेरे बॉक्स पर बार-बार आसानी से गणना किए जाने वाले पात्रों की सबसे बड़ी लंबाई के रूप में चुना गया था।

संशोधन II जैसा कि एक अध्ययनशील पाठक द्वारा बताया गया है, वर्णित उद्देश्य को साथ दिए गए कोड के माध्यम से प्राप्त नहीं किया गया है। परीक्षण का मामला स्पष्ट रूप से अपर्याप्त है।


3
यह एक अच्छा सुझाव प्रश्न लगता है, और मुझे यह देखकर प्रसन्नता हुई है कि आपने अपनी गोल्फ प्रक्रिया को विस्तार से दिखाया है। लेकिन मुझे नहीं पता कि आप "हैशिंग" कार्यक्रम का क्या मतलब है। आपको एक युक्ति पोस्ट करनी चाहिए जो बताती है कि इनपुट कैसे लिया जाना है, आउटपुट कैसे दिया जाना है, और इनपुट से आउटपुट का क्या संबंध होना चाहिए।
xnor

@xnor क्या पर्याप्त है?
मोटोकू

कोड गोल्फ के लिए, आपको निश्चित रूप से उन वैकल्पिक स्थानों में से कुछ को निकालना चाहिए। इसके अलावा, पायथन 2 का उपयोग करें, क्योंकि मुद्रण कम है। print"x"इसके बजायprint("x")
mbomb007

और के बजाय एक सूची समझ का उपयोग करें list()?
mbomb007

3
आपकी प्रक्रिया ठीक लगती है। एक कार्यक्रम से शुरू करें, परीक्षण / त्रुटि से छोटा करें। अधिक अनुभव प्राप्त करें और अजगर युक्तियों को ब्राउज़ करें और आप कुछ ही समय में शानदार प्रदर्शन करेंगे।
Geobits

जवाबों:


11

गोल्फ के लिए कोई 'सही' तरीका नहीं है। आपने अच्छा किया है, और आपके द्वारा उपयोग की जाने वाली प्रक्रिया काफी मानक है। हालांकि एक बयान में कार्यक्रम बनाना आमतौर पर एक आवश्यकता नहीं है।

यदि यह मदद करता है, तो यहां बताया गया है कि मैं आपके कार्यक्रम को कैसे पूरा करूंगा ...

हैशिंग फ़ंक्शन में, कथन के लिए राशि के साथ प्रतिस्थापित किया जा सकता है:

def h(s):
    r = 0
    r = sum(ord(s[i]) << (i * len(s)) for i in range(len(s)))
    return r

इसके बाद इसे लंबो फंक्शन के रूप में परिभाषित किया जा सकता है:

h = lambda s: sum(ord(s[i]) << (i * len(s)) for i in range(len(s)))

और अब हम अनावश्यक स्थान और कोष्ठक हटाते हैं:

h=lambda s:sum(ord(s[i])<<i*len(s)for i in range(len(s)))

जैसा कि Sp3000 ने बताया है, यह आगे की गणना के साथ छोटा किया जा सकता है:

h=lambda s:sum(ord(x)<<i*len(s)for i,x in enumerate(s))

परीक्षण समारोह में आगे बढ़ते हुए, हम इसकी पहली दो पंक्तियों को मिलाते हैं:

def test():
    sums = list(map(h, permutations(sample(ascii_lowercase, 9))))
    ...

चूंकि दोनों फ़ंक्शन केवल एक बार उपयोग किए जाते हैं, हम सब कुछ इनलाइन कर सकते हैं:

sums = list(map(lambda s:sum(ord(x)<<i*len(s)for i,x in enumerate(s)), permutations(sample(ascii_lowercase, 9))))
...

यह सूची समझ के रूप में छोटा है:

sums = [sum(ord(x)<<i*len(s)for i,x in enumerate(s)) for s in permutations(sample(ascii_lowercase, 9))]

अगला, हम इसे एक छोटा नाम देते हैं और अनावश्यक स्थानों को फिर से हटा देते हैं:

x=[sum(ord(x)<<i*len(s)for i,x in enumerate(s))for s in permutations(sample(ascii_lowercase,9))]

अगर इस स्टेटमेंट को प्रिंट फंक्शन के अंदर ले जाया जा सकता है:

print('unique...' if len(set(x)) == len(x) else 'duplicate...')

हालाँकि, यह आमतौर पर उपयोग करने के लिए छोटा होता है और / या:

print(len(set(x)) == len(x) and 'unique...' or 'duplicate...')

चूंकि len(x)परिवर्तन नहीं होता है, हम इसकी कीमत की गणना और हार्डकोड कर सकते हैं:

print(len(set(x)) == 362880 and 'unique...' or 'duplicate...')

अनावश्यक रिक्त स्थान को हटाने और तुलना करने के बाद, हमें मिलता है:

print(len(set(x))<362880and'duplicate...'or'unique...')

यह हमें सब कुछ एक बयान में स्थानांतरित करने देता है:

print(len(set([sum(ord(x)<<i*len(s)for i,x in enumerate(s))for s in permutations(sample(ascii_lowercase,9))]))<362880and'duplicate...'or'unique...')

और अब हम इसके बजाय एक सेट समझ का उपयोग कर सकते हैं:

print(len({sum(ord(x)<<i*len(s)for i,x in enumerate(s))for s in permutations(sample(ascii_lowercase,9))})<362880and'duplicate...'or'unique...')

आयात को छोड़कर, परिणाम 210 बाइट्स है। अगला कदम शायद आयात या लंबे तारों को नीचे गिराना होगा।


7
पर्याप्त रूप से, मुझे लगता enumerateहै कि यह छोटा है:h=lambda s:sum(ord(x)<<i*len(s)for i,x in enumerate(s))
Sp3000

@ Sp3000 ओह अच्छा! हर बिल्‍डिन का अपना दिन होता है: D
grc
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.