Sequenza Q di Hofstadter


25

Definizione

  1. a (1) = 1
  2. a (2) = 1
  3. a (n) = a (na (n-1)) + a (na (n-2)) per n> 2 dove n è un numero intero

Compito

Dato intero positivo n, genera a(n).

Casi test

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

Riferimento



1
Possiamo restituire True nelle lingue in cui può essere utilizzato come 1 ?
Dennis,

1
@Dennis Se in quella lingua vero equivale a 1, allora sì.
Leaky Nun,

4
Oltre al collegamento OEIS, potrebbe essere utile fare riferimento a GEB nel punto in cui è apparsa la sequenza.
Martin Ender,

Risposte:


9

Retina , 84 83 79 74 byte

Il conteggio dei byte presuppone la codifica ISO 8859-1.

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

Provalo online! (La prima riga abilita una suite di test separata da avanzamento riga.)

Dovrò giocare a golf più tardi.


9

Haskell, 35 33 byte

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

Definisce una funzione a.


2
Bel trucco con il legame! Qualcosa del genere non (b.b)1+(b.b)2sarebbe più breve della somma?
xnor

Perché sì, grazie @xnor.
Anders Kaseorg,

8

Julia, 29 byte

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

Provalo online!

Come funziona

Ridefiniamo l'operatore unario !per i nostri scopi.

Se n è 1 o 2 , n<3restituisce vero e questo è il nostro valore di ritorno.

Se n maggiore di 2 , n<3restituisce false e il valore || il ramo viene eseguito. Questa è un'implementazione diretta della definizione, dove ~-nproduce n - 1 e ~-~-nproduce n - 2 .


7

Sesos, 54 byte

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.~.....

Provalo online

smontato

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

O nella notazione Brainfuck:

+>+>>>>>>,-[[->+<]>-<<++[<<<<[->>>+<<<]>>>>[-<<<+<+>>>>]<<<[->>>+<<<]>>>>++[<<<<<[<
[->>+<<]>[-<+>]<-]>>[-<+<+>>]>[<<[->+<]>>[-<<+>>]>]>>>-]<<[-<<<+>>>]>-]>>]<<<<<<<.

6

C, 43 42 byte

Salvato 1 byte grazie a @Dennis

Ogni risposta è la stessa, devo fare qualcosa di diverso!

Provalo online!

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

Spiegazione: è fondamentalmente a(n-a(n-2))+a(n-a(n-1))ma con un comportamento indefinito spavaldo (funziona sul mio telefono (gcc) e ideone).


4
1. Dovresti anche menzionare il compilatore; il tuo "malloppo" è un comportamento indefinito. 2. Con GCC, non hai bisogno 1tra ?e :.
Dennis,

@Dennis È interessante notare che la stessa formulazione funziona nella mia risposta iterativa di PowerShell ...$b+=$b[$_-$b[$_-2]]+$b[$_---$b[$_]]
AdmBorkBork,

@TimmyD alcuni compilatori possono compilare la a (n) prima della n--, e non esiste un comportamento standard (o definito) per quello. Pertanto, comportamento indefinito.
Betseg,

@betseg Sì, sono d'accordo.
Sto

@TimmyD Oh l'ho capito male. Volevo solo cambiare la funzione che tutti usano, quindi la mia sarebbe diversa e vaga: D
Betseg,

5

Mathematica, 36 byte

Il conteggio dei byte presuppone la codifica ISO 8859-1 e Mathematica è $CharacterEncodingimpostato su WindowsANSI(impostazione predefinita su Windows; anche altre impostazioni potrebbero funzionare, ma alcune come UTF-8sicuramente non lo fanno).

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

Definisce ±un operatore unario.

Ho provato a sbarazzarmi della duplicazione, ma ho finito con lo stesso numero di byte:

±1=±2=1
±n_:=Tr[±(n-±(n-#))&/@{1,2}]

Potrei darti una taglia +200 se lo fai a Retina
Leaky Nun,

@LeakyNun va bene? :)
Martin Ender,

Due giorni dopo.
Leaky Nun,

@LeakyNun Presto non avrai più un rappresentante se dai taglie così facilmente.
mbomb007,


4

Gelatina , 15 14 byte

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

Provalo online! oppure verifica tutti i casi di test (richiede alcuni secondi).

Come funziona

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.

Potrei darti una taglia +400 se lo fai a Sesos.
Leaky Nun,

@LeakyNun Sembra che ci sia una risposta Sesos. È uscito un giorno dopo il tuo commento.
Yytsi,

4

Gelatina , 14 12 11 byte

ịḣ2S;
1Ç⁸¡2ị

Questo è un approccio iterativo.

Provalo online! o verifica tutti i casi di test .

Come funziona

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.

3

Python, 45 40 byte

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

Semplice interpretazione ingenua della sfida.

5 byte salvati grazie a @LeakyNun!


3

Haskell, 39 37 byte

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

esattamente come descritto nella sfida, usando le protezioni


Spiacenti, non ho visto la tua soluzione prima di pubblicare la mia (identica) soluzione haskell. Tuttavia, il conteggio dei byte 38 non deve essere considerato come la nuova riga deve essere presa in considerazione?
Laikoni,

E la guardia deve essere n<3per h 2 essere 1.
Laikoni,

@Laikoni Sono 37 secondo la funzione len di Pythons con una stringa multilinea ("" "), a meno che non si consideri newline come due byte. Sì, ho notato l'altra cosa che è stata risolta ora.
KarlKastor,

TIL notepad ++ conta newline come due caratteri.
Laikoni,

@Laikoni si è sbarazzato della newline che ora è indiscutibilmente 37 byte.
KarlKastor,

3

R, 50 byte

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

Uso:

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


3

C #, 51 44 byte

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

mi chiedo se questo può essere abbreviato rendendolo anonimo grazie pinkfloydx33!


1
Espressione c # 6 funzione corporeaint a(int n)=>n<3?1:a(n-a(n-a))+a(n-a(n-2));
pinkfloydx33

Sembra che abbia digitato durante la digitazione sul mio telefono. Il più interno -anella prima serie di parentesi dovrebbe essere-1
pinkfloydx33

Neanche io me ne sono accorto, mal sistemato rq
downrep_nation

3

JavaScript (ES6), 45 byte 34 byte

Una soluzione ricorsiva in ES6. Qualche consiglio sul golf molto apprezzato.

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

Grazie a / u / ismillo per accorciare ulteriormente.




2

APL, 20 byte

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

Spiegazione:

{⍵≤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          

2

VBA Excel 87 byte

Non ricorsivo, poiché voglio che funzioni per n = 100000, dì:

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 premere return(byte # 87) alla fine della riga per ottenere l' End Functionistruzione "free". Si noti che i valori B sono sfalsati di -1 per evitare l'inizializzazione per n = 1 e 2.

Invocare nel foglio di calcolo normalmente, ad esempio =A(100000)per ottenere48157

La versione ricorsiva, 61 byte ,

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

inizia a diventare irragionevolmente lento per n> 30 e non si può dire che funzioni affatto per n> 40.


Non ci importa delle prestazioni. Ci preoccupiamo della lunghezza del codice. Dovresti spostare la soluzione più breve all'inizio della risposta.
mbomb007

1
@ mbomb007 Dato che non sono vicino al campo da golf, farò le mie scelte su ciò che costituisce un programma di lavoro. Non essere in grado di gestire anche numeri interi a byte singolo non è abbastanza buono per quanto mi riguarda, quando esiste una soluzione che può farlo così facilmente.
Joffan,

2

Rubino, 36 byte

Un'implementazione diretta. Tutti i suggerimenti per il golf sono i benvenuti.

a=->n{n<3?1:a[n-a[n-1]]+a[n-a[n-2]]}

Dopo, puoi sbarazzarti di a =. Se lo pubblichi qui, è sufficiente che il codice inizi con ->. Quindi conta come una funzione anonima.
Sembra il

@Seims Sfortunatamente, poiché la funzione si chiama con a[n-1]e così, la funzione deve essere nominata.
Sherlock9,

2

Java 7, 68 61 51 byte

17 salvati grazie a Leaky Nun.

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

Benvenuti in PPCG!
AdmBorkBork,

Benvenuti in PPCG! Potrebbero interessarti Suggerimenti per giocare a golf in Java . Un modulo alternativo sarebbe int a(int n){return n<3?1:a(n-a(n-2))+a(n---a(n));}:, ma sfortunatamente utilizza la stessa quantità di byte della risposta che già hai. Inoltre, vorrei specificare che la tua risposta è in Java 7, poiché la risposta di Java 8 sarebbe più breve: n->return n<3?1:a(n-a(n-1))+a(n-a(n-2))( 39 byte ) .
Kevin Cruijssen,

Grazie per i ragazzi di benvenuto, e grazie per il suggerimento su Java8 - non mi ero reso conto che agli lambda fosse permesso così - anche se in Python sono ammessi così, quindi credo di non averci mai pensato. La lambda ha bisogno di un punto e virgola?
Giustino

@JustinTervay Non uso molto Java 8, ma da quello che ho sentito il punto e virgola non viene conteggiato su espressioni a riga singola, secondo un commento di @DavidConrad e @ CAD97 in una delle mie risposte Java .
Kevin Cruijssen,

2

Oasis , 9 7 5 byte (non concorrenti)

Non competitiva , poiché la lingua postdatizza la sfida. Grazie a Kenny Lau per aver salvato 4 byte. Codice:

ece+V

Modulo espanso ( Vè l'abbreviazione di 11):

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

Codice:

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

Provalo online! . Calcola n = 1000 in 0,1 secondi.


1

PowerShell v2 +, 85 79 69 byte

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

Accetta input $n, imposta $bun array di @(1, 1), quindi entra in un loop da 2 .. $n. Ogni iterazione che affronteremo $bsull'ultimo calcolo della sequenza con una semplice +=e la definizione della sequenza. Quindi viene emesso il numero appropriato da $b(con un -1array perché in PowerShell sono indicizzati zero). Questo funziona se lo $nè 1o 2perché entrambi questi valori sono precompilati negli indici inferiori $bdall'inizio, quindi anche se il loop si adatta alla posta indesiderata, viene comunque ignorato.


Soluzione ricorsiva 78 76 byte

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

La prima volta che ho usato l'equivalente di un lambda come risposta, poiché di solito una soluzione iterativa è più breve (come puoi vedere da tutte le parentesi nidificate). Ma, in questo caso, le parentesi nidificate sono quasi duplicate nella soluzione iterativa con le chiamate di array nidificate, quindi la soluzione ricorsiva è più breve.No, la soluzione iterativa è davvero più breve (vedi sopra).

Chiamalo tramite l'operatore di esecuzione, come &$a 20. Solo una semplice chiamata ricorsiva.


1

JavaScript (ES6), 66 byte

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

Versione non ricorsiva per la velocità; la versione ricorsiva è probabilmente più breve ma la lascerò per qualcun altro a scrivere. Mi piace sempre quando posso usare reduce. Nota: 1 byte salvato restituendo true(che viene lanciato 1quando utilizzato in un contesto intero) per of a(1)e a(2).


1

Pyth, 16 byte

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

Definisce una funzione y.

Provalo online (aggiunto yMS20per stampare i primi 20 valori)


1

Avanti, 76 byte

Finalmente ho funzionato!

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

Provalo online

Spiegazione:

: 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 ;

Provalo online (leggermente non golfato dall'alto)

Sfortunatamente, la ricorsione reciproca è un po ' troppo prolissa per il golf.


1

Acero, 43 41 byte

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

Uso:

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

Questo problema è sicuramente un buon candidato per la memorizzazione. Utilizzando la cache delle opzioni , i tempi di esecuzione si riducono significativamente:

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

Questo può essere visto usando:

CodeTools:-Usage( aC(50) );

0

J, 29 28 byte

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

Usa la definizione ricorsiva.

uso

I comandi extra vengono utilizzati per la formattazione di più input / output.

   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

Spiegazione

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

0

dc, 62 byte

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

Questa soluzione si avvale di array e ricorsione.

?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

In conclusione, se qualcuno sta costruendo un IDE per dc, fammi sapere!
Joe,

0

Erlang, 46 byte

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

0

Lua, 59 byte

function a(n)return n<3 and 1 or a(n-a(n-1))+a(n-a(n-2))end
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.