Sequência Q de Hofstadter

25

Definição

  1. a (1) = 1
  2. a (2) = 1
  3. a (n) = a (na (n-1)) + a (na (n-2)) para n> 2 onde n é um número inteiro

Tarefa

Dado inteiro positivo n, gere a(n).

Casos de teste

n  a(n)
1  1
2  1
3  2
4  3
5  3
6  4
7  5
8  5
9  6
10 6
11 6
12 8
13 8
14 8
15 10
16 9
17 10
18 11
19 11
20 12

Referência

Freira Furada
fonte
Relacionado .
Leaky Nun
1
Podemos retornar True nos idiomas em que pode ser usado como 1 ?
217 Dennis
1
@Dennis Se nesse idioma, true é equivalente a 1, então sim.
Freira vazando
4
Além do link OEIS, pode ser bom fazer referência ao GEB onde a sequência apareceu pela primeira vez.
Martin Ender

Respostas:

9

Retina , 84 83 79 74 bytes

A contagem de bytes assume a codificação ISO 8859-1.

.+
$*;1¶1¶
+`;(?=(1)+¶(1)+)(?=(?<-1>(1+)¶)+)(?=(?<-2>(1+)¶)+)
$3$4¶
G3=`
1

Experimente online! (A primeira linha ativa um conjunto de testes separado por avanço de linha.)

Vou ter que jogar isso mais tarde.

Martin Ender
fonte
9

Haskell, 35 33 bytes

a n|n<3=1|b<-a.(-)n=b(b 1)+b(b 2)

Define uma função a.

Anders Kaseorg
fonte
2
Truque agradável com a ligação! Algo como não (b.b)1+(b.b)2seria mais curto que a soma?
xnor
Por que sim, obrigado @xnor.
Anders Kaseorg 29/07
8

Julia, 29 bytes

!n=n<3||!(n-!~-n)+!(n-!~-~-n)

Experimente online!

Como funciona

Redefinimos o operador unário !para nossos propósitos.

Se n é 1 ou 2 , n<3retorna true e esse é o nosso valor de retorno.

Se n for maior que 2 , n<3retornará false e o || ramo é executado. Esta é uma implementação direta da definição, onde ~-nproduz n - 1 e~-~-n produz n - 2 .

Dennis
fonte
7

Sesos, 54 bytes

0000000: eefb5b 04f83a a75dc2 36f8d7 cf6dd0 af7b3b 3ef8d7  ..[..:.].6...m..{;>..
0000015: cfed12 f661f0 ae9d83 ee63e6 065df7 ce6183 af7383  ....a.....c..]..a..s.
000002a: 76ef3c 3f6383 7eff9c b9e37f                       v.<?c.~.....

Experimente online

Desmontado

set numin
set numout
add 1
fwd 1
add 1
fwd 6
get
sub 1
jmp
    jmp
        sub 1
        fwd 1
        add 1
        rwd 1
    jnz
    fwd 1
    sub 1
    rwd 2
    add 2
    jmp
        rwd 4
        jmp
            sub 1
            fwd 3
            add 1
            rwd 3
        jnz
        fwd 4
        jmp
            sub 1
            rwd 3
            add 1
            rwd 1
            add 1
            fwd 4
        jnz
        rwd 3
        jmp
            sub 1
            fwd 3
            add 1
            rwd 3
        jnz
        fwd 4
        add 2
        jmp
            rwd 5
            jmp
                rwd 1
                jmp
                    sub 1
                    fwd 2
                    add 1
                    rwd 2
                jnz
                fwd 1
                jmp
                    sub 1
                    rwd 1
                    add 1
                    fwd 1
                jnz
                rwd 1
                sub 1
            jnz
            fwd 2
            jmp
                sub 1
                rwd 1
                add 1
                rwd 1
                add 1
                fwd 2
            jnz
            fwd 1
            jmp
                rwd 2
                jmp
                    sub 1
                    fwd 1
                    add 1
                    rwd 1
                jnz
                fwd 2
                jmp
                    sub 1
                    rwd 2
                    add 1
                    fwd 2
                jnz
                fwd 1
            jnz
            fwd 3
            sub 1
        jnz
        rwd 2
        jmp
            sub 1
            rwd 3
            add 1
            fwd 3
        jnz
        fwd 1
        sub 1
    jnz
    fwd 2
jnz
rwd 7
put

Ou na notação Brainfuck:

+>+>>>>>>,-[[->+<]>-<<++[<<<<[->>>+<<<]>>>>[-<<<+<+>>>>]<<<[->>>+<<<]>>>>++[<<<<<[<
[->>+<<]>[-<+>]<-]>>[-<+<+>>]>[<<[->+<]>>[-<<+>>]>]>>>-]<<[-<<<+>>>]>-]>>]<<<<<<<.
Anders Kaseorg
fonte
6

C, 43 42 bytes

Guardado 1 byte graças a @Dennis

Cada resposta é a mesma, devo fazer algo diferente!

Experimente online!

a(n){return n<3?:a(n-a(n-2))+a(n---a(n));}

Explicação: é basicamente, a(n-a(n-2))+a(n-a(n-1))mas com um comportamento indefinido muamba (funciona no meu telefone (gcc) e ideone).

betseg
fonte
4
1. Você também deve mencionar o compilador; seu "swag" é um comportamento indefinido. 2. Com o GCC, você não precisa do 1meio ?e do :.
Dennis
@Dennis Curiosamente, essa mesma formulação funciona na minha resposta iterativa do PowerShell ... $b+=$b[$_-$b[$_-2]]+$b[$_---$b[$_]]
AdmBorkBork
@ TimmyD Alguns compiladores podem compilar a (n) antes da n--, e não há um comportamento padrão (ou definido) para isso. Assim, comportamento indefinido.
betseg 29/07
@betseg Sim, eu concordo. Apenas salientando que não é necessariamente exclusivo de C.
AdmBorkBork
@ TimmyD Oh, eu não entendi isso. Eu só queria mudar a função que todo mundo usa, para que a minha fosse diferente e grossa: D
betseg
5

Mathematica, 36 bytes

A contagem de bytes assume a codificação ISO 8859-1 e a do Mathematica $CharacterEncodingdefinida como WindowsANSI(o padrão no Windows; outras configurações também podem funcionar, mas outras UTF-8definitivamente não).

±1=±2=1
±n_:=±(n-±(n-1))+±(n-±(n-2))

Define ± como um operador unário.

Tentei me livrar da duplicação, mas acabei com a mesma contagem de bytes:

±1=±2=1
±n_:=Tr[±(n-±(n-#))&/@{1,2}]
Martin Ender
fonte
Eu posso lhe dar uma recompensa de +200 se você fizer isso em Retina #
Leaky Nun
@LeakyNun okay? :)
Martin Ender
Dois dias depois.
Freira vazando
@LeakyNun Em breve, você não terá mais representantes se der recompensas com tanta facilidade.
Mbomb007 29/07
Vamos continuar esta discussão no chat .
LegionMammal978
4

Gelatina , 15 14 bytes

2Rạ⁸߀$⁺Sµ1>?2

Experimente online! ou verifique todos os casos de teste (leva alguns segundos).

Como funciona

2Rạ⁸߀$⁺Sµ1>?2  Main link. Argument: n (integer)

2R              Yield [1, 2].
      $         Combine the previous three links into a monadic chain.
   ⁸                Yield n.
  ạ                 Take the absolute difference of the return value and n.
    ߀              Recursively call the main link on each result.
       ⁺            Duplicate the chain.
                    The first copy maps [1, 2] to [a(n - 1), a(n - 2)].
                    The second copy maps [a(n - 1), a(n - 2)] to
                    [a(n - a(n - 1)), a(n - a(n - 2))].
        S           Take the sum.
         µ          Combine all links to the left into a chain.
            ?       If...
           > 2          n is greater than 2, call the chain.
          1         Else, return 1.
Dennis
fonte
Eu posso lhe dar uma recompensa de +400 se você fizer isso em Sesos.
Leaky Nun
@LeakyNun Parece haver uma resposta Sesos. Foi lançado um dia após o seu comentário.
Yytsi
4

Geléia , 14 12 11 bytes

ịḣ2S;
1Ç⁸¡2ị

Essa é uma abordagem iterativa.

Experimente online! ou verifique todos os casos de teste .

Como funciona

1Ç¡2ị   Main link. Argument: n

1       Set the return value to 1.
 Ç¡     Call the helper link n times, updating the return value after each call.
   2ị   Extract the second element of the resulting array.


ịḣ2S;   Helper link. Argument: A (array)

ị       At-index; retrieve the elements of A at the values of A.
 ḣ2     Head 2; extract the first two results.
    S   Take the sum of the result.
     ;  Prepend the sum to A.
Dennis
fonte
3

Python, 45 40 bytes

a=lambda n:n<3or a(n-a(n-1))+a(n-a(n-2))

Simples interpretação ingênua do desafio.

Guardado 5 bytes graças a @LeakyNun!

Cobre
fonte
3

Haskell, 39 37 bytes

h n|n<3=1|n>2=h(n-h(n-1))+h(n-h(n-2))

exatamente como descrito no desafio, usando proteções

KarlKastor
fonte
Desculpe, eu não vi sua solução antes de postar minha solução de haskell (idêntica). No entanto, a contagem de bytes 38 não é necessária, pois a nova linha deve ser levada em consideração?
Laikoni 29/07
E o guarda tem que ser n<3para h 2 ser 1.
Laikoni 29/07
. @Laikoni É de 37 de acordo com a característica Pythons len com uma multilinha ( "" ") corda, a menos que você conte nova linha como dois bytes Sim, eu notei a outra coisa é fixo agora.
KarlKastor
O bloco de notas TIL ++ conta a nova linha como dois caracteres.
Laikoni 29/07
@Laikoni se livrou da nova linha, que agora é indiscutivelmente de 37 bytes.
27416 Karl -astor
3

R, 50 bytes

a=function(n)ifelse(n<3,1,a(n-a(n-1))+a(n-a(n-2)))

Uso:

> a(1)
  1
> a(20)
  12
DSkoog
fonte
3

CJam, 19 18 bytes

XXri{_($2$$+}*]-3=

Experimente online!

Usa a abordagem iterativa.

Martin Ender
fonte
3

C #, 51 44 bytes

int a(int n)=>n<3?1:a(n-a(n-1))+a(n-a(n-2));

Gostaria de saber se isso pode ser encurtado, tornando-o anônimo graças pinkfloydx33!

downrep_nation
fonte
1
Função int a(int n)=>n<3?1:a(n-a(n-a))+a(n-a(n-2));
corporal
Parece que eu digitei enquanto escrevia isso no meu telefone. O mais interior -ano primeiro conjunto de parênteses deve ser-1
pinkfloydx33
Eu não percebi que quer, mal corrigi-lo rq
downrep_nation
3

JavaScript (ES6), 45 bytes 34 bytes

Uma solução recursiva no ES6. Qualquer dica de golfe muito apreciada.

a=n=>n>2?a(n-a(n-1))+a(n-a(n-2)):1

Obrigado a / u / ismillo por diminuir ainda mais.

BugHunterUK
fonte
2

05AB1E, 29 bytes

Uma solução iterativa.

XˆXˆÍL>v¯¤ys-è¯y¯yÍè-è+ˆ}¯¹<è

Experimente online

Emigna
fonte
2

APL, 20 bytes

{⍵≤2:1⋄+/∇¨⍵-∇¨⍵-⍳2}

Explicação:

{⍵≤2:1⋄+/∇¨⍵-∇¨⍵-⍳2}
 ⍵≤2:1               If argument is 2 or less, return 1
      ⋄              Otherwise:
               ⍵-⍳2  Subtract [1, 2] from the argument
             ∇¨      Recursive call on both
           ⍵-        Subtract both results from the argument     
         ∇¨          Recursive call on both again
       +/            Sum          
marinus
fonte
2

VBA Excel 87 bytes

Não recursivo, já que eu quero que isso funcione para n = 100000, diga:

Function A(N):ReDim B(N):For i=3 To N:B(i)=B(i-B(i-1)-1)+B(i-B(i-2)-1)+1:Next:A=B(N)+1

... e pressione return(byte # 87) no final da linha para obter a End Functiondeclaração "de graça". Observe que os valores B são deslocados por -1 para evitar a inicialização para n = 1 e 2.

Invoque na planilha normalmente, por exemplo, =A(100000)para obter48157

A versão recursiva, 61 bytes ,

Function Y(N):If N<3 Then Y=1 Else Y=Y(N-Y(N-1))+Y(N-Y(N-2))

começa a ficar excessivamente lento para n> 30 e não se pode dizer que funcione para n> 40.

Joffan
fonte
Não nos importamos com desempenho. Nós nos preocupamos com o comprimento do código. Você deve mover sua solução mais curta para o topo da sua resposta.
Mbomb007
1
@ mbomb007 Como não estou nem perto de ganhar o golfe, farei minhas próprias escolhas sobre o que constitui um programa de trabalho. Não é possível lidar com números inteiros de byte nem sequer é bom o suficiente para mim, quando existe uma solução que pode ser feita facilmente.
Joffan
2

Ruby, 36 bytes

Uma implementação direta. Todas as sugestões de golfe são bem-vindas.

a=->n{n<3?1:a[n-a[n-1]]+a[n-a[n-2]]}
Sherlock9
fonte
Afaik, você pode se livrar do a =. Se você publicá-lo aqui, será suficiente quando o seu código começar com ->. Conta como uma função anônima então.
Seims
Infelizmente, como a função se autodenomina a[n-1], a função precisa ser nomeada.
Sherlock9
2

Java 7, 68 61 51 bytes

17 salvos graças a Leaky Nun.

int a(int n){return n<3?1:a(n-a(n-1))+a(n-a(n-2));}
Justin
fonte
Bem-vindo ao PPCG!
AdmBorkBork 29/07
Bem-vindo ao PPCG! Você pode gostar de Dicas para jogar golfe em Java . Uma forma alternativa seria int a(int n){return n<3?1:a(n-a(n-2))+a(n---a(n));}:, mas infelizmente ela usa a mesma quantidade de bytes que a resposta que você já possui. Além disso, eu especificaria que sua resposta está no Java 7, pois a resposta do Java 8 seria mais curta: n->return n<3?1:a(n-a(n-1))+a(n-a(n-2))( 39 bytes ) .
Kevin Cruijssen
Obrigado pela recepção, e obrigado pela dica sobre Java8 - eu não sabia que lambdas eram permitidas assim - embora sejam permitidas assim em Python, então acho que nunca pensei nisso. O lambda precisa de um ponto e vírgula?
23416 Justin
@JustinTervay Não uso muito o Java 8, mas pelo que ouvi dizer que o ponto-e-vírgula não conta com expressões de linha única, de acordo com um comentário de @DavidConrad e @ CAD97 em uma das minhas próprias respostas Java .
Kevin Cruijssen
2

Oasis , 9 7 5 bytes (não concorrente)

Não concorrente , uma vez que o idioma pós o desafio. Obrigado a Kenny Lau por salvar 4 bytes. Código:

ece+V

Formulário expandido ( Vabreviação de 11):

a(n) = ece+
a(0) = 1
a(1) = 1

Código:

e        # Stack is empty, so a(n - 1) is used, and it calculates a(n - a(n - 1))
 c       # Calculate a(n - 2)
  e      # Calculate a(n - a(n - 2))
   +     # Add up

Experimente online! . Calcula n = 1000 em 0,1 segundos.

Adnan
fonte
1

PowerShell v2 +, 85 79 69 bytes

param($n)$b=1,1;2..$n|%{$b+=$b[$_-$b[$_-1]]+$b[$_-$b[$_-2]]};$b[$n-1]

Recebe a entrada $n, define $bcomo uma matriz de @(1, 1)e entra em um loop de 2 .. $n. A cada iteração, aderimos $bao cálculo mais recente da sequência com um simples +=e a definição da sequência. Em seguida, produzimos o número apropriado de $b(com a -1porque matrizes no PowerShell são indexadas em zero). Isso funciona se $né 1ou 2porque esses dois valores são preenchidos previamente nos índices mais baixos $bdesde o início, portanto, mesmo que o loop fique preso no lixo, ele será ignorado de qualquer maneira.


Solução recursiva 78 76 bytes

$a={param($k)if($k-lt3){1}else{(&$a($k-(&$a($k-1))))+(&$a($k-(&$a($k-2))))}}

Na primeira vez que usei o equivalente a um lambda como resposta, como geralmente uma solução iterativa é mais curta (como você pode ver em todas as parênteses aninhadas). Mas, nesse caso, os parênteses aninhados são quase duplicados na solução iterativa com as chamadas de matriz aninhada, portanto, a solução recursiva é mais curta. Não, a solução iterativa é realmente mais curta (veja acima).

Chame isso através do operador de execução, como &$a 20. Apenas uma ligação recursiva direta.

AdmBorkBork
fonte
1

JavaScript (ES6), 66 bytes

n=>[...Array(n+1)].reduce((p,_,i,a)=>a[i]=i<3||a[i-p]+a[i-a[i-2]])

Versão não recursiva para velocidade; a versão recursiva é provavelmente mais curta, mas deixarei para outra pessoa escrever. Eu sempre gosto quando uso reduce. Nota: 1 byte salvo ao retornar true(que é convertido 1quando usado em um contexto inteiro) para of a(1)e a(2).

Neil
fonte
1

Pitão, 16 bytes

L|<b3smy-bytdtBb

L                  def y(b):
 |<b3                b < 3 or …
      m      tBb       map for d in [b - 1, b]:
       y-bytd            y(b - y(d - 1))
     s                 sum

Define uma função y.

Experimente online (adicionado yMS20para imprimir os primeiros 20 valores)

Anders Kaseorg
fonte
1

Quarto, 76 bytes

Eu finalmente consegui!

: Q recursive dup dup 3 < if - 1+ else 2dup 2 - Q - Q -rot 1- Q - Q + then ;

Experimente online

Explicação:

: Q recursive                           \ Define a recursive function Q
    dup dup 3 <                         \ I moved a dup here to golf 2 bytes
    if                                  \ If n < 3, return 1
        - 1                             \ Golf: n-n is zero, add one. Same as 2drop 1+
    else
        2dup 2 - Q - Q                  \ Copy n until 4 on stack, find Q(n-Q(n-2))
        -rot                            \ Move the result below 2 copies of n
        1- Q - Q +                      \ Find Q(n-Q(n-2)), then add to previous ^
    then ;

Experimente on-line (um pouco sem golfe por cima)

Infelizmente, a recursão mútua é um pouco exagerada para usar no golfe.

mbomb007
fonte
1

Bordo, 43 41 bytes

a:=n->`if`(n>2,a(n-a(n-1))+a(n-a(n-2)),1)

Uso:

> a(1);
  1
> a(20);
  12

Esse problema é certamente um bom candidato para memorização. Usando o cache de opções , os tempos de execução são reduzidos significativamente:

aC := proc(n) 
      option cache; 
      ifelse( n > 2, aC( n - aC(n-1) ) + aC( n - aC(n-2) ), 1 ); 
end proc:

Isso pode ser visto usando:

CodeTools:-Usage( aC(50) );
DSkoog
fonte
0

J, 29 28 bytes

1:`(+&$:/@:-$:@-&1 2)@.(2&<)

Usa a definição recursiva.

Uso

Comandos extras são usados ​​para formatar várias entradas / saídas.

   f =: 1:`(+&$:/@:-$:@-&1 2)@.(2&<)
   (,:f"0) >: i. 20
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
1 1 2 3 3 4 5 5 6  6  6  8  8  8 10  9 10 11 11 12

Explicação

1:`(+&$:/@:-$:@-&1 2)@.(2&<)  Input: n
                        2&<   If n < 2
1:                              Return 1
                              Else
               -&1 2            Subtract [1, 2] from n to get [n-1, n-2]
            $:@                 Call recursively on n-1 and n-2
           -                    Subtract each of the results from n
        /@:                     Reduce using
      $:                          A recursive call on each
    +&                            Then summation
                                Return that value as the result
milhas
fonte
0

dc, 62 bytes

?si2sa1dd2:a:a[la1+dsadd1-;a-;alad2-;a-;a+r:ali;a0=A]dsAxli;af

Esta solução faz uso de matrizes e recursão.

?si          # Take input from stdin and store it in register `i'
2sa          # Initialise register `a' with 2, since we'll be putting in the first
             #   two values in the sequence
1dd2         # Stack contents, top-down: 2 1 1 1
:a           # Pop index, then pop value: Store 1 in a[2]
:a           # Ditto:                     Store 1 in a[1]
[            # Open macro definition
 la 1+ dsa   # Simple counter mechanism: Increment a and keep a copy on stack

# The STACK-TRACKER(tm): Top of stack will be at top of each column, under the
#   dashed line. Read commands from left to right, wrapping around to next line.
#   This will be iteration number n.
  dd   1-    ;a       -          ;a            la            d          
#-----------------------------------------------------------------------
# n    n-1   a[n-1]   n-a[n-1]   a[n-a[n-1]]   n             n          
# n    n     n        n          n             a[n-a[n-1]]   n          
# n    n     n                                 n             a[n-a[n-1]]
#                                                            n          
#                                                                       

  2-            ;a            -             ;a            +      r    :a
#-----------------------------------------------------------------------
# n-2           a[n-2]        n-a[n-2]      a[n-a[n-2]]   a[n]   n      
# n             n             a[n-a[n-1]]   a[n-a[n-1]]   n      a[n]   
# a[n-a[n-1]]   a[n-a[n-1]]   n             n                           
# n             n                                                       

 li;a        # Load index of target element, and fetch that element's current value
             #    Uninitialised values are zero
 0=A         # If a[i]==0, execute A to compute next term
]dsAx        # Close macro definition, store on `A' and execute
li;a         # When we've got enough terms, load target index and push value
f            # Dump stack (a[i]) to stdout
Joe
fonte
Concluindo, se alguém estiver criando um IDE dc, me avise!
31416 Joe
0

Erlang, 46 bytes

f(N)when N<3->1;f(N)->f(N-f(N-1))+f(N-f(N-2)).
cPu1
fonte
0

Lua, 59 bytes

function a(n)return n<3 and 1 or a(n-a(n-1))+a(n-a(n-2))end
brianush1
fonte