एक जहर शराब परीक्षण अनुसूचक बनाएँ


16

हाल ही में Puzzling.SE में, एक समस्या यह थी कि मैंने यह निर्धारित करने के बारे में लिखा था कि बड़ी संख्या में से दो बोतलें जहर हैं जब जहर केवल सक्रिय हो जाता है यदि दोनों घटक नशे में हैं। यह पूरी तरह से अलग एल्गोरिदम का उपयोग करके 18 या 19 कैदियों को इसे प्राप्त करने का प्रबंधन करने वाले अधिकांश लोगों के साथ, काफी कठिन हो गया।

मूल समस्या कथन इस प्रकार है:

आप एक मध्ययुगीन राज्य के शासक हैं, जो पार्टियों को फेंकना पसंद करते हैं। पिछली बार आपकी शराब की बोतलों में से एक को जहर देने की कोशिश करने वाले दरबारी को यह जानकर गुस्सा आया था कि आप यह पहचानने में कामयाब रहे कि उसने किस बोतल में 1,000 कैदियों के साथ जहर दिया था।

इस बार वह थोड़ा शिल्पकार है। उन्होंने एक समग्र जहर विकसित किया है P: एक द्विआधारी तरल जो केवल घातक है जब दो व्यक्तिगत रूप से हानिरहित घटक मिश्रण करते हैं; यह एपॉक्सी के काम करने के तरीके के समान है। उसने आपको 1,000 शराब की बोतलों का एक और टोकरा भेजा है। एक बोतल में घटक होता है C_aऔर दूसरे में घटक होता है C_b। ( P = C_a + C_b)

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

आपके पास अपनी अगली पार्टी से दो दिन पहले है। उन दो कैदियों को पहचानने के लिए आपको परीक्षण के लिए न्यूनतम संख्या में कैदियों का उपयोग करने की आवश्यकता है, और कैदियों की संख्या के साथ आपको किस एल्गोरिथ्म का पालन करने की आवश्यकता है?


बोनस
इसके अलावा, मान लीजिए कि आपके पास अपने निपटान में 20 कैदियों की एक निश्चित सीमा थी, तो आप उन बोतलों की अधिकतम संख्या क्या है जो आप सैद्धांतिक रूप से परीक्षण कर सकते हैं और एक सटीक निष्कर्ष पर आ सकते हैं कि कौन सी बोतलें प्रभावित हुई थीं?

आपका कार्य बोनस समस्या को हल करने के लिए एक कार्यक्रम बनाना है। nकैदियों को देखते हुए , आपका कार्यक्रम एक परीक्षण अनुसूची तैयार करेगा जो बोतलों के बीच दो जहर की बोतलों का पता लगाने में सक्षम होगा m, जहां mसंभव के रूप में बड़ा है।

आपका प्रोग्राम शुरू में इनपुट नंबर N, कैदियों की संख्या के रूप में ले जाएगा । यह तो उत्पादन होगा:

  • Mबोतलों की संख्या आप परीक्षण करने का प्रयास करेंगे। इन बोतलों से लेबल किया जाएगा 1करने के लिए M

  • N लाइनों, बोतलों के लेबल जिसमें प्रत्येक कैदी पीएगा।

आपका कार्यक्रम फिर इनपुट के रूप में ले जाएगा जो पहले दिन कैदियों की मृत्यु हो गई थी, कैदी के साथ पहली पंक्ति होने 1, अगली पंक्ति होने 2आदि, फिर, यह आउटपुट होगा:

  • Nअधिक लाइनें, बोतलों के लेबल वाले प्रत्येक कैदी को पीना होगा। मृत कैदियों के पास खाली लाइनें होंगी।

आपका कार्यक्रम फिर इनपुट के रूप में ले जाएगा जो दूसरे दिन कैदियों की मृत्यु हो गई, और दो संख्याओं का उत्पादन किया, Aऔर B, जो आपके कार्यक्रम को लगता है कि दो बोतलों में जहर शामिल है, का प्रतिनिधित्व करता है।

दो कैदियों और चार बोतलों के लिए एक उदाहरण इनपुट के रूप में जाना जा सकता है, अगर बोतलें 1और 3जहर हैं:

> 2      // INPUT: 2 prisoners
4        // OUTPUT: 4 bottles
1 2 3    // OUTPUT: prisoner 1 will drink 1, 2, 3
1 4      // OUTPUT: prisoner 2 will drink 1, 4
> 1      // INPUT: only the first prisoner died
         // OUTPUT: prisoner 1 is dead, he can't drink any more bottles
3        // OUTPUT: prisoner 2 drinks bottle 3
> 2      // INPUT: prisoner 2 died
1 3      // OUTPUT: therefore, the poisoned bottles are 1 and 3.

The above algorithm may not actually work in all
cases; it's just an example of input and output.

आपके कार्यक्रम के परीक्षण शेड्यूल को सफलतापूर्वक एक वैध जमा होने के लिए प्रत्येक संभावित जोड़ी जहर की बोतलों को निर्धारित करना चाहिए।

आपका कार्यक्रम निम्नलिखित मानदंडों पर बनाया जाएगा, क्रम में:

  • बोतलों की अधिकतम संख्या यह मामले के लिए विचार कर सकती है N = 20

  • मामले के लिए बोतलों की संख्या N = 21, और उसके बाद क्रमिक रूप से उच्च मामले।

  • कोड की लंबाई। (छोटा कोड जीतता है।)


यदि एक ही दिन में एक से अधिक कैदी की मृत्यु हो जाती है तो इनपुट कैसा दिखेगा? आपके उदाहरणों में से कोई भी उस मामले को शामिल नहीं करता है, और विनिर्देश मेरे लिए अस्पष्ट है।
ESultanik

क्या यह कैदियों की अंतरिक्ष-पृथक सूची के साथ एक एकल पंक्ति है जो मर गए?
ESultanik

क्या कम कोड बोतलों की संख्या से अधिक मायने रखता है? क्या यह एक और बोतल को संभालने के लिए कोड की लंबाई बढ़ाने के लिए उत्पादक है, जैसा कि मैंने अपने हाल के संपादन में किया था?
पिपरी

बोतलों की संख्या प्राथमिकता लेती है। यदि आप अपने कोड को अधिक बोतल में निचोड़ने के लिए अधिक जटिल बनाते हैं, तो यह उत्पादक है।
जो जेड।

मूल समस्या में समस्या को हल करने के लिए केवल 2 दिन हैं। क्या यह भी चुनौती का नियम है? (यह संभव समाधानों को
गंभीर रूप से

जवाबों:


7

पायथन 2.7.9 - 21 बोतलें

यह मानते हुए कि कई कैदियों की मौत होने पर इनपुट क्या होता है, उस पर ESultanik का अनुमान सही है

r=raw_input;s=str;j=s.join;p=int(r());z=range;q=z(p);x=z(p+1)
print s(p+1)+"\n"+j("\n",(j(" ",(s(a) for a in x if a!=b)) for b in q))
v=r().split();d=[s(a) for a in q if s(a) not in v];d+=[p]if len(d)==1 else [];
print "\n"*p,;r();print j(" ",[s(a) for a in d])

एल्गोरिथम: प्रत्येक कैदी हर बोतल से अपनी संख्या को छोड़कर पीता है (1 कैदी पहली बोतल नहीं पीता है)। यदि वे नहीं मरते हैं, तो उनकी संख्या बोतल में जहर है। यदि केवल एक कैदी बचता है, तो अतिरिक्त बोतल में जहर होता है।


3

पर्ल ५ , 66 बोतलें

(21 कैदियों के लिए 72 बोतलें)

कैदियों को आशावादी रूप से 2 समूहों में बांटा गया है। बोतलों को समूह में बांटा गया है।

समूह 1 का प्रत्येक कैदी एक को छोड़कर सभी सेटों से पीएगा। 1 या 2 बचे होंगे। 1 या 2 सेट जो उनके द्वारा पिया नहीं गया था वे 2 दिन तक जारी रहेंगे।

दूसरे दिन सभी बचे हुए कैदी (बचे सहित) एक को छोड़कर शेष सभी बोतलों से पीते हैं।
जब 2 कैदी बच जाते हैं, तो जो बोतलें नहीं पीती हैं, उन्हें जहर दिया जाता है।
अगर केवल 1 कैदी बचता है तो जिस बोतल को वे पीते हैं वह भी संदिग्ध है।

कोड में परीक्षण की सुविधा के लिए अतिरिक्त कार्यक्षमता शामिल है। जब प्याज़ की बोतलों को अतिरिक्त मापदंडों के रूप में जोड़ा जाता है, तो यह इनपुट के बारे में नहीं पूछेगा कि कौन मर गया।

($p,$f,$l)=@ARGV;
$p=9if!$p;
$m=$p-(2*int($p/4))+1;
$n=$p-$m+2;
$b=$m*(($n+1)/2);
@M=(1..$m);
print"Prisoners: $p\nBottles: $b\n";
# building the sets of items
for$x(@M){
    $j=$k+1;$k+=($n+1)/2;
    $s=join",",($j..$k);
    $A[$x]=$s
}
# assigning the sets to the actors
for$x(@M){
    @T=();
    for$j(@M){if($x!=$j){push@T,split/,/,$A[$j]}}
    print"Prisoner $x drinks @T\n";
    $B[$x]=join",",@T
}
if(!$f||!$l){
    # manual input
    print"Who dies: ";
    $_=<STDIN>;chomp;
    @D=split/ /;
    %h=map{($_,1)}@D;
    @S=grep{!$h{$_}}(@M)
} 
else{
    # calculate who dies based on the parameters
    for$x(@M){
        $d=0;
        map{if($_==$f||$_==$l){$d++}}split/,/,$B[$x];
        if($d>1){push@D,$x}else{push@S,$x}
    }
}
for(@D){print"Prisoner $_ dies\n"}

# calculate the remaining items
for(@S){push@R,split/,/,$A[$_]}@R=sort{$a<=>$b}grep{!$g{$_}++}@R;

# different set of actors if there were 1 or 2 sets remaining
if(@S>1){@S=($S[0],$m+1..$p,$S[1],0)}else{@S=($m+1..$p)};

$i=0;@B=@D=();
# assign an item to each actor
for$x(@S){
    @T=();
    for($j=0;$j<@R;$j++){
        if($i!=$j){push@T,$R[$j]}
    }$i++;
    print"Prisoner $x drinks @T\n"if$x>0;
    $B[$x]=join",",@T
}

if(!$f||!$l){
    # manual input
    print"Who dies: ";
    $_=<STDIN>;chomp;
    @D=sort split/ /;
    if(@D<@S-1){push@D,0} # because the set that noone drinks isn't manually put in
    %h=map{($_,1)}@D;
    @L=grep{!$h{$_}}(@S);
}
else{
    # calculate who dies based on the parameters
    @D=();
    for$x(@S){
        $d=0;
        map{if($_==$f||$_==$l){$d++}}split/,/,$B[$x];
        if($d>1){push@D,$x}else{push@L,$x}
    }
}

for(@D){print"Prisoner $_ dies\n"if$_>0}

# calculate the remaining items
for(@L){push@F,split/,/,$B[$_]}
map{$c{$_}++}@F;
for(keys%c){push(@Z,$_)if$c{$_}==1}
@R=sort{$a<=>$b}@Z;

print"Suspected bottles: @R"

परीक्षा

$ perl poisened_bottles.pl 20
Prisoners: 20
Bottles: 66
Prisoner 1 drinks 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
Prisoner 2 drinks 1 2 3 4 5 6 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
Prisoner 3 drinks 1 2 3 4 5 6 7 8 9 10 11 12 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
Prisoner 4 drinks 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
Prisoner 5 drinks 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
Prisoner 6 drinks 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
Prisoner 7 drinks 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
Prisoner 8 drinks 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
Prisoner 9 drinks 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 55 56 57 58 59 60 61 62 63 64 65 66
Prisoner 10 drinks 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 61 62 63 64 65 66
Prisoner 11 drinks 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
Who dies: 2 3 4 5 6 7 8 9 10
Prisoner 2 dies
Prisoner 3 dies
Prisoner 4 dies
Prisoner 5 dies
Prisoner 6 dies
Prisoner 7 dies
Prisoner 8 dies
Prisoner 9 dies
Prisoner 10 dies
Prisoner 1 drinks 2 3 4 5 6 61 62 63 64 65 66
Prisoner 12 drinks 1 3 4 5 6 61 62 63 64 65 66
Prisoner 13 drinks 1 2 4 5 6 61 62 63 64 65 66
Prisoner 14 drinks 1 2 3 5 6 61 62 63 64 65 66
Prisoner 15 drinks 1 2 3 4 6 61 62 63 64 65 66
Prisoner 16 drinks 1 2 3 4 5 61 62 63 64 65 66
Prisoner 17 drinks 1 2 3 4 5 6 62 63 64 65 66
Prisoner 18 drinks 1 2 3 4 5 6 61 63 64 65 66
Prisoner 19 drinks 1 2 3 4 5 6 61 62 64 65 66
Prisoner 20 drinks 1 2 3 4 5 6 61 62 63 65 66
Prisoner 11 drinks 1 2 3 4 5 6 61 62 63 64 66
Who dies: 1 12 14 15 16 17 18 20 11
Prisoner 1 dies
Prisoner 11 dies
Prisoner 12 dies
Prisoner 14 dies
Prisoner 15 dies
Prisoner 16 dies
Prisoner 17 dies
Prisoner 18 dies
Prisoner 20 dies
Suspected bottles: 3 63

मैनुअल इनपुट के बिना टेस्ट

$ perl poisened_bottles.pl 7 2 5
Prisoners: 7
Bottles: 12
Prisoner 1 drinks 3 4 5 6 7 8 9 10 11 12
Prisoner 2 drinks 1 2 5 6 7 8 9 10 11 12
Prisoner 3 drinks 1 2 3 4 7 8 9 10 11 12
Prisoner 4 drinks 1 2 3 4 5 6 9 10 11 12
Prisoner 5 drinks 1 2 3 4 5 6 7 8 11 12
Prisoner 6 drinks 1 2 3 4 5 6 7 8 9 10
Prisoner 2 dies
Prisoner 4 dies
Prisoner 5 dies
Prisoner 6 dies
Prisoner 1 drinks 2 5 6
Prisoner 7 drinks 1 5 6
Prisoner 3 drinks 1 2 6
Prisoner 1 dies
Suspected bottles: 2 5

2

जैसा कि परंपरा है, मैं एक अंतिम-स्थान संदर्भ उत्तर पोस्ट करूंगा।

अजगर - 7 बोतलें

prisoners = int(raw_input())

bottles = 0
while (bottles * (bottles + 1) / 2 - 1) <= prisoners:
    bottles += 1

print bottles

pairs = []
for i in range(bottles):
    for j in range(i + 1, bottles):
        pairs += [str(i + 1) + " " + str(j + 1)]

for i in range(prisoners):
    if i < len(pairs):
        print pairs[i]
    else:
        print

dead_prisoner = raw_input()

for i in range(prisoners):
    print
raw_input() # discard the second day entirely

if dead_prisoner == "":
    print pairs[-1]
else:
    print pairs[int(dead_prisoner) - 1]

प्रत्येक कैदी को अंतिम दो के जोड़े को छोड़कर एक संभावित जोड़ी बोतलें पिलाएं। यदि कोई भी कैदी मर जाता है, तो उस कैदी ने जो पिया है, वह जहर था। अन्यथा, यह आखिरी दो बोतलें थीं जिन्हें जहर दिया गया था।

कम से कम n(n-1)/2 - 1कैदियों के आवंटन के लिए , आप nबोतलों तक कर सकते हैं । के लिए n = 7, यह निचली सीमा है 20

इस समाधान के लिए हमें वास्तव में केवल एक दिन की आवश्यकता है । एक समान दायरे वाले दो-दिवसीय समाधान के लिए 20 बोतल तक मिल सकती है N = 20, लेकिन यह एक तुच्छ उत्तर के लिए बहुत अधिक काम है।

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