Sekwencja Q Hofstadtera

25

Definicja

  1. a (1) = 1
  2. a (2) = 1
  3. a (n) = a (na (n-1)) + a (na (n-2)) dla n> 2, gdzie n jest liczbą całkowitą

Zadanie

Biorąc pod uwagę dodatnią liczbę całkowitą n, wygeneruj a(n).

Przypadki testowe

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

Odniesienie

Leaky Nun
źródło
Związane .
Leaky Nun
1
Czy możemy zwrócić wartość True w językach, w których można jej użyć jako 1 ?
Dennis
1
@Dennis Jeśli w tym języku prawda jest równa 1, to tak.
Leaky Nun
4
Oprócz linku OEIS dobrze byłoby odwołać się do GEB, w którym sekwencja pojawiła się po raz pierwszy.
Martin Ender

Odpowiedzi:

9

Retina , 84 83 79 74 bajty

Liczba bajtów zakłada kodowanie ISO 8859-1.

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

Wypróbuj online! (Pierwszy wiersz włącza pakiet testowy oddzielony od linii).

Później będę musiał zagrać w golfa.

Martin Ender
źródło
9

Haskell, 35 33 bajtów

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

Definiuje funkcję a.

Anders Kaseorg
źródło
2
Niezła sztuczka z oprawą! Czy coś takiego nie (b.b)1+(b.b)2byłoby krótsze niż suma?
xnor
Dlaczego tak, dzięki @xnor.
Anders Kaseorg,
8

Julia, 29 bajtów

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

Wypróbuj online!

Jak to działa

Przedefiniowujemy jednoargumentowego operatora !do naszych celów.

Jeśli n wynosi 1 lub 2 , n<3zwraca wartość true i jest to nasza wartość zwracana.

Jeśli n jest większe niż 2 , n<3zwraca false, a || oddział zostaje wykonany. Jest to prosta implementacja definicji, w której ~-ndaje n - 1 i ~-~-ndaje n - 2 .

Dennis
źródło
7

Sesos, 54 bajty

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

Wypróbuj online

Zdemontowany

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

Lub w notacji Brainfuck:

+>+>>>>>>,-[[->+<]>-<<++[<<<<[->>>+<<<]>>>>[-<<<+<+>>>>]<<<[->>>+<<<]>>>>++[<<<<<[<
[->>+<<]>[-<+>]<-]>>[-<+<+>>]>[<<[->+<]>>[-<<+>>]>]>>>-]<<[-<<<+>>>]>-]>>]<<<<<<<.
Anders Kaseorg
źródło
6

C, 43 42 bajty

Zapisano 1 bajt dzięki @Dennis

Każda odpowiedź jest taka sama, muszę zrobić coś innego!

Wypróbuj online!

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

Objaśnienie: jest to w zasadzie, a(n-a(n-2))+a(n-a(n-1))ale z nieokreślonym zachowaniem swaggy (działa na moim telefonie (gcc) i ideone).

betseg
źródło
4
1. Powinieneś także wspomnieć o kompilatorze; twój „łup” jest niezdefiniowanym zachowaniem. 2. Dzięki GCC nie potrzebujesz 1między nimi ?a :.
Dennis
@Dennis Co ciekawe, to samo sformułowanie działa w mojej iteracyjnej odpowiedzi PowerShell ...$b+=$b[$_-$b[$_-2]]+$b[$_---$b[$_]]
AdmBorkBork
@TimmyD niektóre kompilatory mogą kompilować a (n) przed n-- i nie ma do tego standardowego (lub zdefiniowanego) zachowania. Zatem niezdefiniowane zachowanie.
betseg
@betseg Tak, zgadzam się. Po prostu wskazując, że niekoniecznie jest to unikalne dla C.
AdmBorkBork
@ TimmyD Oh, źle to zrozumiałem. Chciałem tylko zmienić funkcję, z której wszyscy korzystają, aby moja była inna i swaggy: D
betseg
5

Mathematica, 36 bajtów

Liczba bajtów zakłada 8859-1 kodowania ISO i Mathematica jest $CharacterEncodingustawiony na WindowsANSI(domyślne w systemie Windows, inne ustawienia mogą działać jak dobrze, ale niektóre, jak UTF-8na pewno nie).

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

Definiuje ±jako jednoargumentowy operator.

Próbowałem pozbyć się duplikacji, ale skończyłem z tą samą liczbą bajtów:

±1=±2=1
±n_:=Tr[±(n-±(n-#))&/@{1,2}]
Martin Ender
źródło
Mogę dać ci nagrodę +200, jeśli zrobisz to w Retina
Leaky Nun
@LeakyNun dobrze? :)
Martin Ender
Dwa dni później.
Leaky Nun
@LeakyNun Wkrótce nie będziesz miał żadnego przedstawiciela, jeśli tak łatwo rozdajesz nagrody.
mbomb007
Daj nam kontynuować tę dyskusję w czacie .
LegionMammal978
4

Galaretka , 15 14 bajtów

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

Wypróbuj online! lub sprawdź wszystkie przypadki testowe (zajmuje kilka sekund).

Jak to działa

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
źródło
Mogę dać ci nagrodę +400, jeśli zrobisz to w Sesos.
Leaky Nun
@LeakyNun Wydaje się, że istnieje odpowiedź Sesos. Pojawiło się dzień po twoim komentarzu.
Yytsi
4

Galaretka , 14 12 11 bajtów

ịḣ2S;
1Ç⁸¡2ị

To jest podejście iteracyjne.

Wypróbuj online! lub zweryfikuj wszystkie przypadki testowe .

Jak to działa

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
źródło
3

Python, 45 40 bajtów

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

Prosta naiwna interpretacja wyzwania.

Zaoszczędź 5 bajtów dzięki @LeakyNun!

Miedź
źródło
3

Haskell, 39 37 bajtów

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

dokładnie tak, jak opisano w wyzwaniu, używając strażników

KarlKastor
źródło
Przepraszamy, nie widziałem twojego rozwiązania przed opublikowaniem mojego (identycznego) rozwiązania haskell. Czy jednak liczba bajtów 38 nie jest uwzględniona, ponieważ należy wziąć pod uwagę nową linię?
Laikoni
I strażnik musi być n<3dla h 2 być 1.
Laikoni
@Laikoni Jest 37 według funkcji len Pythona z ciągiem wielowierszowym („” ”), chyba że liczysz nowy wiersz jako dwa bajty. Tak, zauważyłem inną rzecz, którą teraz naprawiłem.
KarlKastor
Notatnik TIL ++ liczy nowy wiersz jako dwa znaki.
Laikoni
@Laikoni pozbył się nowego wiersza, który ma teraz bezsprzecznie 37 bajtów.
KarlKastor
3

R, 50 bajtów

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

Stosowanie:

> a(1)
  1
> a(20)
  12
DSkoog
źródło
3

CJam, 19 18 bajtów

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

Wypróbuj online!

Wykorzystuje podejście iteracyjne.

Martin Ender
źródło
3

C #, 51 44 bajtów

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

Zastanawiam się, czy można to skrócić, czyniąc to anonimowym dzięki pinkfloydx33!

downrep_nation
źródło
1
c # 6 wyrażenie int a(int n)=>n<3?1:a(n-a(n-a))+a(n-a(n-2));
cielesna
Wygląda na to, że piszę na maszynie podczas pisania na telefonie. Wewnętrzne najbardziej -aw pierwszym zestawie parens powinno być-1
pinkfloydx33
Ja też tego nie zauważyłem, źle to naprawię rq
downrep_nation 30.07.16
3

JavaScript (ES6), 45 bajtów 34 bajtów

Rozwiązanie rekurencyjne w ES6. Wszelkie wskazówki dotyczące gry w golfa są bardzo mile widziane.

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

Dziękujemy / u / ismillo za dalsze skrócenie.

BugHunterUK
źródło
2

05AB1E, 29 bajtów

Iteracyjne rozwiązanie.

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

Wypróbuj online

Emigna
źródło
2

APL, 20 bajtów

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

Wyjaśnienie:

{⍵≤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
źródło
2

VBA Excel 87 bajtów

Brak rekurencji, ponieważ chcę, aby to działało dla n = 100000, powiedz:

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

... i naciśnij return(bajt # 87) na końcu wiersza, aby uzyskać End Functioninstrukcję „za darmo”. Zauważ, że wartości B są przesunięte o -1, aby uniknąć inicjalizacji dla n = 1 i 2.

Wywoływaj w arkuszu kalkulacyjnym jak zwykle, np. =A(100000)Aby uzyskać48157

Wersja rekurencyjna, 61 bajtów ,

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

zaczyna robić się zbyt wolno dla n> 30 i nie można powiedzieć, że w ogóle działa dla n> 40.

Joffan
źródło
Nie dbamy o wydajność. Dbamy o długość kodu. Powinieneś przenieść swoje krótsze rozwiązanie na górę odpowiedzi.
mbomb007
1
@ mbomb007 Ponieważ nie jestem bliski wygrania golfa, sam podejmę własne decyzje dotyczące tego, co stanowi działający program. Nie jestem w stanie obsłużyć nawet liczb całkowitych jednobajtowych, jeśli o mnie chodzi, nie jest wystarczająco dobry, jeśli istnieje rozwiązanie, które może to zrobić z łatwością.
Joffan
2

Rubinowy, 36 bajtów

Bezpośrednie wdrożenie. Wszelkie sugestie dotyczące gry w golfa są mile widziane.

a=->n{n<3?1:a[n-a[n-1]]+a[n-a[n-2]]}
Sherlock9
źródło
Afaik, możesz pozbyć się a =. Jeśli opublikujesz go tutaj, wystarczy, że kod zacznie się od ->. Liczy się wtedy jako funkcja anonimowa.
Wydaje się
@ Zdaje się Niestety, ponieważ funkcja sama się wywołuje a[n-1], należy ją nazwać.
Sherlock9,
2

Java 7, 68 61 51 bajtów

17 uratowanych dzięki Dziurawej Zakonnicy.

int a(int n){return n<3?1:a(n-a(n-1))+a(n-a(n-2));}
Justin
źródło
Witamy w PPCG!
AdmBorkBork
Witamy w PPCG! Możesz polubić Porady dotyczące gry w golfa w Javie . Alternatywną postacią byłoby: int a(int n){return n<3?1:a(n-a(n-2))+a(n---a(n));}ale niestety używa tej samej ilości bajtów, co odpowiedź, którą już masz. Ponadto wskazałbym, że twoja odpowiedź jest w Javie 7, ponieważ odpowiedź Java 8 byłaby krótsza: n->return n<3?1:a(n-a(n-1))+a(n-a(n-2))( 39 bajtów ) .
Kevin Cruijssen
Dzięki za powitanie i dziękuję za poradę na temat Java8 - nie zdawałem sobie sprawy, że lambdas są dozwolone w ten sposób - chociaż są one dozwolone w Pythonie, więc chyba nigdy o tym nie myślałem. Czy lambda potrzebuje średnika?
Justin
@JustinTervay Nie używam dużo Java 8, ale z tego, co słyszałem, średnik nie jest liczony jako wyrażenia jednowierszowe, zgodnie z komentarzem @DavidConrad i @ CAD97 w jednej z moich własnych odpowiedzi Java .
Kevin Cruijssen
2

Oaza , 9 7 5 bajtów (niekonkurujące)

Nie konkuruje , ponieważ język jest późniejszy niż wyzwanie. Dzięki Kenny Lau za uratowanie 4 bajtów. Kod:

ece+V

Rozszerzona forma ( Vjest skrótem od 11):

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

Kod:

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

Wypróbuj online! . Oblicza n = 1000 w 0,1 sekundy.

Adnan
źródło
1

PowerShell v2 +, 85 79 69 bajtów

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

Pobiera dane wejściowe $n, ustawia $bsię na tablicę @(1, 1), a następnie przechodzi do pętli 2 .. $n. Każdą iterację zajmujemy się $bnajnowszymi obliczeniami w sekwencji za pomocą prostej +=i definicji sekwencji. Następnie wypisujemy odpowiednią liczbę z $b( -1ponieważ tablice w PowerShell są indeksowane zerowo). Działa $nto, jeśli jest 1lub 2ponieważ obie te wartości są wstępnie wypełnione niższymi indeksami $bod początku, więc nawet jeśli pętla pęka na śmieci, i tak jest ignorowana.


Rozwiązanie rekurencyjne 78 76 bajtów

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

Po raz pierwszy użyłem odpowiednika lambda jako odpowiedzi, ponieważ zwykle iteracyjne rozwiązanie jest krótsze (jak widać ze wszystkich zagnieżdżonych części). Ale w tym przypadku zagnieżdżone pareny są prawie zduplikowane w iteracyjnym rozwiązaniu z zagnieżdżonymi wywołaniami tablic, więc rozwiązanie rekurencyjne jest krótsze. Nie, iteracyjne rozwiązanie jest rzeczywiście krótsze (patrz wyżej).

Wywołaj to przez operatora wykonania, na przykład &$a 20. Po prostu rekurencyjne połączenie.

AdmBorkBork
źródło
1

JavaScript (ES6), 66 bajtów

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

Wersja nierekurencyjna dla prędkości; wersja rekurencyjna jest prawdopodobnie krótsza, ale zostawię ją komuś innemu do napisania. Zawsze lubię to, kiedy mogę użyć reduce. Uwaga: 1 bajt zapisany przez zwrócenie true(który jest rzutowany na, 1gdy jest używany w kontekście liczb całkowitych) dla a(1)i a(2).

Neil
źródło
1

Pyth, 16 bajtów

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

Definiuje funkcję y.

Wypróbuj online (dodano, yMS20aby wydrukować pierwsze 20 wartości)

Anders Kaseorg
źródło
1

Dalej 76 bajtów

W końcu to działa!

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

Wypróbuj online

Wyjaśnienie:

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

Wypróbuj online (nieco od golfa od góry)

Niestety, wzajemna rekurencja jest nieco zbyt trudna do użycia w golfa.

mbomb007
źródło
1

Klon, 43 41 bajtów

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

Stosowanie:

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

Ten problem jest z pewnością dobrym kandydatem do zapamiętywania. Przy użyciu opcji pamięci podręcznej czasy uruchamiania są znacznie skrócone:

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

Można to zobaczyć za pomocą:

CodeTools:-Usage( aC(50) );
DSkoog
źródło
0

J, 29 28 bajtów

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

Używa definicji rekurencyjnej.

Stosowanie

Dodatkowe polecenia są używane do formatowania wielu wejść / wyjść.

   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

Wyjaśnienie

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
mile
źródło
0

dc, 62 bajty

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

To rozwiązanie wykorzystuje tablice i rekurencję.

?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
źródło
Podsumowując, jeśli ktoś buduje IDE dc, daj mi znać!
Joe
0

Erlang, 46 bajtów

f(N)when N<3->1;f(N)->f(N-f(N-1))+f(N-f(N-2)).
cPu1
źródło
0

Lua, 59 bajtów

function a(n)return n<3 and 1 or a(n-a(n-1))+a(n-a(n-2))end
brianush1
źródło