Dado um número n> 77 , escreva um programa ou função que encontre um conjunto de números inteiros positivos distintos, de modo que a soma do conjunto seja igual a n e a soma dos recíprocos do conjunto seja igual a 1.
Exemplo para 80:
80 = 2 + 4 + 10 + 15 + 21 + 28 ⟶ 1/2 + 1/4 + 1/10 + 1/15 + 1/21 + 1/28 = 1
Seu programa ou função deve (teoricamente) funcionar para qualquer n <2 32 e não é desculpa para erros de arredondamento de ponto flutuante. Observe que existem soluções para todos os n> 77 .
O menor código em bytes vence.
Há um incentivo de bônus: concederei uma recompensa à menor solução que funcione para qualquer n e execute log (n) . Para n pequeno , deve ser rápido (determinado a meu critério). Sim, isso é possível.
O(log n)
algoritmo.Respostas:
Mathematica, 54 bytes
Tão ineficiente quanto possível, mas resolve
n = 78
em cerca de 9 segundos.O resultado é retornado como uma lista agrupada em uma lista singleton, por exemplo:
fonte
Python 3,
73061995 BytesEsta solução é executada com complexidade de log (n) (até onde eu sei).
Você pode testar a
f(2**32 - 1)
execução quase instantâneaeu usei este artigo em um método para calculá-lo. Com esse método, há uma grande quantidade de dados para os valores predeterminados para n de 78 a 334 sem os números pares depois de 168. Eu queria transformar esses dados em algo pequeno e não conhecia nenhum bom algoritmo de compactação. fez o meu.
A maneira como eu o compactava era ter uma lista de regras de substituição de string. Eu criei um método que encontrou a regra de substituição de string que reduziria o máximo de conteúdo, levando em consideração a definição da regra. Apliquei isso recursivamente até não poder mais criar regras (usei os caracteres gz e AZ). A sequência que fiz para substituir foi uma lista separada por vírgula dos valores hexadecimais para cada um dos números. Em retrospecto, convertê-los em seus valores hexadecimais pode não ter sido a escolha mais sábia, provavelmente seria mais curto deixá-los em decimal, pois o hexadecimal salvaria apenas os números de 3 dígitos, mas adicionaria 0 para os números de um dígito.
Na linha em que defino c, você pode ver a lista de regras de substituição e o texto em que é executado. As regras também precisam ser aplicadas ao contrário, porque algumas regras incluem caracteres criados a partir de outras regras.
Existem também vários lugares nesse código em que eu provavelmente poderia reduzir a sintaxe, como transformar a lista de listas em uma única lista e, em seguida, usar um método diferente para acessar as regras para substituir o texto por
fonte
n=218
saídas[2]
é o esperado ??Haskell, 93 bytes
Horrivelmente lento 1, mas roda em memória constante. Solução trivial: verifique todas as subsequências de
[2..n]
soma e soma de recíprocos.Retornar todas as soluções em vez de uma é 3 bytes mais curto: basta remover o
!!0
(cuidado: o tempo de execução estará sempre fora dos gráficos).1 O tempo de execução depende de quão cedo o resultado aparece na lista de subsequências. A preguiça de Haskell interrompe a busca se a primeira correspondência for encontrada. Quando compilado,
p 89
(resultado[3,4,6,9,18,21,28]
:) é executado no meu laptop (de 4 anos) aos 35 anos. Outros valores, ainda menores, podem levar horas.fonte
Julia, 77 bytes
Esta é uma função lambda ineficiente que aceita um número inteiro e retorna um array inteiro. Para chamá-lo, atribua-o a uma variável.
Nós obtemos as partições do número inteiro usando
partitions
. Em seguida, filtramos o conjunto de partições apenas para aqueles com elementos exclusivos cujas recíprocas somam 1. Para garantir que nenhum erro de arredondamento ocorra, usamos oRational
tipo de Julia para construir as recíprocas.filter
retorna um iterador, portanto, temos que fazê-collect
lo em uma matriz. Isso nos fornece uma matriz de matrizes (com apenas um único elemento), para que possamos obter o primeiro uso[1]
.Agora, quando digo ineficiente, quero dizer isso. A execução disso para n = 80 leva 39,113 segundos no meu computador e aloca 13,759 GB de memória.
fonte