Tienes n
monedas que pesan -1 o 1. Cada una está etiquetada de 0
an-1
para que pueda distinguir las monedas. También tiene un dispositivo de pesaje (mágico). En el primer turno, puede colocar tantas monedas como desee en el dispositivo de pesaje que puede medir pesos negativos y positivos y le dirá exactamente cuánto pesan.
Sin embargo, hay algo realmente extraño en el dispositivo de pesaje. Si coloca monedas x_1, x_2, ..., x_j
en el dispositivo la primera vez, la próxima vez que tenga que colocar monedas (x_1+1), (x_2+1) , ..., (x_j+1)
en la báscula, con la excepción de que, por supuesto, no puede colocar una moneda con un número mayor n-1
. No solo eso, por cada nuevo pesaje que elijas si también quieres poner monedas 0
en la báscula.
Bajo esta regla, ¿cuál es el menor número de pesadas que siempre le dirá exactamente qué monedas pesan 1 y cuáles pesan -1?
Claramente, podría colocar una moneda 0
en el dispositivo en el primer turno y luego tomaría n
un peso exacto para resolver el problema.
Idiomas y bibliotecas
Puede usar cualquier idioma o biblioteca que desee (que no fue diseñada para este desafío). Sin embargo, me gustaría poder probar su código si es posible, así que si puede proporcionar instrucciones claras sobre cómo ejecutarlo en Ubuntu, sería muy apreciado.
Puntuación
Para un determinado, n
su puntaje se n
divide por la cantidad de pesajes que necesita en el peor de los casos. Las puntuaciones más altas son, por lo tanto, mejores. No hay aportes a este rompecabezas, pero su objetivo es encontrar uno n
para el que pueda obtener la puntuación más alta.
Si hay un empate, la primera respuesta gana. En la situación extremadamente improbable en la que alguien encuentra la manera de obtener una puntuación infinita, esa persona gana de inmediato.
Tarea
Su tarea es simplemente escribir código que obtenga la puntuación más alta. Su código tendrá que elegir una n hábilmente y luego también optimizar el número de pesadas para eso n
.
Entradas principales
4/37/5 en Python por Sarge Borsch- 26/14 en Java por Peter Taylor
fuente
x_i
: podemos tener, por ejemplo, una primera ponderación de (x_1, x_2, x_3) = (3, 2, 7), y luego la segunda ponderación puede ser (4, 3, 8) o ( 0, 4, 3, 8). Las etiquetas de monedas no necesitan ser consecutivas, y el índicei
enx_i
no se refiere a la etiqueta de la moneda.Respuestas:
C ++, puntaje
23/1225/1327/1428/14 = 231/15Las soluciones de la propiedad Matrix X revisitada (o la Alegría de X) se pueden usar directamente como soluciones a este problema. Por ejemplo, la solución de 31 filas 15 columnas:
la fila N representa qué monedas coloca en la báscula para la medición N. Cualquiera que sea el resultado de la ponderación que obtenga, obviamente hay un conjunto de valores de monedas que le dan ese peso. Si también hay otra combinación (la solución no es única) considere cómo difieren. Debe reemplazar un conjunto de ponderación
1
de monedas por ponderación de monedas-1
. Esto proporciona un conjunto de columnas que corresponden a ese giro. También hay un conjunto de ponderaciones de monedas por las-1
que reemplaza1
. Ese es otro conjunto de columnas. Debido a que las mediciones no cambian entre las dos soluciones, eso significa que las sumas de columna de los dos conjuntos deben ser las mismas. Pero las soluciones a la propiedad Matrix X revisited (o la alegría de X) son exactamente estas matrices donde tales conjuntos de columnas no existen, por lo que no hay duplicados y cada solución es única.Cada conjunto real de mediciones puede ser descrito por alguna
0/1
matriz. Pero incluso si algunos conjuntos de columnas suman los mismos vectores, podría ser que los signos de los valores de monedas de la solución candidata no se correspondan exactamente con dicho conjunto. Entonces no sé si las matrices como la anterior son óptimas. Pero al menos proporcionan un límite inferior. Entonces, la posibilidad de que se puedan hacer 31 monedas en menos de 15 mediciones aún está abierta.Tenga en cuenta que esto solo es cierto para una estrategia no fija donde su decisión de poner monedas
0
en la balanza depende del resultado de las ponderaciones anteriores. De lo contrario, tendrá soluciones donde los signos de las monedas se corresponden con los conjuntos que tienen la misma suma de columnas.fuente
Python 2, puntaje = 1.0
Este es el puntaje fácil, en caso de que nadie encuentre un puntaje mejor (dudoso).
n
pesajes para cada unon
.Importé
antigravity
para que el programa pueda funcionar con pesos negativos.fuente
antigravity
es básicamente un no-op, ¿verdad?Puntuación = 26/14 ~ = 1.857
Guardar como
LembikWeighingOptimisation.java
, compilar comojavac LembikWeighingOptimisation.java
, ejecutar comojava LembikWeighingOptimisation
.Muchas gracias a Mitch Schwartz por señalar un error en la primera versión del rechazo rápido.
Esto utiliza algunas técnicas bastante básicas que no puedo justificar rigurosamente. Es una fuerza bruta, pero solo para comenzar operaciones de pesaje que usan como máximo la mitad de las monedas: las secuencias que usan más de la mitad de las monedas no son directamente transferibles a los pesajes complementarios (porque no sabemos el peso total), pero en un nivel ondulado a mano debería haber aproximadamente la misma cantidad de información. También itera a través de pesadas iniciales en orden de la cantidad de monedas involucradas, sobre la base de que de esa manera cubre pesadas dispersas (que con suerte brindan información sobre el extremo superior relativamente temprano) sin primero arrastrarse a través de un grupo que comienza con un subconjunto denso en El extremo inferior.
La
MaskRange
clase es una mejora masiva en la versión anterior en términos de uso de memoria, y elimina el GC de ser un cuello de botella.fuente
Python 3,
puntaje = 4/3 = 1.33… (N = 4)puntaje = 1.4 (N = 7)Actualización: implementado la búsqueda de fuerza bruta en el conjunto de solucionadores "estáticos", y obtuve un nuevo resultado
Creo que se puede mejorar aún más mediante la búsqueda de solucionadores dinámicos, que pueden utilizar los resultados de ponderación para futuras decisiones.
Aquí hay un código de Python que busca valores pequeños en todos los solucionadores estáticos
n
(estos solucionadores siempre pesan los mismos conjuntos de monedas, de ahí el nombre "estático") y determina el número de pasos en el peor de los casos simplemente comprobando que sus resultados de medición permiten solo una moneda coincidente establecido en todos los casos. Además, realiza un seguimiento del mejor puntaje encontrado hasta ahora y de los primeros solucionadores de ciruelas pasas que habían demostrado que definitivamente son peores que los que se encontraron antes. Esta fue una optimización importante, de lo contrario no podría esperar este resultado conn
= 7. (Pero claramente todavía no está muy bien optimizado)No dude en hacer preguntas si no está claro cómo funciona ...
La salida:
Esta línea
(StaticSolver({0,2}, {0,1,3}, {0,1,2,4}, {1,2,3,5}, {0,2,3,4,6}), 5), score = 7/5 = 1.4
descubre el mejor solucionador encontrado. Los números entre{}
llaves son los índices de monedas para colocar en el dispositivo de ponderación en cada paso.fuente