Послідовність Сильвестра


32

Послідовність Сильвестра, OEIS A000058 , є цілою послідовністю, визначеною наступним чином:

Кожен член - це продукт усіх попередніх членів плюс один. Перший член послідовності - 2.

Завдання

Створіть найменшу можливу програму, яка займає n і обчислює n-й член послідовності Сильвестра. Застосовуються стандартні вхід, вихід та лазівки. Оскільки результат зростає дуже швидко, не очікується, що ви приймете будь-який термін, результат якого спричинить переповнення обраної вами мови.

Випробування

Ви можете використовувати нульове або одне індексування. (Тут я використовую нульову індексацію)

>>0
2
>>1
3
>>2
7
>>3
43
>>4
1807

Якими входами очікується обробка? Виробництво зростає досить швидко.
Геобіт

1
@Geobits, як очікується, ви будете обробляти стільки, скільки може ваша мова
Wheat Wizard

Чи є масив, який при індексації з nповертає nthномер прийнятої послідовності?
user6245072

@ user6245072 Ні, ви не повинні індексувати власні масиви
Wheat Wizard

Відповіді:


26

Брейн-Флак , 76 68 58 52 46 байт

<>(()())<>{({}[()])<>({({}[()])({})}{}())<>}<>

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

Замість цього використовується це відношення:

formula

яка є похідною від цього відношення, модифікованого з того, що передбачено в послідовності:

a(n+1) = a(n) * (a(n) - 1) + 1.

Пояснення

Щоб отримати документацію про те, що робить кожна команда, відвідайте сторінку GitHub .

У Brain-Flak є два стеки, які я назву відповідно як стек 1 та стек 2.

Вхід зберігається в стеку 1.

<>(()())<>             Store 2 in Stack 2.

{                      while(Stack_1 != 0){
  ({}[()])                 Stack_1 <- Stack_1 - 1;
  <>                       Switch stack.
  ({({}[()])({})}{}())     Generate the next number in Stack 2.
  <>                       Switch back to Stack 1.
}

<>                     Switch to Stack 2, implicitly print.

Для алгоритму генерації:

({({}[()])({})}{}())      Top <- (Top + Top + (Top-1) + (Top-1) + ... + 0) + 1

(                  )      Push the sum of the numbers evaluated in the process:

 {            }               while(Top != 0){
  ({}[()])                        Pop Top, push Top-1    (added to sum)
          ({})                    Pop again, push again  (added to sum)
                              }

               {}             Top of stack is now zero, pop it.
                 ()           Evaluates to 1 (added to sum).

Альтернативна 46-байтна версія

Для цього використовується лише один стек.

({}<(()())>){({}<({({}[()])({})}{}())>[()])}{}

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


1
Ще 10 байтів, щоб показати, що java develepors має перейти до розпаду мозку
Rohan Jhunjhunwala

1
@RohanJhunjhunwala Боюся, що це неможливо ...
Leaky Nun

@LeakyNun це ще цікаво подумати. Мозок Флак має деяку силу і надихає короткий час
Rohan Jhunjhunwala

5
Версія з одним стеком також є чистою. Що, як правило, є важливим моментом для модульної кодової функції в мозку.
Пшеничний майстер

Ого. Це надзвичайно вражаюча відповідь.
DJMcMayhem

12

Желе , 5 байт

Ḷ߀P‘

Тут використовується індексація на основі 0 та визначення специфікації виклику.

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

Як це працює

Ḷ߀P‘  Main link. Argument: n

Ḷ      Unlength; yield [0, ..., n - 1].
 ߀    Recursively apply the main link to each integer in that range.
   P   Take the product. This yields 1 for an empty range.
    ‘  Increment.

Ах, я забув, що порожній продукт - 1.
Лина монашка

12

Шестикутник , 27 байт

1{?)=}&~".>")!@(</=+={"/>}*

Розгорнуто:

    1 { ? )
   = } & ~ "
  . > " ) ! @
 ( < / = + = {
  " / > } * .
   . . . . .
    . . . .

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

Пояснення

Розглянемо послідовність b(a) = a(n) - 1і зробимо невелику перестановку:

b(a) = a(n) - 1
     = a(n-1)*(a(n-1)-1) + 1 - 1
     = (b(n-1) + 1)*(b(n-1) + 1 - 1)
     = (b(n-1) + 1)*b(n-1)
     = b(n-1)^2 + b(n-1)

Ця послідовність дуже схожа, але ми можемо відкласти приріст до самого кінця, що відбувається, щоб зберегти байт у цій програмі.

Отож ось анотований вихідний код:

enter image description here
Створено разом із шестигранним кольором Timwi .

Ось діаграма пам'яті (червоний трикутник показує початкове положення та орієнтацію вказівника пам'яті):

enter image description here
Створено за допомогою Езотерициду Тімві .

Код починається з сірого шляху, який загортає лівий кут, тому початковий лінійний біт такий:

1{?)(
1      Set edge b(1) to 1.
 {     Move MP to edge N.
  ?    Read input into edge N.
   )(  Increment, decrement (no-op).

Тоді код потрапляє на те, <що є гілкою, і вказує початок (і кінець) основного циклу. Поки N край має позитивне значення, зелений шлях буде виконаний. Цей шлях обертається навколо сітки кілька разів, але насправді цілком лінійний:

""~&}=.*}=+={....(

Не .існує, тому фактичний код:

""~&}=*}=+={(
""             Move the MP to edge "copy".
  ~            Negate. This is to ensure that the value is negative so that &...
   &           ...copies the left-hand neighbour, i.e. b(i).
    }=         Move the MP to edge b(i)^2 and turn it around.
      *        Multiply the two copies of b(i) to compute b(i)^2.
       }=      Move the MP back to edge b(i) and turn it around.
         +     Add the values in edges "copy" and b(i)^2 to compute
               b(i) + b(i)^2 = b(i+1).
          ={   Turn the memory pointer around and move to edge N.
            (  Decrement.

Як тільки це зменшення зменшиться Nдо 0, червоний шлях виконується:

")!@
"     Move MP back to edge b(i) (which now holds b(N)).
 )    Increment to get a(N).
  !   Print as integer.
   @  Terminate the program.

Чи можете ви запустити свого брутафорса на цьому?
CalculatorFeline

@CalculatorFeline Жорстокий форсер може робити не більше 7-байтних програм (і навіть це лише з купою припущень) за розумну кількість часу. Я не вважаю, що це можливо віддалено в 7 байтах.
Мартін Ендер

Так? Що не так у спробі?
CalculatorFeline

@CalculatorFeline Лінь. Грубий форсер завжди вимагає трохи ручного налаштування, що я не можу заважати зробити практично 0 шансів, що він щось знайде. Деяка версія сценарію розміщена на GitHub, хоча будь-хто інший вільний, щоб дати їй відгук.
Мартін Ендер

І як це зробити?
CalculatorFeline

9

J, 18 14 12 байт

Ця версія завдяки випадковим. Спробую написати докладне пояснення пізніше.

0&(]*:-<:)2:

J, 14 байт

Ця версія завдяки милям. Використовували дієприслівник ^:замість порядку денного, як показано нижче. Більше пояснень.

2(]*:-<:)^:[~]

J, 18 байт

2:`(1+*/@$:@i.)@.*

0-індексований.

Приклади

   e =: 2:`(1+*/@$:@i.)@.*
   e 1
3
   e 2
7
   e 3
43
   e 4
1807
   x: e i. 10
2 3 7 43 1807 3263443 10650056950807 113423713055421862298779648 12864938683278674737956996400574416174101565840293888 1655066473245199944217466828172807675196959605278049661438916426914992848    91480678309535880456026315554816
   |: ,: x: e i. 10
                                                                                                        2
                                                                                                        3
                                                                                                        7
                                                                                                       43
                                                                                                     1807
                                                                                                  3263443
                                                                                           10650056950807
                                                                              113423713055421862298779648
                                                    12864938683278674737956996400574416174101565840293888
165506647324519994421746682817280767519695960527804966143891642691499284891480678309535880456026315554816

Пояснення

Це порядок денний, який виглядає приблизно так:

           ┌─ 2:
           │    ┌─ 1
       ┌───┤    ├─ +
       │   └────┤           ┌─ / ─── *
── @. ─┤        │     ┌─ @ ─┴─ $:
       │        └─ @ ─┴─ i.
       └─ *

(Створено з використанням (9!:7)'┌┬┐├┼┤└┴┘│─'тоді 5!:4<'e')

Декомпозиція:

       ┌─ ...
       │
── @. ─┤
       │
       └─ *

Використовуючи верхню гілку як герунду G, а нижню як селектор F, це:

e n     <=>     ((F n) { G) n

При цьому використовується функція константа 2:тоді 0 = * n, коли знак дорівнює нулю (при цьому nдорівнює нулю). В іншому випадку ми використовуємо цю виделку:

  ┌─ 1
  ├─ +
──┤           ┌─ / ─── *
  │     ┌─ @ ─┴─ $:
  └─ @ ─┴─ i.

Що є одним із плюс у наступній серії:

            ┌─ / ─── *
      ┌─ @ ─┴─ $:
── @ ─┴─ i.

Розкладаючи далі, це продукт ( */) над самонаправленням ( $:) над діапазоном ( i.).


2
Ви також можете використовувати прислівник потужності, щоб отримати 2(]*:-<:)^:[~]14 байт за допомогою формули a(0) = 2та a(n+1) = a(n)^2 - (a(n) - 1). Щоб обчислити великі значення, 2на початку потрібно буде позначити як розширене ціле число.
миль

Обидва рішення дуже приємні. Я думаю, що я не знав про v`$:@.uрекурсивний формат. Я завжди використовував ^:vформат, який часто є більш складним. @miles Я також ніколи не використовував (]v)трюк. Щоб зрозуміти це мені знадобилося 5 хвилин.
randomra

1
Для повноти 3-й вид циклічного циклу (14 байт методом миль): 2(]*:-<:)~&0~](або 2:0&(]*:-<:)~]). І поєднуючи їх 13 байт ]0&(]*:-<:)2: .
randomra

12 байт: 0&(]*:-<:)2:. (Вибачте, я не повинен
гольфувати

@randomra Це дійсно акуратне використання облігацій. Мені довелося прочитати сторінку, щоб дізнатися, що саме сталося, оскільки зазвичай можна подумати, що середнє дієслово отримує три аргументи.
милі

9

Perl 6 , 24 байти

{(2,{1+[*] @_}...*)[$_]}
{(2,{1+.²-$_}...*)[$_]}

Пояснення

# bare block with implicit parameter 「$_」
{
  (
    # You can replace 2 with 1 here
    # so that it uses 1 based indexing
    # rather than 0 based
    2,

    # bare block with implicit parameter 「@_」
    {
      1 +

      # reduce the input of this inner block with 「&infix:<*>」
      # ( the input is all of them generated when using a slurpy @ var )
      [*] @_

      # that is the same as:
      # 「@_.reduce: &infix:<*>」
    }

    # keep calling that to generate more values until:
    ...

    # forever
    *

  # get the value as indexed by the input
  )[ $_ ]
}

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

my &code = {(2,{1+[*] @_}...*)[$_]}

say code 0; # 2
say code 1; # 3
say code 2; # 7
say code 3; # 43
say code 4; # 1807

# you can even give it a range
say code 4..7;
# (1807 3263443 10650056950807 113423713055421844361000443)

say code 8;
# 12864938683278671740537145998360961546653259485195807
say code 9;
# 165506647324519964198468195444439180017513152706377497841851388766535868639572406808911988131737645185443
say code 10;
# 27392450308603031423410234291674686281194364367580914627947367941608692026226993634332118404582438634929548737283992369758487974306317730580753883429460344956410077034761330476016739454649828385541500213920807

my $start = now;
# how many digits are there in the 20th value
say chars code 20;
# 213441

my $finish = now;
# how long did it take to generate the values up to 20
say $finish - $start, ' seconds';
# 49.7069076 seconds

Фрагмент масиву з $_? Що це за чаклунство?
Заїд

8

Haskell, 26 байт

f n|n<1=2|m<-f$n-1=1+m*m-m

Приклад використання: f 4-> 1807.


7

Java 7, 46 42 байти

int f(int n){return--n<0?2:f(n)*~-f(n)+1;}

Використовує 0-індексацію за звичайною формулою. Я змінив n*n-nна n*(n-1)хоча, так як Java не має під рукою оператора харчування, і f()дзвінки ставали довго.


3
f(n)*~-f(n) повинні працювати.
Денніс

1
Як я щоразу забуваю про цей трюк ? Якщо цього немає на сторінці підказок, це чорт напевно.
Геобіт

2
return--n<0економить ще один байт.
Денніс





5

Мозг-Флак , 158 154 байт

Протікає черниця мене бити тут

({}<(()())>){({}[()]<<>(())<>([]){{}<>({}<<>(({}<>))><>)<>({<({}[()])><>({})<>}{})<>{}([])}{}<>({}())([]){{}({}<>)<>([])}{}<>>)}{}([][()]){{}{}([][()])}{} 

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

Пояснення

Помістіть дві під вхід a (0)

({}<(()())>) 

У той час як вхід більший за нуль, віднімаємо один із вхідних і ...

{
({}[()]

Мовчки ...

<

Поставте один на інший стек, щоб діяти як каталізатор множення <> (()) <>

Поки стек не порожній

 ([])
 {
  {}

Перемістіть верхню частину списку та скопіюйте

  <>({}<<>(({}<>))><>)

Помножте каталізатор на копію

  <>({<({}[()])><>({})<>}{})<>{}
  ([])
 }
 {}

Додайте його

 <>({}())

Перемістіть послідовність назад у відповідний стек

 ([])
 {
 {}
 ({}<>)<>
 ([])
 }
 {}
 <>
>)
}{}

Видаліть усі, крім нижнього пункту (тобто останнього створеного номера)

([][()])
{
{}
{}
([][()])
}
{}

5

C, 32 байти

f(n){return--n?f(n)*~-f(n)+1:2;}

Використовує індексацію на основі 1. Перевірте це на Ideone .



5

R, 44 42 41 байт

2 байти зберегти завдяки JDL

1 байт зберегти завдяки користувачу5957401

f=function(n)ifelse(n,(a=f(n-1))^2-a+1,2)

1
З постановки проблеми це не зрозуміло, але до тих пір, nпоки гарантовано не буде негативним, тоді стан можна зменшити n>0до справедливого n.
JDL

@JDL Приємно! Спасибі !
Mamie

f(n-1)становить 6 байт. Я думаю, що ви зберігаєте байт, присвоюючи йому щось. тобтоifelse(n,(a=f(n-1))^2-a+1,2)
user5957401

5

Оазис , 4 байти (не конкуруючий)

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

Код:

²->2

Альтернативне рішення завдяки Zwei :

<*>2

Розширена версія:

a(n) = ²->
a(0) = 2

Пояснення:

²    # Stack is empty, so calculate a(n - 1) ** 2.
 -   # Subtract, arity 2, so use a(n - 1).
  >  # Increment by 1.

Використовує кодування CP-1252 . Спробуйте в Інтернеті!


Остання мова про гольф? Ти більше не збираєшся робити? Д:
Конор О'Брайен

@ ConorO'Brien Напевно, зараз у мене ідеї :(
Аднан

Перш ніж подивитися на цей виклик, я зрозумів b<*>2 скориставсяa(n-1)*(a(n-1)+1)-1
Zwei

@Zwei Дуже акуратно! Ви насправді можете відмовитися, bоскільки це буде автоматично заповнене (а не введення) :).
Аднан

1
Так, я помітив це після публікації. Я здивований, наскільки добре ця мова працює для цього, навіть якщо вона розроблена для послідовностей.
Zwei

3

Пітон, 38 36 байт

2 байти завдяки Деннісу.

f=lambda n:0**n*2or~-f(n-1)*f(n-1)+1

Ідей це!

Використовує це співвідношення, модифіковане відповідно до наведеного в послідовності:

a(n+1) = a(n) * (a(n) - 1) + 1

Пояснення

0**n*2 повертає 2 коли n=0і в 0іншому випадку, оскільки 0**0визначено, що знаходиться 1в Python.


3

Чеддар , 26 байт

n g->n?g(n-=1)**2-g(n)+1:2

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

Досить ідіоматичний.

Пояснення

n g ->    // Input n, g is this function
  n ?     // if n is > 1
    g(n-=1)**2-g(n)+1   // Do equation specified in OEIS
  : 2     // if n == 0 return 2

Зараз 4 рази (майже)
Leaky Nun

Чому ви видалили посилання TIO?
Leaky Nun

@LeakyNun о, ви повинні редагувати, поки я
Downgoat





2

Желе , 7 байт

²_’
2Ç¡

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

Використовує замість цього співвідношення, подане в послідовності: a(n+1) = a(n)^2 - a(n) + 1

Пояснення

2Ç¡   Main chain, argument in input

2     Start with 2
  ¡   Repeat as many times as the input:
 Ç        the helper link.


²_’   Helper link, argument: z
²     z²
  ’   z - 1
 _    subtraction, yielding z² - (z-1) = z² - z + 1

2

C, 46 байт

s(n,p,r){for(p=r=2;n-->0;p*=r)r=p+1;return r;}

Ідей це!

Використання p як тимчасове зберігання продукту.

В основному, я визначив дві послідовності p(n)і r(n), де r(n)=p(n-1)+1іp(n)=p(n-1)*r(n) .

r(n) є необхідною послідовністю.


1
Будь-яка причина, що ви не використовуєте тут те саме відношення з вашої відповіді Python? Це повинно бути набагато коротшим ...
Денніс

@Dennis Це цікавіше.
Leaky Nun

@Dennis І цю відповідь можна перенести
Leaky Nun

2

R, 50 46 44 байт

    n=scan();v=2;if(n)for(i in 1:n){v=v^2-v+1};v

Замість того, щоб відстежувати всю послідовність, ми просто відслідковуємо продукт, який дотримується заданого правила квадратичного оновлення до тих пір, поки n> 1 n> 0. (У цій послідовності використовується "start at one нуля")

Використання старту в нульовому режимі економить пару байтів, оскільки ми можемо використовувати, якщо (n), а не якщо (n> 1)


2

Медузи , 13 байт

p
\Ai
&(*
><2

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

Пояснення

Почнемо знизу вгору:

(*
<

Це гачок, який визначає функцію f(x) = (x-1)*x .

&(*
><

Це складає попередній гак з функцією збільшення, тому він дає нам функцію g(x) = (x-1)*x+1 .

\Ai
&(*
><

Нарешті, це генерує функцію, hяка є ітерацією попередньої функціїg стільки разів, скільки задано цілим числом.

\Ai
&(*
><2

І нарешті, ми застосовуємо цю ітерацію до початкового значення 2 . pНагорі просто друкує результат.

Альтернативно (також 13 байт)

p
>
\Ai
(*
>1

Це відкладає приріст до самого кінця.


2

C, 43 , 34 , 33 байт

1-індексований:

F(n){return--n?n=F(n),n*n-n+1:2;}

Основний тест:

int main() {
  printf("%d\n", F(1));
  printf("%d\n", F(2));
  printf("%d\n", F(3));
  printf("%d\n", F(4));
  printf("%d\n", F(5));
}




1

Власне , 14 12 байт

Для цього використовується 0-індексація. Пропозиції з гольфу вітаються. Спробуйте в Інтернеті!

2#,`;πu@o`nF

Ungolfing:

2#              Start with [2]
  ,`     `n     Take 0-indexed input and run function (input) times
    ;           Duplicate list
     πu         Take product of list and increment
       @o       Swap and append result to the beginning of the list
           F    Return the first item of the resulting list

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