बारह-सिक्का समस्या


14

पृष्ठभूमि

बारह-सिक्का समस्या एक क्लासिक बैलेंस पहेली है जो आमतौर पर नौकरी के साक्षात्कार में उपयोग की जाती है। यह पहेली पहली बार 1945 में सामने आई थी और मेरे पिता द्वारा मेरे पिता को दी गई थी जब उन्होंने मेरी माँ से शादी करने के लिए कहा था! पहेली में बारह सिक्के हैं, जिनमें से एक या तो दूसरों की तुलना में भारी या हल्का है (आपको पता नहीं है कि कौन सा है)। समस्या अद्वितीय सिक्के को निर्धारित करने के लिए तीन बार एक संतुलन तराजू का उपयोग करना है। कुछ बदलावों में, यह पहचानना भी आवश्यक है कि सिक्का भारी है या हल्का।

यहां कार्य में सबसे खराब स्थिति में संभवतया कम से कम वजन का उपयोग करते हुए, एन सिक्कों से जुड़ी सामान्य समस्या को हल करना शामिल है । यह पहचानना आवश्यक नहीं है कि सिक्का भारी है या हल्का है, केवल एक ही है। इसके अलावा, आपके पास दिए गए सेट के बाहर किसी भी अतिरिक्त सिक्के तक पहुंच नहीं है (जो, उत्सुकता से, एक फर्क पड़ता है)।

यह पता चलता है कि k वज़न (3 ^ k-1) / 2 सिक्कों के लिए पर्याप्त है (इसलिए इस भिन्नता में 4 वज़न वास्तव में 13 सिक्कों को संभाल सकते हैं)। इसके अलावा (और आश्चर्यजनक रूप से), यह संभव है (लेकिन यहां आवश्यक नहीं है) अग्रिम में तौल के पूर्ण सेट का चयन करने के बजाय, भविष्य के वजन पिछले परिणामों पर निर्भर करते हैं। दो संभावित समाधानों के विवरण के लिए, यह पेपर और यह Quora उत्तर देखें

कार्य

एक फ़ंक्शन या प्रोग्राम लिखें, एक पूर्णांक n को इनपुट के रूप में STDIN, कमांड-लाइन तर्क या फ़ंक्शन तर्क के साथ लें, जो कि सबसे खराब स्थिति में संभवतम कम से कम वज़न का उपयोग करके n सिक्कों के लिए समस्या को हल करता है । कार्यक्रम चाहिए:

  • 1,2,3-4,5,6पैमाने के प्रत्येक तरफ सिक्कों की सूचियों को इंगित करने के लिए प्रारूप में STDOUT के लिए वजन का प्रिंट करें । तौले जाने वाले किसी भी सिक्के का उल्लेख नहीं किया जाना चाहिए। सिक्कों को स्पष्ट रूप से 1 से n तक गिना जाता है और संख्यात्मक क्रम में मुद्रित नहीं किए जाने की आवश्यकता होती है (इसलिए 2,1-3,4जैसा है 1,2-3,4)।
  • प्रत्येक वजन के बाद कार्यक्रम को एसटीडीआईएन के माध्यम से एक इनपुट पर इंतजार करना चाहिए, जो होना चाहिए <, =या >, यह दर्शाता है कि पैमाने के बाईं ओर हल्का है, समान है, या दाईं ओर से भारी है।
  • अंतिम तौल परिणाम के बाद, प्रोग्राम को अद्वितीय सिक्के की संख्या को प्रिंट या वापस करना चाहिए।
  • प्रोग्राम को उपयोगकर्ता से असंगत परिणाम इनपुट को संभालने की आवश्यकता नहीं है।
  • कार्यक्रम को 3 से कम n हैंडल करने की आवश्यकता नहीं है ।

उदाहरण आउटपुट

>> 3
1-2
>> =
1-3
>> <
3

# using Quora algorithm
>> 13
1,2,3,4-5,6,7,8
>> <
1,2,5-3,4,6
>> >
3-4
>> <
3

# using paper algorithm
>> 13
1,2,3,4-5,6,7,8
>> <
2,6,7,9-3,8,10,11
>> >
6,8,10,12-4,5,7,11
>> =
3

स्कोरिंग

सबसे छोटा कोड जीतता है। मानक नियम लागू होते हैं।

जवाबों:


2

पायथन 3: 497 बाइट्स

I=lambda a,b:input(",".join(a)+"-"+",".join(b)+"\n>> ")
def A(a,b):
 l,L=len(a),len(b)
 if l+L==1:return(a or b)[0]
 m=(2*l+1-L)//3;M=m+L-l;x,y,X,Y=a[:m],a[m:2*m],b[:M],b[M:2*M];r=I(x+X,y+Y);return A(a[2*m:],b[2*M:])if r=="="else A(x,Y)if r=="<"else A(y,X)
def B(a,n=[]):
 if len(a)==1:return a[0]
 m=len(n);l=(len(a)+1+m)//3;x,y,z=a[:l],a[l:2*l-m],a[2*l-m:];r=I(x,y+n);return B(z,a[:1])if r=="="else A(x+z[:1-m],y)if r=="<"else A(y+z[:1-m],x)
print(B(list(map(str,range(1,int(input("N= "))+1)))))

मुझे संदेह है कि यह थोड़ा और कम हो सकता है, लेकिन मुझे कोई स्पष्ट स्थान नहीं दिखता है (प्रत्येक फ़ंक्शन के लगभग 5 अलग-अलग संस्करणों के बाद)।

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

दो एल्गोरिथ्म फ़ंक्शंस kमें निम्नलिखित आकारों में दिए गए वज़न के असामान्य वजन वाले सिक्के मिल सकते हैं :

  • A: 3^kकुल सिक्के, की दो सूची में विभाजित (3^k-1)/2और (3^k+1)/2
  • B: (3^k + 1)/2सिक्के अगर किसी ज्ञात-अच्छे सिक्के की आपूर्ति करते हैं, (3^k - 1)/2 अन्यथा।

यहाँ प्रस्तुत प्रश्न निर्दिष्ट करता है कि हमारे पास प्रारंभ में कोई ज्ञात-अच्छे सिक्के नहीं हैं, इसलिए हम खराब सिक्के (3^k - 1)/2को kतौल के एक सेट में ढूंढ सकते हैं ।

यहाँ एक परीक्षण फ़ंक्शन है, जो मैंने यह सुनिश्चित करने के लिए लिखा था कि मेरा कोड फर्जी वज़न का अनुरोध नहीं कर रहा था या इसके लिए आवश्यक वज़न की संख्या से अधिक का उपयोग कर रहा था:

def test(n):
    global I
    orig_I = I
    try:
        for x in range(3,n+1):
            max_count = 0
            for y in range(x*2):
                count = 0
                def I(a, b):
                    assert len(a) == len(b), "{} not the same length as {}".format(a,b)
                    nonlocal count
                    count += 1
                    if y//2 in a: return "<"if y%2 else ">"
                    if y//2 in b: return ">"if y%2 else "<"
                    return "="
                assert B(list(range(x)))==y//2, "{} {} not found in size {}".format(['heavy','light'][y%2], y//2+1, x)
                if count > max_count:
                    max_count = count
            print(x, max_count)
    finally:
        I = orig_I

यह सिक्के और खराब वजन (भारी या हल्का) के प्रत्येक संयोजन के साथ परीक्षण के बाद किसी दिए गए सेट के लिए सबसे खराब स्थिति में प्रिंट करता है।

यहां 125 तक के सेट के लिए परीक्षण आउटपुट दिया गया है:

>>> test(150)
3 2
4 2
5 3
6 3
7 3
8 3
9 3
10 3
11 3
12 3
13 3
14 4
15 4
16 4
17 4
18 4
19 4
20 4
21 4
22 4
23 4
24 4
25 4
26 4
27 4
28 4
29 4
30 4
31 4
32 4
33 4
34 4
35 4
36 4
37 4
38 4
39 4
40 4
41 5
42 5
43 5
44 5
45 5
46 5
47 5
48 5
49 5
50 5
51 5
52 5
53 5
54 5
55 5
56 5
57 5
58 5
59 5
60 5
61 5
62 5
63 5
64 5
65 5
66 5
67 5
68 5
69 5
70 5
71 5
72 5
73 5
74 5
75 5
76 5
77 5
78 5
79 5
80 5
81 5
82 5
83 5
84 5
85 5
86 5
87 5
88 5
89 5
90 5
91 5
92 5
93 5
94 5
95 5
96 5
97 5
98 5
99 5
100 5
101 5
102 5
103 5
104 5
105 5
106 5
107 5
108 5
109 5
110 5
111 5
112 5
113 5
114 5
115 5
116 5
117 5
118 5
119 5
120 5
121 5
122 6
123 6
124 6
125 6

ब्रेकपॉइंट ठीक उसी तरह हैं, जहाँ आप अपेक्षा करते हैं, बीच में (3^k - 1)/2और (3^k + 1)/2

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.