fundo
A sequência 1-2-3-Tribonacci
Imagine por um segundo que você poderia criar uma sequência de fibonacci substituindo a fórmula de iteração padrão pela seguinte:
Basicamente, em vez de somar os dois últimos para obter o próximo, você soma os três últimos. Esta é a base para a sequência 1-2-3-Tribonacci.
Critério de Brown
O critério de Brown declara que você pode representar qualquer valor inteiro como uma soma dos membros de uma sequência, desde que:
Para todos
n
maiores que 1,
O que isso significa para o desafio
Você pode descrever qualquer número inteiro positivo como uma soma dos membros da sequência 1-2-3-Tribonacci formada pelas seguintes condições iniciais:
Isso é conhecido como, para todos os valores nessa sequência, a proporção entre os termos nunca é maior que 2 (a média fica em torno de 1,839).
Como escrever neste sistema de representação numérica
Digamos que você use uma representação little-endian. Alinhe os membros da sequência da seguinte maneira:
1 2 3 6 11 20 37 68
Então, você pega seu número para ser representado (para nossos testes, digamos que seja 63
) e encontra os valores dos 1-2-3-Tribonacci fornecidos, que somam 63 (usando os maiores valores primeiro!) . Se o número fizer parte da soma, coloque 1 abaixo, 0 se não.
1 2 3 6 11 20 37 68
0 0 0 1 0 1 1 0
Você pode fazer isso para qualquer número inteiro - basta verificar se você usa primeiro os maiores valores abaixo de sua entrada!
Definição (finalmente)
Escreva um programa ou função que faça o seguinte, com alguma entrada inteira positiva n
(escrita em qualquer base padrão) entre 1 e o valor máximo do seu idioma:
- Converta o valor na representação numérica do 1-2-3-Tribonacci definida.
- Usando essa representação binária, e leia-a como se fosse binária. Isso significa que os dígitos permanecem os mesmos, mas o que eles significam muda.
- Pegue esse número binário e converta-o na base do número original.
- Envie ou retorne esse novo número.
No entanto, enquanto a saída for válida, você não precisará seguir estas etapas. Se você encontrar magicamente uma fórmula mais curta (e matematicamente equivalente), fique à vontade para usá-la.
Exemplos
Deixe a função f
ser a função descrita pela definição e []
represente as etapas executadas (como little-endian, embora não deva importar) (você não precisa seguir esse processo, este é apenas o processo descrito):
>>> f(1)
[1]
[1]
[1]
1
>>> f(5)
[5]
[0, 1, 1]
[6]
6
>>> f(63)
[63]
[0, 0, 0, 1, 0, 1, 1]
[104]
104
fonte
Respostas:
Javascript
117111 bytesObrigado a @theonlygusti por ajudar no golfe com 5 bytes
Como funciona
Primeiro, a função gera todos os números de tribonacci até encontrar um maior que a entrada
Em seguida, ele pesquisa inversamente a lista de números. Se um número for menor que a entrada, ele adiciona 2 ^ (índice desse número) ao valor de retorno e reduz a entrada por esse número.
Finalmente, ele retorna o resultado.
Experimente Online
fonte
a[++i]<x
dentro da condição for para salvar um byte?x>0
porx
. Salve mais 2 bytes.Python 2 ,
110102 bytes-3 bytes graças a Rod (truque interessante para converter booleano
i
para um int com,+i
para que o repr`+i`
funcione)Experimente online!
fonte
'01'[i]
por`+i`
i
é um booleano, não um int. Editar - Ohhh+i
, limpo.JavaScript (ES6),
9793 bytesAqui, estamos usando
reduce()
uma função recursiva. Assumimos que a saída seja de 31 bits (que é a maior quantidade não assinada com a qual JS pode trabalhar facilmente para operações bit a bit).Em termos de desempenho, isso claramente não é muito eficiente.
Para os curiosos:
F()
N + 1reduce()
e N iterações converge rapidamente para a Constante de Tribonacci (≈ 1.83929). Portanto, cada bit adicional na saída custa aproximadamente o dobro do tempo que o anterior.F()
função é chamada bons 124 milhões de vezes.Teste
Nota: pode demorar 1 ou 2 segundos para concluir.
Mostrar snippet de código
fonte
Mathematica,
7874 bytesLinearRecurrence[{1,1,1},{1,2,3},#]
gera uma lista, de comprimento igual à entrada, dos números 1-2-3 tribonacci. (O{1,1,1}
representa a soma dos três termos anteriores, enquanto{1,2,3}
os valores iniciais.) Em seguida,#~NumberDecompose~
encontra a maneira mais ambiciosa de escrever a entrada como uma soma dos elementos da lista (esta é a mesma função que decomporia um valor monetário em múltiplos de as moedas disponíveis, por exemplo). Por fim,Fold[#+##&,...]
converte a lista binária resultante em um número inteiro (base 10).Submissão anterior:
Como costuma ser o caso (embora não acima), essa versão golfista é super lenta em entradas maiores que 20 ou mais, porque gera (com recursão não otimizada) uma lista de tribos cujo comprimento é a entrada; a substituição da final
#
por um limite mais razoávelRound[2Log@#+1]
resulta em desempenho muito melhor.fonte
123Tribonacci[]
builtin?Haskell, 95 bytes
Exemplo de uso:
f 63
->104
. Experimente online! .Como funciona:
!
cria a sequência 1-2-3-Tribonacci. Dado1
,2
e3
como parâmetros de início, pegamos os primeirosn
elementos da sequência. Em seguida, dobre a partir da função direita#
que subtrai o próximo elementoe
den
e define o bit no valor de retornor
see
é necessário ou permite que o unset bit. Definir o bit está dobrandor
e adicionando1
, deixando-o desabilitado está apenas dobrando.fonte
Gelatina , 31 bytes
Experimente online!
Estou quase certo de que há uma maneira MUITO mais curta de conseguir isso em Jelly.
Quão?
fonte
Perl 6 ,
9391 bytes-2 bytes graças a b2gills
Como funciona
Primeiro, ele gera a sequência 1-2-3-Tribonacci até o primeiro elemento maior que a entrada:
Com base nisso, ele encontra o subconjunto da sequência que se soma à entrada:
Com base nisso, constrói uma lista de booleanos especificando se cada elemento da sequência faz parte da soma:
E, finalmente, interpreta essa lista de valores True = 1, False = 0 como base 2 e a retorna como um número (base 10):
fonte
*>$^n
e.sum==$n
. Também não é necessário o espaço entremy
e@f
JavaScript (ES6),
6160 bytesCalcula os números 1-2-3-Tribonacci até atingir o número original e, à medida que a recursão se desenrola, tenta subtrair cada um por sua vez, duplicando o resultado à medida que avança.
Editar: salvou 1 byte graças a @Arnauld.
fonte
n=>(g=(x,y,z)=>(n>x&&g(y,z,x+y+z)*2)+!(n<x||![n-=x]))(1,2,3)
salvar um byte?n<x||
mas isso![]
é apenas genialidade.Lote,
151148145 bytesPorta da minha resposta JavaScript. Editar: salvei 3 bytes passando meus argumentos de sub-rotina em ordem inversa e outros 3 bytes usando
@
s individuais em cada linha em vez de@echo off
.fonte
Geléia ,
191817 bytesExperimente online!
fundo
Em vez de tentar converter um número inteiro em 1,2,3-Tribonacci base, depois de binário em número inteiro, faremos o oposto: converter números inteiros em binário, depois de 1,2,3-Trionacci base em número inteiro e retornar o mais alto que corresponde à entrada. Isso é facilmente realizado.
Vamos exemplificar o processo para a entrada 63 , em particular a etapa em que 104 é testado. Em binário, do dígito mais significativo ao menos significativo, 104 é igual a
onde a segunda linha representa os valores posicionais desses dígitos.
Podemos estender a sequência 1,2,3-Tribonacci para a direita, observando que os dígitos adicionados cumprem a mesma fórmula recursiva. Por três dígitos, isso dá
Agora, para calcular o valor do número 1,2,3-Tribonacci base, podemos usar a fórmula recursiva. Como cada número é a soma dos três números à direita (na tabela acima), podemos remover o primeiro dígito e adicioná-lo aos três primeiros dígitos da matriz restante. Após 7 etapas, que é igual ao número de dígitos binários de 104 , é raro ficar com apenas três dígitos.
Agora, como o primeiro e o último dígito restante possuem valor posicional 0 , o resultado é o dígito do meio, ou seja, 63 .
Como funciona
fonte
Gelatina ( garfo ),
1716 bytesEconomizei 1 byte graças a @Dennis, que jogou golfe sem nem mesmo executá-lo.
Isso se baseia em um garfo de geléia, onde ainda estou trabalhando decepcionantemente na implementação de um eficiente átomo de resolução Frobenius. Para aqueles que estão interessados, gostaria de igualar a velocidade do Mathematica
FrobeniusSolve
e, felizmente, há uma explicação de suas método no artigo "Fazendo mudanças e encontrando repetições: equilibrando uma mochila", de Daniel Lichtblau.Explicação
fonte
ḣ3S;µ¡¶3RṚdzæFṪḄ
? Não tenho seu garfo instalado, então não posso testar.³
referencia o primeiro argumento.jelly.py
tinha algumas outras coisas depois desse último commit.dc ,
110102 bytesBem, parece que grandes mentes que pensam da mesma forma. Aparentemente, o algoritmo que criei para contornar as limitações de
dc
inventei é coincidentemente o mesmo usado na resposta do @LliwTelrac. Interessante.Experimente online!
fonte
Python 2 , 93 bytes
Esta é uma porta da minha resposta Jelly .
Experimente online!
fonte
utilitários bash + BSD (OS X, etc.), 53 bytes
utilitários bash + GNU (funciona também com BSD), 59 bytes
Entrada e saída em ambos os itens acima estão em binário.
Experimente a versão GNU no TIO. (O exemplo vinculado a demonstra a entrada de 111111, que é 63 em binário, e a saída de 1101000, que é 104 em binário.)
Não acho que o TIO ofereça uma opção BSD, mas se você tiver um Mac disponível, poderá experimentá-los por aí. (O programa de 59 bytes é muito mais rápido que o programa de 53 bytes.)
Infelizmente,
seq
não pode simplesmente ser descartado na solução BSD no lugar dejot
, pois o formato de saída paraseq
é diferente para saídas acima de 999999. (Isso começa a ser um problema para entradas em torno de 32, desde 32 ^ 4> 1000000.)Você pode substituir
jot
acima porseq -f%.f
para que isso funcione com os utilitários GNU, mas pelos mesmos 59 bytes, você pode usar a solução GNU acima, que é muito mais rápida.fonte