Uma cadeia de adição é uma sequência de números inteiros começando com 1, em que cada número inteiro que não seja o 1 inicial é uma soma dos dois números anteriores.
Por exemplo, aqui está uma cadeia de adição:
[1, 2, 3, 4, 7, 8, 16, 32, 39, 71]
Aqui estão as somas que a tornam uma cadeia de adição:
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
Neste desafio, você será dado um número inteiro positivo n
, e você deve uma das cadeias de adição mais curtos que termina em saída n
.
Exemplos - observe que existem muitas saídas possíveis, tudo o que você precisa encontrar é uma cadeia de adição tão curta quanto:
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]
Regras padrão de E / S, etc. Lacunas padrão banidas. Código de golfe: menos bytes ganha.
code-golf
sequence
arithmetic
isaacg
fonte
fonte
Respostas:
Haskell , 57 bytes
Uma solução de força bruta. Experimente online!
Explicação
A lista infinita
c
contém todas as cadeias de adição, ordenadas por comprimento. É definido indutivamente em termos de si mesmo, fazendo uma listax
dec
e dois elementos dex
e anexando sua soma ax
. A funçãof
encontra a primeira listac
que termina com o número desejado.fonte
Braquilog , 14 bytes
Experimente online!
Uma submissão de força bruta que constrói todas as cadeias de adição possíveis usando aprofundamento iterativo, parando quando uma cadeia contendo seu argumento correto é encontrada. Diferentemente da maioria das submissões do Brachylog, essa é uma submissão de funções que insere pelo argumento correto (convencionalmente chamado de Saída) e gera pelo argumento esquerdo (convencionalmente chamado de Entrada); fazer isso é um tanto controverso, mas a meta resposta mais votada sobre o assunto diz que é legal (e é consistente com nossos padrões normais de E / S para funções). Se usássemos a entrada e a saída de uma maneira mais convencional, seriam 16 bytes (
∧≜;1{j⊇Ċ+}ᵃ⁽.∋?∧
), porque o lado direito do programa não seria capaz de usar a restrição implícita (seria necessário desativá-la e fornecer uma nova restrição explícita, a um custo de 2 bytes).Explicação
Uma sutileza interessante aqui é o que acontece na primeira iteração, em que a entrada é um número e não uma lista como nas outras iterações; começamos com o número 1, fazemos duas cópias de cada dígito (tornando o número 11) e, em seguida, encontramos uma subsequência de dois dígitos (também o número 11). Então pegamos sua soma de dígitos, que é 2, e, como tal, a sequência começa
[1,2]
como queremos. Em futuras iterações, estamos começando com uma lista como[1,2]
, dobrando-a[1,2,1,2]
, em seguida, tomar um de dois elementos subsequence ([1,1]
,[1,2]
,[2,1]
ou[2,2]
); claramente, as somas de cada uma delas serão válidas nos próximos elementos da cadeia de adição.É um pouco frustrante aqui que a dica de ordem de avaliação seja necessária aqui, especialmente o
≜
componente (parece queᵃ
leva a dica de ordem de avaliação de dentro para fora e não por padrão por padrão, portanto, o uso grosseiro de≜
para forçar o problema).fonte
ᵃ
é um daqueles componentes que raramente surgem, mas quando você precisa, realmente precisa, pois não há uma maneira remota e concisa de implementá-lo usando outras construções de controle. Depois que percebi que isso era umᵃ
desafio, o resto veio diretamente de lá.Geléia , 17 bytes
Produz a primeira solução lexicograficamente em tempo exponencial.
Experimente online!
Como funciona
fonte
JavaScript (ES6),
8386 bytesEditar: corrigido para exibir a lista em ordem não inversa
Demo
Mostrar snippet de código
fonte
PHP, 195 bytes
Experimente online!
fonte
Mathematica, 140 bytes
.
produz uma cadeia de adição mais curta diferente sempre que você a executa
Experimente on-line,
cole o código com ctrl + v, insira a entrada [71] no final do código e pressione Shift + Enter
fonte
[1,2,4,5,9,18,36,72,77,149]
). Parece que seu programa usa amostragem aleatória e não é garantido que encontre a solução ideal.Pitão, 13 bytes
Suíte de teste
Dá a primeira cadeia lexicograficamente mais curta. É bastante lento, mas não tão ruim - é
19
concluído em cerca de 30 segundos usando pypy.Algumas idéias da solução de @ Dennis.
Eu realmente gosto deste - há uma tonelada de truques legais envolvidos.
Explicação:
Ainda é um pouco difícil de entender, mas deixe-me tentar explicar um pouco mais detalhadamente.
Começamos com
ySQ
, que fornece todos os subconjuntos ordenados possíveis de[1, 2, ... Q]
, em ordem crescente de tamanho. A menor cadeia de adição é definitivamente uma delas, mas precisamos encontrá-la.A primeira coisa que faremos é filtrar a lista para manter apenas as listas que contêm a
Q
. Fazemos isso com/#Q
.Em seguida, ordenamos a lista pelo que resta depois de removermos o resultado de uma determinada função.
-D
ordens pelo restante depois de remover algo.O que removemos é
sM^N2
ondeN
está a lista da qual estamos removendo as coisas.^N2
fornece o produto cartesiano deN
si mesmo, todos os pares possíveis de dois elementosN
.sM
então soma cada um dos pares.Qual é o menor resultado possível, após a remoção? Bem, o menor elemento da lista de entrada definitivamente permanecerá, porque todos os números são positivos, portanto, qualquer soma de dois números será maior que o menor número. E haverá pelo menos um número, porque verificamos que a entrada estava presente na lista. Portanto, o menor resultado possível será quando cada número, exceto o menor número, for a soma de dois outros números na lista e o menor número na lista for 1. Nesse caso, a chave de classificação será
[1]
. Esses requisitos significam que a lista deve ser uma cadeia de adição.Então, classificamos as cadeias de adição à frente. Lembre-se de que
y
fornece seus subconjuntos em ordem crescente de tamanho; portanto, a lista que é classificada na frente deve ser uma das cadeias de adição mais curtas.h
seleciona essa lista.fonte