Una cadena de suma es una secuencia de enteros que comienza con 1, donde cada entero que no sea el 1 inicial es una suma de dos enteros anteriores.
Por ejemplo, aquí hay una cadena de suma:
[1, 2, 3, 4, 7, 8, 16, 32, 39, 71]
Estas son las sumas que lo convierten en una cadena de suma:
1 + 1 = 2
1 + 2 = 3
1 + 3 = 4
3 + 4 = 7
1 + 7 = 8
8 + 8 = 16
16 + 16 = 32
7 + 32 = 39
32 + 39 = 71
En este desafío, se le dará un número entero positivo n
, y debe generar una de las cadenas de suma más cortas que termina en n
.
Ejemplos: tenga en cuenta que hay muchas salidas posibles, todo lo que debe encontrar es una cadena de suma que sea igual de corta:
1: [1]
2: [1, 2]
3: [1, 2, 3]
4: [1, 2, 4]
5: [1, 2, 3, 5]
6: [1, 2, 3, 6]
7: [1, 2, 3, 4, 7]
11: [1, 2, 3, 4, 7, 11]
15: [1, 2, 3, 5, 10, 15]
19: [1, 2, 3, 4, 8, 11, 19]
29: [1, 2, 3, 4, 7, 11, 18, 29]
47: [1, 2, 3, 4, 7, 10, 20, 27, 47]
71: [1, 2, 3, 4, 7, 8, 16, 32, 39, 71]
Reglas de E / S estándar, etc. Prohibidas las lagunas estándar. Código de golf: gana pocos bytes.
code-golf
sequence
arithmetic
isaacg
fuente
fuente
Respuestas:
Haskell , 57 bytes
Una solución de fuerza bruta. Pruébalo en línea!
Explicación
La lista infinita
c
contiene todas las cadenas de suma, ordenadas por longitud. Se define inductivamente en términos de sí mismo, tomando una listax
dec
y dos elementos dex
, y agregando su suma ax
. La funciónf
encuentra la primera listac
que termina con el número deseado.fuente
Brachylog , 14 bytes
Pruébalo en línea!
Una sumisión de fuerza bruta que construye todas las cadenas de suma posibles utilizando la profundización iterativa, deteniéndose cuando se encuentra una cadena que contiene su argumento correcto. A diferencia de la mayoría de las presentaciones de Brachylog, esta es una presentación de función que ingresa a través de su argumento derecho (convencionalmente llamado Salida) y las salidas a través de su argumento izquierdo (convencionalmente llamado Entrada); hacer esto es algo controvertido, pero la meta respuesta más votada sobre el tema dice que es legal (y hacerlo es consistente con nuestros valores predeterminados normales de E / S para las funciones). Si usáramos la entrada y la salida de una manera más convencional, serían 16 bytes (
∧≜;1{j⊇Ċ+}ᵃ⁽.∋?∧
), porque el lado derecho del programa no podría hacer uso de la restricción implícita (por lo tanto, necesitaría deshabilitarla y dar una nueva restricción explícita, a un costo de 2 bytes).Explicación
Una sutileza interesante aquí es lo que sucede en la primera iteración, donde la entrada es un número en lugar de una lista como en las otras iteraciones; comenzamos con el número 1, hacemos dos copias de cada dígito (haciendo el número 11), luego encontramos una subsecuencia de 2 dígitos (también el número 11). Luego tomamos su suma de dígitos, que es 2, y como tal la secuencia comienza
[1,2]
como queremos. En iteraciones futuras, estamos empezando con una lista como[1,2]
, duplicando a[1,2,1,2]
, a continuación, tomar una subsecuencia de dos elementos ([1,1]
,[1,2]
,[2,1]
, o[2,2]
); claramente, las sumas de cada uno de estos serán los siguientes elementos válidos de la cadena de adición.Es un poco frustrante aquí que la sugerencia de orden de evaluación se necesita aquí, especialmente el
≜
componente (parece queᵃ
toma su sugerencia de orden de evaluación desde adentro en lugar de afuera por defecto, por lo tanto, el uso más bien crudo≜
para forzar el problema).fuente
ᵃ
es uno de esos componentes internos que rara vez aparece, pero cuando lo necesitas, realmente lo necesitas, ya que no hay una forma remotamente corta de implementarlo usando otras construcciones de control. Una vez que me di cuenta de que esto era unᵃ
desafío, el resto vino directamente desde allí.Jalea , 17 bytes
Emite la primera solución lexicográfica en tiempo exponencial.
Pruébalo en línea!
Cómo funciona
fuente
JavaScript (ES6),
8386 bytesEditar: arreglado para generar la lista en orden no inverso
Manifestación
Mostrar fragmento de código
fuente
PHP, 195 bytes
Pruébalo en línea!
fuente
Mathematica, 140 bytes
.
produce una cadena de adición más corta diferente cada vez que la ejecuta
Pruébelo en línea,
pegue el código con Ctrl + V, coloque la entrada, es decir, [71] al final del código y presione Mayús + Entrar
fuente
[1,2,4,5,9,18,36,72,77,149]
). Parece que su programa usa muestreo aleatorio y no se garantiza que encuentre la solución óptima.Pyth, 13 bytes
Banco de pruebas
Da la primera cadena más corta lexicográficamente. Es bastante lento, pero no está tan mal.
19
completa en unos 30 segundos con pypy.Algunas ideas de la solución de @ Dennis.
Realmente me gusta este, hay un montón de trucos interesantes involucrados.
Explicación:
Esto todavía es un poco difícil de entender, pero déjame intentar explicarte con un poco más de detalle.
Comenzamos con
ySQ
, que da todos los posibles subconjuntos ordenados de[1, 2, ... Q]
, en orden creciente de tamaño. La cadena de adición más corta es definitivamente una de estas, pero necesitamos encontrarla.Lo primero que haremos es filtrar la lista para mantener solo las listas que contienen un
Q
. Hacemos esto con/#Q
.A continuación, ordenamos la lista por lo que queda después de eliminar el resultado de una determinada función.
-D
órdenes por el resto después de eliminar algo.Lo que eliminamos es
sM^N2
dóndeN
está la lista de la que eliminamos cosas.^N2
da el producto cartesiano deN
sí mismo, todos los pares posibles de dos elementos enN
.sM
luego suma cada uno de los pares.¿Cuál es el resultado más pequeño posible, después de hacer esta eliminación? Bueno, el elemento más pequeño en la lista de entrada definitivamente permanecerá, porque todos los números son positivos, por lo que cualquier suma de dos números será mayor que el número más pequeño. Y habrá al menos un número, porque verificamos que la entrada estaba presente en la lista. Por lo tanto, el resultado más pequeño posible será cuando cada número, excepto el número más pequeño, sea la suma de otros dos números en la lista, y el número más pequeño en la lista sea 1. En este caso, la clave de clasificación será
[1]
. Estos requisitos significan que la lista debe ser una cadena de adición.Entonces, clasificamos las cadenas de adición al frente. Recuerde que
y
da sus subconjuntos en orden creciente de tamaño, por lo que la lista que se ordena al frente debe ser una de las cadenas de adición más cortas.h
selecciona esa lista.fuente