Te dan un montón de pesos, y tu tarea es construir un pequeño móvil equilibrado usando esos pesos.
La entrada es una lista de pesos enteros en el rango de 1 a 9, inclusive. Puede haber duplicados.
La salida es una imagen ascii de un móvil que, cuando se cuelga, se equilibraría. Quizás mejor se muestra con el ejemplo:
entrada
3 8 9 7 5
salida posible
|
+-----+---------+
| |
+--+-+ +----+------+
| | | |
8 ++--+ 7 5
| |
9 3
Debe usar los caracteres ascii como se muestra. Los segmentos horizontal y vertical pueden ser de cualquier longitud. Ninguna parte del móvil puede tocar (horizontal o verticalmente) otra parte no conectada del móvil. Todos los pesos deben colgarse de un segmento vertical de longitud de al menos 1, y debe haber un segmento vertical del que se cuelga todo el móvil.
El tamaño de un móvil es el número total de +
, -
y |
caracteres necesarios para su construcción. Los tamaños más bajos son mejores.
Puede poner tantas conexiones en un segmento como desee. Por ejemplo:
entrada
2 3 3 5 3 9
salida posible
|
+---+---+-----------+
| | |
+--+-+ 5 9
| | |
2 | 3
|
+++
| |
3 3
El programa ganador es el que puede generar el promedio más bajo de tamaños móviles para un conjunto de prueba de entradas. La prueba real es súper secreta para evitar la codificación rígida, pero será algo como esto:
8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 7
1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 7 7
3 4 4 4 4 5 5 5 5 6 6 6 6 7 7 7 7
fuente
total_weight_hung_from_point * distance_of_point_from_pivot
debe ser la misma en ambos lados del punto de pivote.Respuestas:
Python 2.
Estoy engañando un
poco:Solo construyo móviles con uno horizontal.
Tengo la sensación (pero no lo he probado) que el móvil óptima en las condiciones dadas en realidad siempre no sólo tienen una horizontal.Editar: no siempre es cierto; with2 2 9 1
Nabb ha encontrado un contraejemplo en los comentarios a continuación:Acabo de hacer estúpido forzamiento bruto:
Mis resultados para sus entradas de muestra; cada uno se ejecutó durante 5 segundos (soy consciente de que esto es ridículo para los pequeños; solo pasar por todas las permutaciones posibles sería más rápido). Tenga en cuenta que, dado que hay un elemento aleatorio, las ejecuciones posteriores pueden encontrar mejores o peores resultados.
El código (detallado, ya que esto no es código golf):
fuente
1 9 2 8
a genera1-------8+-9--2
; Desde lo más alto de mi cabeza no puedo encontrar nada mejor (pero no confiaría en eso), ¿tienes algo?2 2 9 1
es decir (2 + 2) * 3 = 9 + 1 * 3 para el tamaño 16 en lugar del2-9+--2----1
cual es 18. Supongo que hay un umbral (tal vez 5 o 6 ) después de lo cual una sola fila horizontal siempre es óptima.2-2-+9-1
saldos, con una puntuación de 13(4*2+2*2 = 9*1+1*3)
. Así que no creo que sea un buen contraejemplo.Bueno, esta es una pregunta antigua, pero acabo de verla aparecer en la pestaña de preguntas principales, así que aquí está mi solución (óptima):
Al mirar las reglas, estoy bastante seguro de que no es trampa, aunque parece que sí. Esto solo generará todos los números dados en una cadena vertical, por un costo total de 2 * número_de_insumos (que es el mínimo posible porque cada número debe tener una barra encima, sin importar el diseño). Aquí hay un ejemplo:
Produce:
Lo cual, por supuesto, está en perfecto equilibrio.
Originalmente iba a intentar algo más en el espíritu de este desafío, pero rápidamente resultó que de todos modos simplemente se optimizó para esta estructura
fuente
|
a la parte inferior de un peso.Aquí hay una solución que fuerza bruta a la solución de fila única más pequeña. El código itera sobre todas las permutaciones y calcula el centro de masa para cada una. Si el centro de masa tiene coordenadas enteras, hemos encontrado una solución.
Después de que se hayan intentado todas las permutaciones, agregamos un segmento a la mezcla (equivalente a un peso de masa 0) en nuestro conjunto actual de pesos y reintentos.
Para ejecutar el programa, hazlo
python balance.py 1 2 2 4
.que produce estas mejores soluciones:
fuente
Python 3
Creo que esto no es peor que 1 más que óptimo en cualquiera de los casos de prueba, y lo hace en 5 segundos.
Básicamente, uso un enfoque de barra única. Ordeno aleatoriamente la entrada, luego inserto los pesos en la barra de uno en uno. Cada elemento se coloca en la posición que minimiza el exceso de peso en cada lado, o la segunda mejor posición desde esa perspectiva, utilizando el primer 75% del tiempo y el último 25% del tiempo. Luego, verifico si el móvil está equilibrado al final y es mejor que el mejor móvil encontrado hasta ahora. Guardo el mejor, luego lo detengo e imprimo después de 5 segundos de búsqueda.
Resultados, en 5 segundos:
Código:
La única de estas soluciones que creo que es subóptima es la más larga, que tiene esta solución, que encontré después de 10 minutos de ejecución:
fuente