Q-послідовність Hofstadter


25

Визначення

  1. a (1) = 1
  2. a (2) = 1
  3. a (n) = a (na (n-1)) + a (na (n-2)) для n> 2, де n - ціле число

Завдання

Дано додатне ціле число n, генеруйтеa(n) .

Тестові шафи

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

Довідково

  • Обов’язковий OEIS A005185


1
Чи можемо ми повернути True в мовах, де його можна використовувати як 1 ?
Денніс

1
@Dennis Якщо в цій мові правда еквівалентна 1, то так.
Leaky Nun

4
Крім посилання на OEIS, можливо, було б добре посилатися на GEB, де послідовність з'явилася вперше.
Мартін Ендер

Відповіді:


9

Сітківка , 84 83 79 74 байт

Кількість байтів передбачає кодування ISO 8859-1.

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

Спробуйте в Інтернеті!(Перший рядок включає тестовий набір, відокремлений виведенням ліній.)

Пізніше мені доведеться пограти в гольф.



8

Джулія, 29 байт

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

Спробуйте в Інтернеті!

Як це працює

Ми переосмислюємо одинарного оператора !для наших цілей.

Якщо n дорівнює 1 або 2 , n<3повертає true і це наше повернене значення.

Якщо n більше 2 , n<3повертається помилка та || відділення виконується. Це пряма реалізація визначення, де ~-nврожайність n - 1, а ~-~-nурожайність n - 2 .


7

Сесо, 54 байти

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

Спробуйте в Інтернеті

Розібраний

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

Або в позначенні Brainfuck:

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

6

C, 43 42 байти

Збережено 1 байт завдяки @Dennis

Кожна відповідь однакова, я повинен робити щось інше!

Спробуйте в Інтернеті!

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

Пояснення: це в основному, a(n-a(n-2))+a(n-a(n-1))але з хитрим невизначеним поведінкою (працює на моєму телефоні (gcc) та ideone).


4
1. Ви також повинні згадати компілятор; ваш "сваг" - це невизначена поведінка. 2. За допомогою GCC вам не потрібно 1між ?і :.
Денніс

@Dennis Цікаво, що ця сама формулювання працює в моїй ітеративній відповіді PowerShell ...$b+=$b[$_-$b[$_-2]]+$b[$_---$b[$_]]
AdmBorkBork

@TimmyD деякі компілятори можуть зібрати a (n) перед n--, і для цього немає стандартної (або визначеної) поведінки. Таким чином, невизначена поведінка.
betseg

@betseg Так, я згоден. Тільки зазначивши, що це не обов'язково унікально для C.
AdmBorkBork

@TimmyD О, я це неправильно зрозумів. Я просто хотів змінити функцію, якою користуються всі, тож мій був би іншим і хитрим: D
betseg

5

Математика, 36 байт

Кількість байтів передбачає кодування ISO 8859-1, а Mathematica $CharacterEncodingвстановлено на WindowsANSI(за замовчуванням у Windows; інші налаштування можуть працювати також, але такі, як, UTF-8безумовно, не роблять).

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

Визначається ±як одинаковий оператор.

Я намагався позбутися від дублювання, але закінчився тим самим числом байтів:

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

Я можу дати вам 200 доларів, якщо ви це зробите в Retina
Leaky Nun

@LeakyNun добре? :)
Мартін Ендер

Через два дні
Leaky Nun

@LeakyNun Незабаром у вас не залишиться жодного представника, якщо ви так легко роздаєте щедроти.
mbomb007


4

Желе , 15 14 байт

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

Спробуйте в Інтернеті! або перевірити всі тестові випадки (займає кілька секунд).

Як це працює

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.

Я можу дати вам +400 щедрості, якщо ви це зробите в Sesos.
Лина монашка

@LeakyNun Здається, відповідь Сесоса. Він з’явився через день після вашого коментаря.
Yytsi

4

Желе , 14 12 11 байт

ịḣ2S;
1Ç⁸¡2ị

Це ітеративний підхід.

Спробуйте в Інтернеті! або перевірити всі тестові випадки .

Як це працює

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

Пітон, 45 40 байт

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

Просте наївне тлумачення виклику.

Збережено 5 байт завдяки @LeakyNun!


3

Haskell, 39 37 байт

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

точно так, як описано в виклику, з використанням охоронців


Вибачте, я не бачив вашого рішення перед тим, як опублікувати моє (ідентичне) рішення haskell. Однак чи не число байтів 38, оскільки новий рядок потрібно враховувати?
Laikoni

І охоронець повинен бути n<3для того, h 2 щоб бути 1.
Laikoni

. @Laikoni Це 37 згідно Пітони лена функція з вмістити ( «» ") рядок, якщо не брати до уваги нового рядка як два байти Так, я помітив іншу річ це тепер виправлена.
KarlKastor

Блокнот TIL ++ вважає новий рядок двома символами.
Лайконі

@Laikoni позбувся нового рядка, зараз це безперечно 37 байт.
КарлКастор

3

R, 50 байт

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

Використання:

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


3

C #, 51 44 байт

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

мені цікаво, чи можна це скоротити, зробивши це анонімним завдяки pinkfloydx33!


1
c # 6 функція виразного тілаint a(int n)=>n<3?1:a(n-a(n-a))+a(n-a(n-2));
pinkfloydx33

Здається, я друкую під час набору тексту на своєму телефоні. Внутрішня частина -aв першому наборі парен повинна бути-1
pinkfloydx33

Я також цього не помітив, погано виправляю rq
downrep_nation

3

JavaScript (ES6), 45 байт 34 байт

Рекурсивне рішення в ES6. Будь-які поради щодо гольфу дуже вдячні.

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

Дякую / u / ismillo за скорочення ще більше.




2

APL, 20 байт

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

Пояснення:

{⍵≤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 байт

Нерекурсивний, оскільки я хочу, щоб це працювало за n = 100000, скажіть:

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

... і натисніть return(байт № 87) в кінці рядка, щоб отримати End Functionвиписку для "безкоштовно". Зауважте, що значення B зміщені на -1, щоб уникнути ініціалізації для n = 1 і 2.

Надішліть електронну таблицю як звичайну, наприклад, =A(100000)щоб отримати48157

Рекурсивна версія, 61 байт ,

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

починає надмірно повільно ставити n> 30, і не можна сказати, що він працює взагалі за n> 40.


Нас не хвилює ефективність. Ми дбаємо про довжину коду. Ви повинні перемістити своє коротше рішення до верхньої частини вашої відповіді.
mbomb007

1
@ mbomb007 Оскільки я ніде не перемагаю в гольфі, я буду робити власний вибір щодо того, що є робочою програмою. Не в змозі обробити навіть однобайтові цілі числа, наскільки я переживаю, недостатньо добре, коли є рішення, яке може зробити це легко.
Йофан

2

Рубін, 36 байт

Пряма реалізація. Будь-які пропозиції щодо гольфу вітаються.

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

Афаїк, ви можете позбутися від a =. Якщо ви розмістите його тут, досить, коли ваш код починається з ->. Тоді це вважається анонімною функцією.
Сейми

@Seims На жаль, як функція називає себе a[n-1]і так, функцію потрібно назвати.
Шерлок9,

2

Java 7, 68 61 51 байт

17 врятованих завдяки Leaky Nun.

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

Ласкаво просимо до PPCG!
AdmBorkBork

Ласкаво просимо до PPCG! Можливо, вам сподобаються поради щодо гольфу на Java . Альтернативна форма буде такою:, int a(int n){return n<3?1:a(n-a(n-2))+a(n---a(n));}але, на жаль, вона використовує таку ж кількість байтів, що і відповідь, яку ви вже маєте. Також я зазначив би, що ваша відповідь є в Java 7, оскільки відповідь на Java 8 буде коротшою: n->return n<3?1:a(n-a(n-1))+a(n-a(n-2))( 39 байт ) .
Kevin Cruijssen

Дякую за привітання, хлопці, і спасибі за підказку щодо Java8 - я не розумів, що лямбди дозволено так - хоча вони в Python дозволені так, тому я думаю, я просто ніколи про це не думав. Чи потрібна лямбда напівколонка?
Джастін

@JustinTervay Я не використовую Java 8 дуже багато, але з того, що я чув, крапка з двократкою не зараховується на однорядкові вирази, згідно з коментарями @DavidConrad та @ CAD97 в одній із моїх власних відповідей Java .
Кевін Круїссен

2

Оазис , 9 7 5 байт (неконкурентоспроможний)

Неконкурентовані , оскільки мова висуває виклик. Завдяки Кені Лау за збереження 4 байтів. Код:

ece+V

Розширена форма ( Vскорочена 11):

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

Код:

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

Спробуйте в Інтернеті! . Обчислює n = 1000 за 0,1 секунди.


1

PowerShell v2 +, 85 79 69 байт

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

Бере введення $n, встановлює $bмасив @(1, 1), а потім входить в цикл з 2 .. $n. Кожну ітерацію ми торкаємося $bостаннього обчислення в послідовності з простим +=та визначенням послідовності. Потім виводимо відповідне число з $b(з тим, -1що масиви в PowerShell нульово індексуються). Це працює, якщо $nє 1або 2тому, що обидва ці значення попередньо заповнюються нижчими індексами $bз самого початку, так що навіть якщо цикл затягується на сміття, він все одно ігнорується.


Рекурсивний розчин 78 76 байт

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

Перший раз я використав еквівалент лямбда як відповідь, оскільки зазвичай ітераційне рішення коротше (як видно з усіх вкладених паронів). Але в цьому випадку вкладені пароні майже дублюються в ітеративному рішенні з вкладеними викликами масиву, тому рекурсивне рішення коротше. Ні, ітеративне рішення дійсно коротше (див. Вище).

Зателефонуйте через оператор виконання, наприклад &$a 20. Просто прямий рекурсивний дзвінок.


1

JavaScript (ES6), 66 байт

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

Нерекурсивна версія для швидкості; рекурсивна версія, ймовірно, коротша, але я залишу її для написання кимось іншим. Мені завжди подобається, коли я можу використовувати reduce. Примітка: 1 байт, збережений при поверненні true(який передається 1при використанні в цілому контексті) для a(1)та a(2).



1

По-четверте, 76 байт

Я, нарешті, спрацював!

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

Спробуйте в Інтернеті

Пояснення:

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

Спробуйте в Інтернеті (злегка відірвавшись від гольфу)

На жаль, взаємна рекурсія є занадто багатослівною, щоб використовувати для гольфу.


1

Клен, 43 41 байт

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

Використання:

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

Ця проблема, безумовно, є хорошим кандидатом на запам'ятовування. Використовуючи кеш опцій , час виконання значно скорочується:

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

Це можна побачити, використовуючи:

CodeTools:-Usage( aC(50) );

0

J, 29 28 байт

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

Використовується рекурсивне визначення.

Використання

Додаткові команди використовуються для форматування декількох входів / виходів.

   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

Пояснення

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

постійного струму, 62 байти

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

Це рішення використовує масиви та рекурсії.

?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

На закінчення, якщо хтось будує IDE для dc, дайте мені знати!
Джо

0

Ерланг, 46 байт

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.