Recientemente en Puzzling.SE, escribí un problema acerca de determinar qué dos botellas de un número mayor están envenenadas cuando el veneno solo se activa si ambos componentes están borrachos. Terminó siendo una experiencia terrible, con la mayoría de las personas logrando reducirlo a 18 o 19 prisioneros usando algoritmos completamente diferentes.
La declaración original del problema es la siguiente:
Eres el gobernante de un reino medieval al que le encantan las fiestas. El cortesano que trató de envenenar una de sus botellas de vino la última vez se enfureció al saber que logró identificar qué botella había envenenado de 1,000 con solo diez prisioneros.
Esta vez es un poco más astuto. Ha desarrollado un veneno compuesto
P
: un líquido binario que solo es mortal cuando dos componentes individualmente inofensivos se mezclan; Esto es similar a cómo funciona el epoxi. Te ha enviado otra caja de 1,000 botellas de vino. Una botella tiene componenteC_a
y otra tiene componenteC_b
. (P = C_a + C_b
)Cualquiera que beba ambos componentes morirá a la medianoche de la noche en que bebió el componente final, independientemente de cuándo en el día en que bebieron el líquido. Cada componente de veneno permanece en el cuerpo hasta que se activa el segundo componente, por lo que si bebe un componente un día y otro componente al día siguiente, morirá a medianoche al final del segundo día.
Tienes dos días antes de tu próxima fiesta. ¿Cuál es el número mínimo de prisioneros que necesita usar para las pruebas para identificar qué dos botellas están contaminadas y qué algoritmo necesita seguir con ese número de prisioneros?
Bono
Además, suponga que tiene un límite fijo de 20 prisioneros a su disposición, ¿cuál es el número máximo de botellas que en teoría podría probar y llegar a una conclusión precisa sobre qué botellas se vieron afectadas?
Su tarea es construir un programa para resolver el problema de bonificación. Dado a los n
presos, su programa diseñará un cronograma de pruebas que podrá detectar las dos botellas envenenadas entre m
botellas, donde m
sea lo más grande posible.
Inicialmente, su programa tomará como entrada el número N
, el número de prisioneros. Luego generará:
M
, la cantidad de botellas que intentará probar. Estas botellas serán etiquetadas de1
aM
.N
líneas, que contienen las etiquetas de las botellas que tomará cada prisionero.
Su programa tomará como entrada qué presos murieron el primer día, con el prisionero en la primera línea 1
, la siguiente línea 2
, etc. Luego, generará:
N
más líneas, que contienen las etiquetas de las botellas que tomará cada prisionero. Los prisioneros muertos tendrán líneas en blanco.
Luego, su programa tomará como entrada qué prisioneros murieron en el segundo día, y generará dos números A
y B
representará las dos botellas que su programa cree que contienen el veneno.
Un ejemplo de entrada para dos prisioneros y cuatro botellas podría ser así, si las botellas 1
y 3
están envenenadas:
> 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.
El programa de pruebas de su programa debe determinar con éxito cada posible par de botellas envenenadas para que sea un envío válido.
Su programa se puntuará según los siguientes criterios, en orden:
El número máximo de botellas que puede discernir para el caso
N = 20
.El número de botellas para el caso
N = 21
, y sucesivamente casos más altos después de eso.La longitud del código. (El código más corto gana).