11 = (1 + 2 + 3 + 4 + 5) - (1 + 2 + 3) + (6) - (4)


35

Dado um número inteiro positivo N , sua tarefa é retornar o número de etapas exigidas pelo seguinte algoritmo para atingir N :

  1. Encontre o menor número triangular T i tal que T i  ≥ N . Construa a lista correspondente L = [1, 2, ..., i] .

  2. Enquanto a soma dos termos de L for maior que N , remova o primeiro termo da lista.

  3. Se a soma dos termos de L agora for menor que N , incremente i e inclua-a na lista. Continue com o passo 2.

Paramos assim que N é alcançado. Somente o primeiro passo é executado sistematicamente. Os passos 2 e 3 podem não ser processados.

Exemplos

Abaixo está um exemplo para N = 11 :

Exemplo

Portanto, a saída esperada para N = 11 é 4 .

Outros exemplos:

  • N = 5 - Começamos com T 3 = 1 + 2 + 3 = 6 , seguido por 2 + 3 = 5 . Saída prevista: 2 .
  • N = 10 - Somente o primeiro passo é necessário porque 10 é um número triangular: T 4 = 1 + 2 + 3 + 4 = 10 . Saída prevista: 1 .

100 primeiros valores

Abaixo estão os resultados para 1 ≤ N ≤ 100 :

  1,  2,  1,  4,  2,  1,  2, 10,  2,  1,  4,  2,  6,  2,  1, 22,  8,  2, 10,  2,
  1,  2, 12,  6,  2,  4,  2,  1, 16,  2, 18, 50,  2,  6,  2,  1, 22,  6,  2,  4,
 26,  2, 28,  2,  1,  8, 30, 16,  2,  6,  4,  2, 36,  2,  1,  2,  4, 12, 40,  2,
 42, 14,  2,108,  2,  1, 46,  2,  6,  4, 50,  2, 52, 18,  2,  4,  2,  1, 56, 12,
  2, 20, 60,  4,  2, 22, 10,  2, 66,  2,  1,  4, 10, 24,  2, 40, 72,  8,  2,  6

Regras

  • Você pode escrever um programa completo ou uma função que imprima ou retorne o resultado.
  • Você é obrigado a processar qualquer N ≤ 65536 em menos de um minuto em hardware de gama média.
  • Com tempo suficiente, seu programa / função deve, teoricamente, funcionar para qualquer valor de N que seja suportado nativamente pelo seu idioma. Caso contrário, explique o motivo na sua resposta.
  • Isso é código de golfe, então a resposta mais curta em bytes vence!

Relacionado. (Eu suspeito que você já sabe sobre este, mas apenas publicá-la para a posteridade)
ETHproductions

Qual é o valor máximo de N que precisamos manipular?
Lucas

@ Luke Por favor, veja as regras atualizadas.
Arnauld

Respostas:


4

Geléia , 29 31 bytes

ÆDµ’H+Ṛ%1$ÐḟṂ
>TḢ_@Ç}‘Ḥ
R+\ðċȯç

Um link monádico que retorna o resultado (N = 65536 leva menos de dois segundos).

Experimente online!

Quão?

Para uma explicação completa do algoritmo, consulte o post fantástico de Martin Ender .

ÆDµ’H+Ṛ%1$ÐḟṂ - Link 1, smallest natural number, M, that satisfies the below*, N
              - * N = T(M) - T(i) for some non-negative integer i <= M
ÆD            - divisors of N
  µ           - monadic chain separation, call that d
   ’          - increment d (vectorises)
    H         - halve (vectorises
      Ṛ       - reverse d
     +        - add (vectorises)
          Ðḟ  - filter discard if:
       %1$    -   modulo one is truthy (those which are the result of even divisors)
            Ṃ - minimum

>TḢ_@Ç}‘Ḥ - Link 2, evaluate result for non-triangular: list of T(1) to T(N), N
>         - T(i) > N
 T        - truthy indexes
  Ḣ       - head (yields the first i for which T(i) > N)
     Ç}   - call last link (1) as a monad converted to a dyad using the right argument
   _@     - subtract with reverse @rguments
       ‘  - increment
        Ḥ - double 

R+\ðċȯç - Main link: N
R       - range -> [1,2,...,N]
 +\     - reduce with addition -> [1,3,6,10,...T(N)]
   ð    - dyadic chain separation, call that t
    ċ   - count occurrences of N in t (1 if N is triangular else 0)
      ç - call last link (2) as a dyad(t, N)
     ȯ  - or

A implementação de programa completo de 29 bytes que criei do algoritmo descrito leva 4 min 30 para N = 65536 no meu laptop, portanto, suponho que não conte.

Ṁ‘ṭµS<³µ¿
ḊµS>³µ¿
0®Ḃ‘©¤ĿÐĿL’

Usar um loop while para cada etapa 3 e reutilizá-la como etapa 1 é igual ao comprimento que eu posso gerenciar com a inicialização da lista, pois nenhuma verificação na etapa 3 significa criar uma lista até que nada permaneça e depois encontrar o primeiro índice do valor:

ḊµS>³µ¿
Ṁ‘ṭ
Ḥ½_.ĊR®Ḃ‘©¤ĿÐĿS€i

25

Mathematica, 79 bytes

Min[2#/(d=Divisors@#~Cases~_?OddQ)+d]-2⌊(2#)^.5+.5⌋+⌈Sqrt[8#+1]~Mod~1⌉&

Explicação

Não me incomodei em implementar o algoritmo no desafio, então queria procurar um atalho para a solução. Embora eu tenha encontrado um, infelizmente não bate a resposta do Mathematica que implementa o algoritmo. Dito isso, tenho certeza de que ainda não está otimizado, e pode haver outros idiomas que podem se beneficiar dessa abordagem ou de algumas das idéias obtidas no processo.

Por isso, afirmo que a sequência que devemos calcular é:

f (n) = 2 * ( A212652 (n) - A002024 (n)) + 1 + A023532 (n-1)

Como alternativa, é f (n) = 1 se n for um número triangular ef (n) = 2 * ( A212652 (n) - A002024 (n) + 1) caso contrário.

Na primeira expressão, A023532 simplesmente codifica esses dois casos diferentes. As outras duas seqüências (mais 1) são a diferença entre o maior número inteiro k na decomposição mais longa de n em números inteiros consecutivos (k-i + 1) + (k-i + 2) + ... + k = n e o maior número inteiro j, de modo que 1 + 2 + ... + j <n .

Em palavras um pouco mais simples, é aqui como encontramos a resposta para os números não triangular: primeiro, encontrar o maior número triangular T j que é menos do que n . Então j é o penúltimo número inteiro que é adicionado durante a etapa 1 (porque depois de adicionar j + 1 , teremos excedido n ). Decomponha n em tantos (ou tão pequenos) números inteiros consecutivos quanto possível e chame o máximo entre esses números k . O resultado é simplesmente 2 * (kj) . A razão intuitiva para isso é que o máximo na decomposição cresce 1 ponto a cada dois passos e paramos quando atingimosk .

Precisamos mostrar quatro coisas para provar que isso funciona:

  1. f (n) = 1 para números triangulares. Esse é trivialmente o caso, porque o primeiro passo simplesmente interage com todos os números triangulares. Se acertarmos n exatamente durante esse processo, terminaremos e houve apenas uma etapa para calcular.
  2. Para todos os outros números, sempre terminamos após uma etapa de exclusão, nunca após uma etapa de inserção. Isso significa que todos os outros f (n) são pares.
  3. Em cada etapa de inserção após a primeira, adicionamos apenas um único número. Isso garante que alcançaremos uma decomposição incluindo pares de etapas k após kj .
  4. A decomposição final de n que obtemos é sempre a maior decomposição possível de n em números inteiros consecutivos, ou seja, é sempre a decomposição de n com o menor valor máximo entre os números somados. Em outras palavras, o último número que adicionamos à soma é sempre A212652 (n) .

Já mostramos por que (1) é verdadeiro. Em seguida, provamos que não podemos terminar em uma etapa de inserção, exceto a inicial (o que não ocorre para números não triangulares).

Suponha que tenhamos terminado uma etapa de inserção, atingindo n após adicionar um valor p à soma. Isso significa que, antes desta etapa de inserção, o valor era np ( ou menos se adicionássemos vários valores de uma vez). Mas essa etapa de inserção foi precedida por uma etapa de exclusão (já que não poderíamos ter atingido n durante a etapa 1). O último valor q removemos durante esta etapa de exclusão foi necessariamente menor que p devido à maneira como o algoritmo funciona. Mas isso significa que, antes de removermos q , tínhamos n-p + q ( ou menos ), que é menor que n. Mas isso é uma contradição, porque teríamos que parar de remover números inteiros quando atingimos n-p + q em vez de remover outro q . Isso prova o ponto (2) acima. Então agora sabemos que sempre terminamos em uma etapa de exclusão e que, portanto, todos os números não triangulares têm saídas pares.

A seguir, provamos (3) que cada etapa de inserção pode inserir apenas um valor. Este é essencialmente um corolário de (2). Mostramos que, após adicionar um valor, não podemos atingir n exatamente e, como a prova estava usando uma desigualdade, também não podemos terminar abaixo de n (já que n-p + q ainda seria menor que n e não deveríamos ter removido que muitos valores em primeiro lugar). Portanto, sempre que adicionamos um único valor, é garantido que excedamos n, porque ficamos abaixo de n removendo um valor menor. Portanto, sabemos que a extremidade superior da soma cresce 1 em cada dois passos. Sabemos o valor inicial deste extremidade superior (é o menor m tal queT m > n ). Agora só precisamos descobrir esse limite superior quando chegarmos à soma final. Então o número de etapas é simplesmente o dobro da diferença (mais 1).

Para fazer isso, provamos (4) que a soma final é sempre a decomposição de n em tantos números inteiros quanto possível, ou a decomposição em que o máximo nessa decomposição é mínimo (ou seja, é a decomposição mais antiga possível). Faremos isso novamente por contradição (a redação desta parte pode ser um pouco mais rigorosa, mas eu já gastei muito tempo nisso ...).

Digamos que a decomposição mais antiga / mais longa possível de n seja a + (a + 1) + ... (b-1) + b , a ≤ b , e digamos que o algoritmo a ignore. Isso significa que, no momento em que b é adicionado, a não deve mais fazer parte da soma. Se a fizesse parte da soma s , teríamos n ≤ s naquele momento. Portanto, ou a soma contém apenas os valores de a a b , que é igual a n e paramos (portanto, não pulamos essa decomposição) ou há pelo menos um valor menor que a na soma, ganhe nesse caso n <se esse valor seria removido até atingirmos a soma exata (novamente, a decomposição não foi ignorada). Portanto, teríamos que nos livrar de a antes de adicionar b . Mas isso significa que teríamos que chegar a uma situação em que a seja o menor componente da soma e o maior ainda não seja b . No entanto, nesse ponto, não podemos remover a , porque a soma é claramente menor que n (já que b está ausente), portanto, é necessário adicionar valores primeiro até adicionarmos b e pressionar n exatamente. Isso prova (4).

Então, juntando essas coisas: sabemos que o primeiro par de etapas nos fornece um valor máximo de A002024 (n) . Sabemos que o valor máximo da decomposição final é A212652 (n) . E sabemos que esse máximo é incrementado uma vez em cada par de etapas. Portanto, a expressão final é 2 * ( A212652 (n) - A002024 (n) + 1) . Essa fórmula quase funciona para números triangulares, exceto que para aqueles que precisamos apenas de 1 etapa em vez de 2, é por isso que corrigimos o resultado com a função indicadora dos números triangulares (ou sua inversa, o que for mais conveniente).

Finalmente, quanto à implementação. Para a sequência anterior, estou usando a fórmula MIN (ímpar d | n; n / d + (d-1) / 2) da OEIS. Acontece que salvamos alguns bytes se levarmos o fator 2 para essa expressão para obter MIN (ímpar d | n; 2n / d + d-1) , porque esse -1 então cancela com o +1 na minha primeira versão de f (n) que codifica diretamente os dois casos para números triangulares e não triangulares. No código, isso é:

Min[2#/(d=Divisors@#~Cases~_?OddQ)+d]

Para a última sequência ( 1, 2, 2, 3, 3, 3, ...), podemos usar um formulário fechado simples:

⌊(2#)^.5+.5⌋

E, finalmente, a função indicadora inversa dos números triangulares é 0 sempre que 8n + 1 é um quadrado perfeito. Isso pode ser expresso no Mathematica como

⌈Sqrt[8#+1]~Mod~1⌉

Existem várias maneiras de expressar essas duas últimas seqüências e de mudar um deslocamento constante entre elas. Portanto, tenho certeza de que essa ainda não é uma implementação ideal, mas espero que isso possa dar aos outros um ponto de partida para examinar novas abordagens no suas próprias línguas.

Desde que eu resolvi esse problema, aqui está um gráfico da sequência de n = 1000 (eu também poderia calcular 100k em alguns segundos, mas na verdade não mostra nenhum insight adicional):

insira a descrição da imagem aqui

Pode ser interessante examinar as variações dessas linhas muito retas, mas deixarei isso para outra pessoa ...


Finalmente, reservei um tempo para ler sua resposta completamente. Isto é brilhante. Observe que (3) já foi assumido no algoritmo (a etapa 3 é um se , não por um tempo ), mas a prova é - é claro - muito bem-vinda.
Arnauld

@ Arnauld Obrigado. :) Devo ter esquecido / interpretado mal a parte if / while. Ainda bem que não faz diferença então.
Martin Ender

7

Mathematica, 72 bytes

(For[l=u=c=k=0,k!=#,c++,If[#>k,While[#>k,k+=++u],While[#<k,k-=l++]]];c)&

Função pura usando um argumento inteiro.

Como funciona

For[ ... ]

Um Forlaço.

l=u=c=k=0

Inicialização; defina l(inferior), u(superior), c(contador) e k(soma) como 0.

k!=#

Condição; repita enquanto knão for igual à entrada.

c++

Incremento; incrementar o contador c.

If[#>k,For[,#>k,,k+=++u],For[,#<k,,k-=l++]]

Corpo

If[#>k, ... ]

Se a entrada for maior que k:

While[#>k,k+=++u]

Enquanto a entrada for maior que k, incremente ue aumente kem u.

Se a entrada não for maior que k:

While[#<k,k-=l++]

Enquanto que a entrada é menor do que k, decremento kpor le incremento l.

( ... ;c)

Retorne capós o loop.


11
For[,...]batidas While[...].
Martin Ender

5

Python 2 , 104 bytes

N=input();i=s=0;l=()
while N!=sum(l):exec'while sum(l)'+['<N:i+=1;l+=i,','>N:l=l[1:]'][s%2];s+=1
print s

Experimente online!

Alterna entre adicionar termos ao final da lista e remover termos desde o início.


5

Haskell , 70 63 68 64 bytes

EDITAR:

  • -7 bytes: Livre-se de um espaço, dois sinais e alguns parênteses, negando o sentido de a. Corrigidos erros de um por um na explicação.
  • +5 bytes: Argh, perdeu completamente o requisito 65536 e descobriu que (1) potências de 2 são particularmente caras, porque elas só são atingidas quando você chega ao número em si (2), portanto, é somar longos intervalos em torno zero) o tempo todo. Substituiu a soma por uma fórmula matemática.
  • -4 bytes: ajustado ae blinearmente para obter termos na fórmula da soma para cancelar.

1#1 é uma função anônima que recebe e retorna um número inteiro.

Use como (1#1) 100.

1#1
(a#b)n|s<-a*a-b*b=sum$[a#(b+2)$n|s>8*n]++[(b#a)(-n)+1|s<8*n]

Experimente online!

Como funciona

  • (a#b)nrepresenta a etapa atual do cálculo. a, bsão números 1, 3, 5, ..enquanton pode ser positivo ou negativo, dependendo da etapa.
    • Quando na etapa 1 ou 3, representa a lista [(a+1)/2,(a+3)/2..(b-1)/2]e o número da meta-n .
    • Na etapa 2, representa a lista [(b+1)/2,(b+3)/2..(a-1)/2]e o número da meta n.
  • A estranha correspondência entre a, be as listas é capaz de somar com a expressão curta s=a*a-b*b.
    • Nos passos 1 e 3, é o mesmo que s= -8*sum[(a+1)/2..(b-1)/2].
    • Na etapa 2, é o mesmo que s=8*sum[(b+1)/2..(a-1)/2].
  • A ramificação é feita tendo compreensões de lista que produzem elementos em apenas um caso cada e somando os resultados.
    • Se s>8*n, então, bé incrementado por 2 antes da recorrência.
      • Nas etapas 1 e 3, isso aumenta a lista, enquanto na etapa 2, reduz a lista.
    • Se s<8*n, a recursão altera a etapa trocando ae b, e negando n, e 1 é adicionado ao resultado.
    • Se s==8*n, nenhuma das duas compreensões da lista fornecer elementos, então a soma é 0.
  • (1#1) nrepresenta um "estágio 2" fictício antes de iniciar, que é imediatamente alterado para a etapa 1, a partir da qual é criada a lista [1..0]=[].

4

PHP> = 7.0, 74 bytes

while($i=$r<=>$argn)for($s++;($r<=>$argn)==$i;)$r+=$i+1?-++$y:++$x;echo$s;

use o operador da nave espacial

Experimente online!

Expandido

while($i=$r<=>$argn) # if input is not equal sum of array
  for($s++;  # raise count steps
  ($r<=>$argn)==$i;)
  # so long as value compare to input has not change to lower/higher to higher/lower or equal  
    $r+=$i+1
      ?-++$y # if $i was higher remove the first integer
      :++$x;} # if $i was lower add the next highest integer     
echo$s; # Output steps

O que é $argn?
chx 15/05

@chx Uma variável que está disponível quando você o PHP na linha de comando com a opção -R php.net/manual/en/features.commandline.options.php
Jörg Hülsermann

Uau. Eu nunca ouvi falar de -Rmuito menos argvou argi. Eu conhecia argc e argv, é claro. Muito interessante, obrigado.
chx 15/05

4

C, 94 91 bytes

Experimente on-line

c;s;m;M;f(n){while(s-n){while(s<n)s+=++M;c++;if(s==n)break;while(s>n)s-=++m;c++;}return c;}

Uso extensivo em variáveis ​​não inicializadas oO
YSC 15/17

@YSC em C, números inteiros declarados globalmente não inicializados são definidos como zero no tempo de compilação. Leia mais
Khaled.K

Esqueceu sobre isso. Obrigado por este lembrete.
YSC

FYI, eu postei uma outra resposta C . Pelo menos um dos truques que usei não funcionará com outros compiladores (os ausentes return), mas, para os que o fizerem, sinta-se à vontade para incorporá-los à sua resposta.
hvd 15/05

3

JavaScript (ES6), 82 bytes

D=(o,a=0,b=1,d=1,c=0)=>a<o?D(o,a+=b,b+1,d,c+(a>=o)):a>o?D(o,a-=d,b,d+1,c+(a<=o)):c

Snippet de teste


Desculpe dizer isso, mas cada ↄ conta como 3 bytes. Eu acho que não importa, pois é trivialmente renomável.
Ørjan Johansen

@ ØrjanJohansen Obrigado por me lembrar. Eu realmente deveria me lembrar de pontuar meu código em bytes, e não em comprimento. Não acho que exista um consenso da comunidade sobre "trivialmente renomáveis ​​[variáveis]", por isso editei o post. Ah bem.
R. Kap 14/05

3
O trecho falha com "Demasiada recursão" em 6553. 6553 funciona no Nó (6.9.1) localmente, mas 65536 não ("Tamanho máximo da pilha de chamadas excedido").
Eush77 14/05

3

dc , 61 bytes

dsN[ddd9k4*d2*1+dv-0k2/-d1+*2/-d[q]s.0=.-lN-0lN-sNlFx]dsFxz2-

Experimente online!

Explicação

Macro recursiva principal:

ddd9k4*d2*1+dv-0k2/-d1+*2/-d[q]s.0=.-lN-0lN-sNlFx
   9k4*d2*1+dv-0k2/-                              # Compute triangular root
                    d1+*2/                        # Compute triangular number
  d                       -d[q]s.0=.              # Check if sum is exact
 d                                  -lN-          # Compute S-N or S+N
                                        0lN-sN    # Update N := -N
d                                             lFx # Leave the trail and recurse

Esta macro:

  1. Localiza o número triangular mínimo que excede o número atual na pilha (usando o método modificado fórmula da raiz triangular ).
  2. Verifica se a soma triangular S representa exatamente o número atual. Sai se houver.
  3. Prossiga para a etapa 1 com S+N(super-aproximação) ouS-N (sub-aproximação), a escolha alterna entre iterações.

Quando sai, a trilha deixada na pilha informa ao programa principal quantas iterações foram necessárias.


3

Python 3, 150 138 bytes

n=int(input())
S=sum
l=[1]
i=s=1
while S(l)<n:i+=1;l+=[i]
while S(l)!=n:
 while S(l)>n:l.pop(0)
 s+=1
 if S(l)<n:i+=1;l+=[i];s+=1
print(s)

Changelog:

  • Alterado anexado a + =, removido mais (obrigado musicman523, Loovjo; -12 bytes)

11
A etapa 2 pode remover um ou vários termos de uma vez da lista (como 1, 2 e 3 no exemplo de N = 11), mas é contada como uma etapa de qualquer maneira.
Arnauld

@Arnauld ignorou isso; fixo.
L3viathan

11
Você pode explicar por que o elsenecessário? Eu acredito que as elseexecuções sempre, porque o loop sempre termina normalmente (sem break), e parece funcionar bem sem ele .
Musicman523

Você pode pular a A=l.appendpeça e usá-la l+=[x].
Loovjo 14/05

3

Lote, 126 bytes

@echo off
set/an=s=l=u=0
:l
if %s% lss %1 set/as+=u+=1,n+=!!l&goto l
if %s% gtr %1 set/as-=l+=1&goto l
cmd/cset/an+n+2-!l

Explicação: lé zero se a etapa 2 nunca foi executada. Isso permite nrastrear o número de iterações da etapa 3. Como o algoritmo nunca para na etapa 3, ele deve ter executado a etapa 1 uma vez e a etapa 2n+1 vezes para um total de n+n+2etapas. No entanto, se o parâmetro for um número triangular, a etapa 2 nunca será executada, portanto, precisamos subtrair uma etapa.


3

Python 2, 86 81 bytes

n=input()
l=u=i=s=0
while n:k=n>0;i+=k^s;s=k;l+=k;n-=l*k;u+=k^1;n+=u*-~-k
print i

Experimente online!

Calcula o caso de teste 65536 em0.183s no TIO.


Esta versão recursiva em 84 bytes não pode computar todos os valores até 65536:

def f(n,l=[0],m=1):k=n>sum(l);return n==sum(l)or f(n,[l[1:],l+[l[-1]+1]][k],k)+(m^k)

Experimente online!


2

Mathematica, 92 bytes

(For[q=a=b=0;t={},t~AppendTo~q;q!=#,If[q<#,q+=++b,q-=++a]];Length@Split@Sign@Differences@t)&

Função pura pegando um argumento inteiro e retornando um número inteiro.

As variáveis ae brepresentam os números iniciais e finais (que mudam constantemente) na soma em consideração, enquanto qrepresentam o total atual (dos números de a+1até b); tmantém o controle de todos os valores qencontrados até o momento. Após inicializar essas variáveis, oFor loop continua em execução If[q<#,q+=++b,q-=++a], o que adiciona um novo número ao final ou subtrai o número na frente, conforme determinado pela especificação, até qigualar a entrada.

Agora só precisamos extrair o número de etapas da tlista de qvalores encontrados ao longo do caminho. Por exemplo, quando a entrada é 11, o Forloop sai com tigual {0,1,3,6,10,15,14,12,9,15,11}. A melhor maneira que encontrei para calcular o número de etapas a partir disso é contar quantas vezes as diferenças mudam de subir para diminuir; é isso que o comando detalhado Length@Split@Sign@Differences@tfaz, mas suspeito que possa ser melhorado.


2

C (tcc), 71 bytes (61 + 10)

Argumentos da linha de comando (incluindo um espaço):

-Dw=while

Fonte:

c,m,M,s;f(n){w(++c,s-n){w(c&s<n)s+=++M;w(~c&s>n)s-=m++;}--c;}

Como funciona:

cconta o número de etapas. me Marmazene o mínimo e o máximo do intervalo,s a soma. Inicialmente, são todos zero.

Continuamente, cé aumentado es comparado a n. Contanto que sejam desiguais:

  • Se cfor ímpar, contanto que s<n, adicione um número inteiro ao final do intervalo: aumenteM em um e sem M.

  • Se cfor par, desde que s>nremova um número inteiro do início do intervalo: diminua semm e aumente mem um.

Quando o loop sair, c foi aumentado muitas vezes. Decrementar produz o resultado correto e é calculado no registro correto para atuar como o valor de retorno.

Curiosamente, usa exatamente os mesmos nomes de variáveis ​​que a resposta C de Khaled.K . Eles não são copiados.


1

Perl 6 , 114 bytes

{((0,0,1),->(\a,\b,\c){b,(a..*).first(->\d{(d,b).minmax.sum*c>=$_*c}),-c}...->(\a,\b,\c){(a,b).minmax.sum==$_})-1}

(inspirado por um antigo Haskell implementação )

Experimente
Ele roda com uma entrada de 65536 em menos de 45 segundos no meu computador, mas não consegui executá-lo em menos de 60 segundos com o TIO.run.
Eu tenho o Rakudo v2017.04 +, onde ele tem v2017.01 .
O Rakudo / NQP / MoarVM obtém otimizações quase diariamente, portanto, pode haver um número intermediário necessário para obtê-lo com o tempo.


Expandido

{
  (

    # generate a sequence

    (0,0,1),           # initial value 

    -> (\a,\b,\c) {
      b,               # swap the first two values

      (a..*)
      .first(          # find the first number that brings us to or past the input

        -> \d {
          (d,b).minmax # get a Range object regardless of which is larger
          .sum * c     # sum it, and negate it every other time

          >=           # is it equal to or greater than

          $_ * c       # negate the original input every other time
        }

      ),

      -c               # invert for next round
    }

    ...                # keep doing that until

    -> (\a,\b,\c) {
     (a,b).minmax.sum == $_ # it finally reaches the input
    }

  ) - 1 # count the number of elements in the sequence
        # and subtract one for the initializer
}

Observe que o Rakudo possui uma otimização para Range.sumque ele não precise percorrer todos os valores.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.