Dado un número n> 77 , escriba un programa o función que encuentre un conjunto de enteros positivos distintos de modo que la suma del conjunto sea igual a n , y la suma de los recíprocos del conjunto sea igual a 1.
Ejemplo para 80:
80 = 2 + 4 + 10 + 15 + 21 + 28 ⟶ 1/2 + 1/4 + 1/10 + 1/15 + 1/21 + 1/28 = 1
Su programa o función debe (teóricamente) funcionar para cualquier n <2 32 , y no está justificado por errores de redondeo de coma flotante. Tenga en cuenta que existen soluciones para todos n> 77 .
El código más corto en bytes gana.
Hay un incentivo adicional: otorgaré una recompensa a la solución más pequeña que funcione para cualquier ny ejecute log (n) . Para pequeños n debe ser rápido (determinado a mi discreción). Si, esto es posible.
O(log n)
algoritmo.Respuestas:
Mathematica, 54 bytes
Casi tan ineficiente como parece, pero se resuelve
n = 78
en unos 9 segundos.El resultado se devuelve como una lista envuelta en una lista única, por ejemplo:
fuente
Python 3,
73061995 BytesEsta solución se ejecuta en complejidad log (n) (por lo que puedo decir).
Puedes probar que se
f(2**32 - 1)
ejecuta casi al instanteUsé este documento sobre un método para calcularlo. Con este método hay una gran cantidad de datos para los valores predeterminados para n de 78 a 334 sin los números pares después de 168. Quería convertir estos datos en algo pequeño y no conocía ningún buen algoritmo de compresión, así que hecho el mío
La forma en que lo comprimí fue tener una lista de reglas de reemplazo de cadenas. Creé un método que encontró la regla de reemplazo de cadena que reduciría la mayor parte del contenido teniendo en cuenta la definición de la regla. Luego lo apliqué recursivamente hasta que no pude crear más reglas (usé los caracteres gz y AZ). La cadena que hice para reemplazar era una lista separada por comas de los valores hexadecimales para cada uno de los números. En retrospectiva, convertirlos a sus valores hexadecimales puede no haber sido la mejor opción, probablemente sería más corto dejarlos en decimal, ya que tener hexadecimal solo ahorraría para los números de 3 dígitos pero agregaría un 0 para los números de un solo dígito.
La línea donde configuré c puede ver la lista de reglas de reemplazo y el texto en el que se ejecuta. Las reglas también deben aplicarse a la inversa porque algunas reglas incluyen caracteres creados a partir de otras reglas.
También hay numerosos lugares en este código donde probablemente podría reducir la sintaxis, como convertir la lista de listas en una sola lista y luego usar un método diferente para acceder a las reglas para reemplazar el texto con
fuente
n=218
salidas[2]
es lo esperado ??Haskell, 93 bytes
Horriblemente lento 1 pero se ejecuta en memoria constante. Solución trivial: verifique todas las subsecuencias de
[2..n]
para suma y suma de recíprocos.Devolver todas las soluciones en lugar de una es 3 bytes más corto: simplemente elimine el
!!0
(cuidado: el tiempo de ejecución siempre estará fuera de los gráficos).1 El tiempo de ejecución depende de qué tan temprano aparezca el resultado en la lista de subsecuencias. La pereza de Haskell detiene la búsqueda si se encuentra la primera coincidencia. Cuando se compila,
p 89
(result:) se[3,4,6,9,18,21,28]
ejecuta en mi computadora portátil (de 4 años) en 35s. Otros valores, incluso los más pequeños, pueden llevar horas.fuente
Julia, 77 bytes
Esta es una función lambda ineficiente que acepta un entero y devuelve una matriz de enteros. Para llamarlo, asígnelo a una variable.
Obtenemos las particiones del entero usando
partitions
. Luego filtramos el conjunto de particiones solo para aquellos con elementos únicos cuyos recíprocos suman 1. Para asegurar que no ocurra ningún error de redondeo, usamos elRational
tipo de Julia para construir los recíprocos.filter
devuelve un iterador, por lo que tenemos quecollect
hacerlo en una matriz. Esto nos da una matriz de matrices (con un solo elemento), por lo que podemos obtener el primer uso[1]
.Ahora, cuando digo ineficiente, lo digo en serio. Ejecutar esto para n = 80 toma 39.113 segundos en mi computadora y asigna 13.759 GB de memoria.
fuente