Prefácio
Na canção bem conhecida, Os Doze Dias de Natal , o narrador recebe vários presentes por dia. A música é cumulativa - em cada verso, um novo presente é adicionado, com uma quantidade um maior que o presente anterior. Uma perdiz, duas pombas, três galinhas francesas e assim por diante.
Em qualquer verso N , podemos calcular a soma acumulada de presentes até o momento na música, encontrando o N- ésimo número tetraédrico , que fornece os resultados:
Verse 1: 1
Verse 2: 4
Verse 3: 10
Verse 4: 20
Verse 5: 35
Verse 6: 56
Verse 7: 84
Verse 8: 120
Verse 9: 165
Verse 10: 220
Verse 11: 286
Verse 12: 364
Por exemplo, após o versículo 4, tivemos 4 * (1 perdiz) , 3 * (2 pombas) , 2 * (3 galinhas francesas) e 1 * (4 pássaros cantando) . Ao somar estes, obtemos 4(1) + 3(2) + 2(3) + 1(4) = 20
.
O desafio
Sua tarefa é escrever um programa ou função que, dado um número inteiro positivo representando o número de presentes 364 ≥ p ≥ 1 , determine em que dia (verso) do Natal é.
Por exemplo, se p = 286 , estamos no 11º dia de Natal. No entanto, se p = 287 , a próxima carga de presentes começou, ou seja, é o 12º dia.
Matematicamente, isso é encontrar o próximo número tetraédrico e retornar sua posição em toda a sequência de números tetraédricos.
Regras:
- Isso é código-golfe , então a solução mais curta (em bytes) vence.
- Aplicam-se lacunas de golfe padrão.
- Quando se trata de dias, seu programa deve ser indexado 1.
- Seu envio deve ser um programa ou uma função completa - mas não um trecho.
Casos de teste
1 -> 1
5 -> 3
75 -> 7
100 -> 8
220 -> 10
221 -> 11
364 -> 12
fonte
x=>{while(x>p)p+=r+=++i;return i}
:, tenho certeza de que pode ser reduzido em uma linguagem como JavaScript.Respostas:
Geléia ,
76 bytes-1 byte graças a Dennis (use mínimo vetorizado
«
, e primeiro índicei
)TryItOnline
Quão?
Não é tão eficiente - calcula os números tetraédricos de 1º a enésimo nono em ordem em uma lista e retorna o índice baseado em 1 do primeiro que é igual ou maior.
Anterior 7 byters usando intervalo reduzido
[0,1,2,3,...,n-1]
e contagem tetrahedrals menos do que n:Ḷ+\⁺<µS
,Ḷ+\⁺<ḅ1
,Ḷ+\⁺<ċ1
, eḶ+\⁺<¹S
fonte
Python , 27 bytes
Experimente online!
Uma fórmula direta com algumas curvas, igual à original encontrada pela Level River St.
A equação deslocada
i**3-i==n*6
é próximai**3==n*6
de grandei
. Resolve ai=(n*6)**(1/3)
. Tomando o chão, as voltas para baixo, conforme necessário, compensando a diferença.Porém, existem 6 entradas nos limites em que o erro leva abaixo de um número inteiro que deveria estar acima. Tudo isso pode ser corrigido aumentando ligeiramente o expoente sem introduzir mais erros.
Python , 38 bytes
A fórmula
n=i*(i+1)*(i+2)/6
para os números tetraédricos podem ser mais bem escrita emi+1
comon*6=(i+1)**3-(i+1)
. Então, encontramos o menori
para o quali**3-i<n*6
. Cada vez que incrementamos ai
partir de 1, as chamadas recursivas são adicionadas1
à saída. Começando emi=1
vez dei=0
compensar a mudança.fonte
**.33359
funciona para um byte extra.lambda n:n**.3336//.5501
salva alguns bytes.J , 12 bytes
Pode haver uma maneira mais eficiente de fazer isso, mas essa é uma oportunidade adorável de usar a inversão de função interna de J.
Experimente online!
Como funciona
fonte
Python , 22 bytes
Fortemente inspirado pela resposta Python do @ xnor .
Experimente online!
fonte
Geléia , 7 bytes
Experimente online!
Como funciona
fonte
JavaScript (ES6), 33 bytes
Com base na fórmula recursiva:
A segunda expressão também pode ser escrita como ...
... qual é o que estamos usando aqui.
a(i - 1)
é realmente armazenado nak
variável e passado para a próxima iteração aték >= n
.Casos de teste
Mostrar snippet de código
fonte
Ruby, 26 bytes
Editar: versão alternativa, ainda 26 bytes
Versão original
Usa o fato de que
T(x) = x(x+1)(x+2)/6 = ((x+1)**3-(x+1))/6
está muito próximo(x+1)**3/6
.A função simplesmente multiplica por 6, localiza uma versão ligeiramente alterada da raiz do cubo (sim, são necessárias 5 casas decimais) e retorna o resultado truncado para um número inteiro.
Programa de teste e saída
fonte
0.3336
parece funcionar para a versão original. (Edit: Deixa pra lá, Dennis salienta que eu estava esquecendo o 364.) #JavaScript,
3633 bytes-3 bytes graças a Luke (fazendo a função ser curry)
Esta é uma função lambda sem nome que pode ser atribuída
func
e chamada comfunc(220)()
, conforme descrito nesta meta post . Minha função original, sem curry, fica assim:Esta resposta usa o fato de que x th número tetraédrico pode ser encontrado com a seguinte função:
A submissão funciona aumentando
i
e encontrando recursivamentetetrahedral(i)
, até que seja maior ou igual an
(o número de presentes dados).Quando chamado com um argumento conforme o esperado
i = undefined
, e, portanto, não é maior quen
. Isso significa quef(n,-~i)
é executado e-~undefined
avaliado como1
, o que desencadeia a recursão.Snippet de teste:
fonte
n=>g=i=>n<=i/6*++i*++i?i-2:g(~-i)
. Você chamaria assimf(2)()
.i=>n<=i
MATL ,
1211 bytesExperimente online!
Explicação
fonte
05AB1E , 10 bytes
Experimente online!
Explicação
fonte
[N2Ý+P6÷¹Q#N>
legal.Pyke, 11 bytes
Experimente aqui!
fonte
Mathematica, 26 bytes
Função sem nome, usando um argumento inteiro não negativo e retornando um número inteiro não negativo (sim, funciona também para o dia
0
). Queremos encontrar o menor número inteiroi
para o qual a entrada#
é no máximoi(i+1)(i+2)/6
, que é a fórmula para o número de presentes dados nos primeirosi
dias. Através de truques algébricos leves, a desigualdade# ≤ i(i+1)(i+2)/6
é equivalente a(i+1) + 6# ≤ (i+1)^3
. Portanto, a estrutura0//.i_/;i+6#>i^3:>i+1
começa com a0
e continua adicionando1
enquanto o testei+6#>i^3
é satisfeito; depois(...)-1&
subtrai1
no final (em vez de gastar bytes com parênteses dentro da desigualdade).Se deixarmos os 12 dias de Natal continuar, poderemos lidar com cerca de 65536 dias antes do limite de recursão
//.
interno para interromper o processo ... isso é cerca de 4,7 * 10 ^ 13 dias, ou cerca de dez vezes a idade do universo até agora ....fonte
J , 9 bytes
Experimente online!
Isso é mais ineficiente do que usar o inverso do fatorial, mas passa a ser mais curto.
Por exemplo, se o número inteiro de entrada for n = 5, faça o intervalo
[2, n+1]
.Estes são os primeiros 5 números tetraédricos. O próximo passo é determinar a que intervalo (dia) n pertence. Existem n +1 = 6 intervalos.
Então n = 5 pertence ao intervalo 3, que é
(4, 10]
e o resultado é 3.Explicação
fonte
Python, 43 bytes
Economizou 5 bytes graças ao @FlipTack e outros 3 graças ao @xnor !
fonte
f(220)=11
, o que deveria serf(220)=10
.and-~f(n,i+1)
porand f(n,i+1)or i
. Estranhamente, geralmente é mais curto quando você está contando uma variável recursivamente para não retorná-la, mas para incrementar a saída recursivamente.Japonês , 12 bytes
Teste online!ou Verifique todos os casos de teste de uma só vez
Como funciona
Esta é uma simplificação da fórmula tetraédrica que várias outras respostas estão usando:
Ao substituir
x - 1
parax
, podemos simplificar esta consideravelmente:Portanto, o resultado correto é um a menos que o menor número inteiro, de
x
modo que(x^3 - x) / 6
maior ou igual à entrada.Solução de 13 bytes, inspirada na resposta da @ xnor :
Mais algumas soluções @ETHproductions e eu brinquei com
Teste aqui .
fonte
SmileBASIC, 43 bytes
I
é o dia,R
é oi
th número triangular eP
é oi
número th tetrahedral (número de presentes).Acho que uma resposta semelhante em outro idioma, talvez:
x=>{while(x>p)p+=r+=++i;return i}
poderia ser muito boa.fonte
?I
no final, não é?Python 3,
4846 bytesfonte
221
irá travá-lo.Mathematica,
3125 bytesfonte
Haskell,
2123 bytesEdit: Como o xnor apontou, a solução original (
floor.(/0.82).(**0.4)
) não funcionou entre os dias de natalfonte
Lote, 69 bytes
Calcula manualmente números tetraedronais.
fonte
Pitth 11 bytes
Experimente online!
praticamente traduziu a resposta de Dennis para Pyth
fonte
R, 19 caracteres
com base na resposta do xnor em
Python
.fonte
QBIC , 19 bytes
Isso rouba a fórmula de @xnor:
Tentei discar a resolução para 0,3336 para salvar um byte, mas isso falhou na caixa de teste final.
fonte
Bash + bc, 44 bytes
fonte