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



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.


9

Haskell, 35 33 bajtów

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

Definiuje funkcję a.


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 .


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:

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

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


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}]

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


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.

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.

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!


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


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


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!


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.




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          

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.


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]]}

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));}

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.


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.


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


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)


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.


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

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

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

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

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.