# 建立有毒的葡萄酒测试计划程序

16

• `M`，您将尝试测试的瓶子数量。这些瓶子将被标记为从`1``M`

• `N` 行，其中包含每个囚犯将喝的瓶子的标签。

• `N`更多的行，其中包含每个囚犯将喝的瓶子的标签。死囚将有空白行。

``````> 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

pppery

JoeZ。2015年

LukStorms 2015年

7

# Python 2.7.9 — 21瓶

``````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])
``````

3

# Perl 5、66瓶

## （72瓶21名囚犯）

``````(\$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

# Python — 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

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