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


32

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

Каждый участник является продуктом всех предыдущих участников плюс один. Первый член последовательности - 2.

задача

Создайте наименьшую возможную программу, которая берет n и вычисляет n-й член последовательности Сильвестра. Стандартный ввод, вывод и лазейки применяются. Так как результат растет очень быстро, вы не должны принимать какой-либо термин, из-за которого результат может вызвать переполнение в выбранном вами языке.

Тестовые случаи

Вы можете использовать либо ноль, либо одно индексирование. (Здесь я использую нулевую индексацию)

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

Какие входные данные должны быть обработаны? Выход растет довольно быстро.
Geobits

1
@ Geobits вы должны справиться столько, сколько ваш язык может
Wheat Wizard

Является ли массив, который при индексации, nвозвращает nthномер принятой последовательности?
user6245072

@ user6245072 Нет, вы должны индексировать свои собственные массивы
Wheat Wizard

Ответы:


26

Brain-Flak , 76 68 58 52 46 байт

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

Попробуйте онлайн!

Использует эти отношения вместо:

формула

который получен из этого отношения, модифицированного из того, что предусмотрено в последовательности:

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

объяснение

Для получения документации о том, что делает каждая команда, пожалуйста, посетите страницу GitHub .

В Brain-Flak есть два стека, которые я назову Stack 1 и Stack 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 байтов, чтобы показать, что ява-девелепоры должны перейти в состояние мозгового истощения
Рохан Джунджхунвала

1
@RohanJhunjhunwala Боюсь, что это невозможно ...
Утренняя монахиня

@ LeakyNun это все еще интересно думать. Brain Flak обладает некоторой силой и удивительно лаконичен
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)

Эта последовательность очень похожа, но мы можем отложить приращение до самого конца, что позволяет сохранить байт в этой программе.

Итак, вот аннотированный исходный код:

введите описание изображения здесь
Создано с помощью HexagonyColorer Тимви .

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

введите описание изображения здесь
Создано с помощью Эзотерики Тимви .

Код начинается с серого пути, который оборачивает левый угол, поэтому начальный линейный бит следующий:

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

Затем код попадает в <ветвь и указывает начало (и конец) основного цикла. Пока N- ребро имеет положительное значение, будет выполнен зеленый путь. Этот путь несколько раз обходит сетку, но на самом деле он полностью линейный:

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

.Нет-OPS, поэтому фактический код:

""~&}=*}=+={(
""             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 brute forcer может выполнять не более 7-байтовых программ (и даже только с некоторыми предположениями) за разумное время. Я не вижу, чтобы это было возможно дистанционно в 7 байтов.
Мартин Эндер

Так? Что не так с попыткой?
CalculatorFeline

@CalculatorFeline Laziness. Грубый форсер всегда требует некоторой ручной настройки, которую я не могу потрудиться, потому что практически нет вероятности, что он что-то найдет. Некоторая версия скрипта есть на 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.

Далее разлагается, это product ( */) over self-reference ( $:) over range ( i.).


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

Оба решения очень хороши. Я думаю, что я не знал о v`$:@.uрекурсивном формате. Я всегда использовал ^:vформат, который часто является более сложным. @ Мили Я тоже никогда не использовал (]v)трюк. Мне понадобилось 5 минут, чтобы понять это.
Рандомра

1
Для полноты 3-й вид зацикливания (14 байтов, используя метод миль): 2(]*:-<:)~&0~](или 2:0&(]*:-<:)~]). И объединяя их 13 байтов ]0&(]*:-<:)2: .
Рандомра

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
Как я могу забыть об этом трюке каждый раз ? Если этого нет на странице с советами, это наверняка произойдет.
Geobits

2
return--n<0сохраняет еще один байт.
Деннис





5

Brain-Flak , 158 154 байта

Лики Монахиня побила меня здесь

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

Попробуйте онлайн!

объяснение

Положите два под входом а (0)

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

В то время как вход больше нуля, вычтите единицу из входа и ...

{
({}[()]

Молча ...

<

Поместите один на другой стек, чтобы действовать как катализатор для умножения <> (()) <>

Пока стек не пустой

 ([])
 {
  {}

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

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

Умножьте катализатор на копию

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

Добавить один

 <>({}())

Переместите последовательность обратно в правильный стек

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

Удалить все, кроме нижнего элемента (т. Е. Последний созданный номер)

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

5

C, 32 байта

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

Использует индексирование на основе 1. Проверьте это на Ideone .



5

R, 44 42 41 байт

2 байта экономят благодаря JDL

1 байт благодаря пользователю user5957401

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 . Попробуйте онлайн!


Последний язык игры в гольф? Ты больше не собираешься зарабатывать? D:
Конор О'Брайен

@ ConorO'Brien Вероятно, у меня сейчас нет идей :(
Аднан

Прежде чем взглянуть на эту проблему, я получил с b<*>2помощьюa(n-1)*(a(n-1)+1)-1
Zwei

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

1
Да, я заметил это после публикации. Я удивлен, насколько хорошо этот язык работает для этого, даже если он разработан для последовательностей.
Цвей

3

Python, 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 раза (почти)
Лаки Монахиня

Почему вы удалили ссылку TIO?
Утренняя монахиня

@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 Это более интересно.
Утренняя монахиня

@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. (Эта последовательность использует соглашение «начать с одного нуля»)

Использование соглашения о начале с нуля экономит пару байтов, поскольку мы можем использовать if (n) вместо if (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

С, 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.