1, 2, 4, 8, 16,… 33?


24

Вызов

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

         1, 2, 4, 8, 16 ...

Ой, подождите ... Я забыл первые несколько цифр:

1, 1, 1, 1, 2, 4, 8, 16 ...

Черт возьми, я добавлю еще несколько для хорошей меры:

1, 1, 1, 1, 2, 4, 8, 16, 33, 69, 146, 312, 673, 1463, 3202, 7050, 15605, 34705 ...

Числа являются обобщенными каталонскими числами, заданными формулой (с нулевым индексом):

a(n+1)=a(n)+k=2n1a(k)a(n1k)

где

a(0)=a(1)=a(2)=a(3)=1

Это OEIS A004149 .

Вы можете выбрать, хотите ли вы иметь последовательность с нулевым или единичным индексированием. Последовательность, конечно, должна быть одинаковой, поэтому вы должны переписать формулу, если она у вас одноиндексная.


Поправьте меня , если я ошибаюсь здесь, но модификация для одной-индексированной формулы изменить a(n-1-k)на a(n-k), правильно?
Sumner18

9

Ответы:


23

Python , 51 байт

f=lambda n,k=2:n<3or k<n and f(k)*f(n-k-2)+f(n,k+1)

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

Немного упрощает формулу:

a(n)=k=2n1a(k)a(n2k)

a(1)=a(0)=a(1)=a(2)=1


8
Поздравляю на 100k!
Стьюи Гриффин

Поскольку я также пришел к этому решению самостоятельно, я должен сказать, что путь к нему немного неровный ...
Эрик Аутгольфер

10

Perl 6 , 44 байта

{1,1,1,1,{sum @_[2..*]Z*@_[@_-4...0,0]}...*}

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

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

Объяснение:

{                                          }  # Anonymous code block
                                       ...*   # Create an infinite sequence
 1,1,1,1,                                     # Starting with four 1s
         {                            }       # Where each new element is:
          sum                                   # The sum of
              @_[2..*]                          # The second element onwards
                      Z*                        # Zip multiplied with
                        @_[@_-4...0  ]          # The fourth last element backwards
                                   ,0           # And 1

10

05AB1E , 14 13 11 байт

$ƒˆ¯Âø¨¨¨PO

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

Выводит n-й элемент, 0-индексированный.

$                # push 1 and the input
 ƒ               # repeat (input+1) times
  ˆ              #  add the top of the stack (initially 1) to the global array
   ¯             #  push the global array
    Â            #  and a reversed copy of it
     ø           #  zip the two together, giving a list of pairs
      ¨¨¨        #  drop the last 3 pairs
         P       #  take the product of each pair (or 1 if the list is empty)
          O      #  take the sum of those products
                 #  after the last iteration, this is implicitly output;
                 #  otherwise, it's added to the global array by the next iteration

7

JavaScript (ES6), 42 байта

Порт решения xnor .

0 индексированные.

f=(n,k=2)=>n<3||k<n&&f(k)*f(n+~++k)+f(n,k)

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


JavaScript (ES6),  83  75 байт

Более быстрое, менее рекурсивное, но значительно более длинное решение.

0 индексированные.

f=(n,i,a=[p=1])=>a[n]||f(n,-~i,[...a,p+=(h=k=>k<i&&a[k]*a[i-++k]+h(k))(2)])

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




6

05AB1E , 17 13 байт

4Å1λ£₁λ¨Â¦¦s¦¦*O+

Не короче, чем существующий ответ 05AB1E , но я хотел попробовать рекурсивную функциональность новой версии 05AB1E для себя. Может быть, игра в гольф на несколько байтов. РЕДАКТИРОВАТЬ: И это действительно может, увидеть рекурсивную версию ответа @Grimy 's 05AB1E ниже, который составляет 13 байтов .

N

N£è
£ .

Объяснение:


a(N)знак равноa(N-1)+ΣКзнак равно2N-1(a(К)a(N-1-К))

a(0)знак равноa(1)знак равноa(2)знак равноa(3)знак равно1

   λ               # Create a recursive environment,
    £              # to output the first (implicit) input amount of results after we're done
4Å1                # Start this recursive list with [1,1,1,1], thus a(0)=a(1)=a(2)=a(3)=1
                   # Within the recursive environment, do the following:
      λ            #  Push the list of values in the range [a(0),a(n)]
       ¨           #  Remove the last one to make the range [a(0),a(n-1)]
        Â          #  Bifurcate this list (short for Duplicate & Reverse copy)
         ¦¦        #  Remove the first two items of the reversed list,
                   #  so we'll have a list with the values in the range [a(n-3),a(0)]
           s       #  Swap to get the [a(0),a(n-1)] list again
            ¦¦     #  Remove the first two items of this list as well,
                   #  so we'll have a list with the values in the range [a(2),a(n-1)]
              *    #  Multiply the values at the same indices in both lists,
                   #  so we'll have a list with the values [a(n-3)*a(2),...,a(0)*a(n-1)]
               O   #  Take the sum of this list
               +  #  And add it to the a(n-1)'th value
                   # (afterwards the resulting list is output implicitly)

13 байт версии @Grimy (убедитесь , что upvote своего ответа , если у вас еще нет!):

1λ£λ1šÂ¨¨¨øPO

N


1λèλ1šÂ¨¨¨øPO
λλ1šÂ¨¨¨øPOa(0)знак равно1

Объяснение:


a(N)знак равноΣКзнак равно2N-1(a(К)a(N-2-К))

a(-1)знак равноa(0)знак равноa(1)знак равноa(2)знак равно1

 λ             # Create a recursive environment,
  £            # to output the first (implicit) input amount of results after we're done
1              # Start this recursive list with 1, thus a(0)=1
               # Within the recursive environment, do the following:
   λ           #  Push the list of values in the range [a(0),a(n)]
    1š         #  Prepend 1 in front of this list
      Â        #  Bifurcate the list (short for Duplicate & Reverse copy)
       ¨¨¨     #  Remove (up to) the last three value in this reversed list
          ø    #  Create pairs with the list we bifurcated earlier
               #  (which will automatically remove any trailing items of the longer list)
           P   #  Get the product of each pair (which will result in 1 for an empty list)
            O  #  And sum the entire list
               # (afterwards the resulting list is output implicitly)

1
Интересно, что это может решить (1200) за 40 секунд на tio, в то время как другие рекурсивные подходы тайм-аут для чисел n, чем 100 ...
Стьюи Гриффин

1
Я также сделал (но не опубликовал) рекурсивную версию. Это 13 байтов для первых n членов или 11 байтов для бесконечного списка . Специальный регистр a (n-1) стоит много байтов и не нужен (см., Например , формулу xnor ).
Grimmy

@Grimy Вы не возражаете, если я добавлю ваши рекурсивные решения в мой ответ (конечно же, зачет)? Я также оставлю свой оригинальный ответ. Но приятно видеть различия между исходной формулой и формулой сохранения байтов в xnor. :)
Кевин Круйссен

1
Конечно это нормально!
Grimmy

@StewieGriffin Да, меня также впечатлила скорость этих рекурсивных бесконечных функций. Возможно, одна из сильных сторон Эликсира, и определенно благодаря встроенной ленивой загрузке. Он рассчитывается n=100за 0,65 секунды , но когда я отключаю ленивую загрузку, вместо 60 секунд, даже дляn=25 .
Кевин Круйссен





2

Japt , 19 17 16 байт

Выводится n1-й член, 1-индексированный.

@Zí*Zz2)Ťx}g4Æ1

Попытайся

@Zí*Zz2)Ťx}g4Æ1     :Implicit input of integer U
@                    :Function taking an array as an argument via parameter Z
 Zí                  :  Interleave Z with
    Zz2              :  Z rotated clockwise by 180 degrees (simply reversing would be a bye shorter but would modify the original array)
   *                 :  Reduce each pair by multiplcation
       )             :  End interleave
        Å            :  Slice off the first element
         ¤           :  Slice off the first 2 elements
          x          :  Reduce by addition
           }         :End function
            g        :Pass the following as Z, push the result back to it and repeat until it has length U
             4Æ1     :Map the range [0,4) to 1s
                     :Implicit output of the last element

1

Haskell , 65 байт

f a|a<4=1|z<-g[2..a]=sum$zipWith(*)z$reverse(1:g[0..a-4])
g=map f

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

Вы можете использовать либо fдля получения одного элемента последовательности, либо передать список значений gи получить все индексы для этого списка.


1

Forth (gforth) , 99 81 байт

: f recursive dup 4 > if 0 over 3 do over 1- i - f i f * + loop else 1 then nip ;

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

Вывод n-й член, а ввод 1-индексированный

Изменить: 17 байтов сохранены путем переключения на формулу Xnor. Сохранено еще 1 байт с помощью 1-индексированного

Код Объяснение

: f                     \ start a new word definition
  recursive             \ mark that this word will be recursive
  dup 4 >               \ duplicate the input and check if it is greater than 4
  if                    \ if it is:
    0 over              \ create an accumulator and copy n to top of stack
    3 do                \ start counted loop from 3 to n-1
      over 1- i - f     \ recursively calculate f(n-1-i)
      i f               \ recursively calculate f(i)
      * +               \ multiply results and add to accumulator
    loop                \ end the counted loop        
  else                  \ otherwise, if n < 5
    1                   \ put 1 on the stack
  then                  \ end the if block
  nip                   \ drop n from the stack
;                       \ end the word definition

1

Древесный уголь , 26 байт

F⁵⊞υ¹FN⊞υΣ✂E⮌υ×κ§υλ³→I§υ±⁴

Попробуйте онлайн! Ссылка на подробную версию кода. Печатает 0-индексированное n-е число, хотя оно рассчитывается с использованием 1-индексации внутри. Объяснение:

F⁵⊞υ¹

Начните с a[0] = a[1] = a[2] = a[3] = a[4] = 1. Да, это 1-индексированный, но затем с дополнительным нулевым значением. Это код для вас.

FN

Рассчитайте дополнительные nусловия. Это излишне, но облегчает поиск нужного термина n<5.

⊞υΣ✂E⮌υ×κ§υλ³

Для каждого слагаемого вычислите следующий слагаемый как сумму слагаемых до настоящего времени, умноженных на обратное слагаемое до настоящего времени, за исключением трех слагаемых.

Это неоперация, используемая, чтобы обмануть Charcoal при разборе формы с двумя аргументами Slice, иначе мне пришлось бы использовать менее удачный способ удаления трех терминов.

I§υ±⁴

Выведите 4-й последний член.


1

Pyth , 30 байт

J*4]1VQ=+J+eJsPP*M.t,PJ_PJ0;<J

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

Возвращает первое N элементы последовательности.

J*4]1VQ=+J+eJsPP*M.t,PJ_PJ0;<JQ # Full program, last Q = input (implicitly added)
J*4]1                  # J = 4 * [1] (=[1,1,1,1])
VQ                     # for N in range(Q):
  =+J                  #  J +=
     +eJ               #   J[-1] + 
        s              #    sum(                           )
           *M          #     map(__operator_mul,          )
             .t      0 #      transpose(          , pad=0)
               ,       #       [       ,         ]
                PJ     #         J[:-1] 
                  _PJ  #                 J[1::-1]
<JQ                    # J[::Q]

Альтернатива: заменить <на, @чтобы вернутьN-ый элемент последовательности, 0-индексированный.



1

Октава , 73 байта

g=(1:4).^0;for(i=3:(n=input('')))g(i+2)=g(4:i+1)*g(i-(2:i-1))';end;g(end)

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

-2 байта благодаря Стьюи Гриффину. И снова императивный подход побеждает функционально-рекурсивный подход. Это показано ниже.

Октава , 75 байт

f(f=@(a)@(n){@()sum(arrayfun(@(k)a(a)(k)*a(a)(n-2-k),2:n-1)),1}{2-(n>3)}())

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

Капча хотел проверить, что я был человеком, когда писал это. Если честно, я не уверен .


Я не вижу каких-либо очевидных способов сократить петлевой подход ... Выглядит неплохо! Кроме того, не часто я вижу индексацию с нуля в Octave :)
Стьюи Гриффин,

@StewieGriffin Поскольку рекурсия имеет некоторые смещения, на самом деле не имеет значения, выберете ли вы нулевое или одно индексирование. Я думаю, возможно, я мог бы побрить несколько байтов, если бы я сделал 2-индексирование, но это казалось обманом. Во всяком случае, ваша интуиция была права - так или иначе, это было действительно короче анонимным рекурсивным способом. Я думаю, что главное преимущество в том, что он очень хорошо справляется с созданием четырех начальных значений, потому что он просто возвращает 1 для n<4.
Санчиз

1
@StewieGriffin Конечно, старое доброе умножение матриц. Отлично сработано!
Sanchises


0

C / C ++ , 70 69 67 байт

-1 байт благодаря Джонатану.

int a(int n){int k=2,s=0;while(++k<n)s+=a(k)*a(n+~k);return s?s:1;}

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


Может a(n-1-k)быть a(n+~k)?
Джонатан Фрех

@JonathanFrech даже a(++k)*a(n-k), вероятно, будет работать, и он падает еще на 2 байта for. Но я чувствую запах неопределенного поведения.
Полфосол ఠ_ఠ

Это, кажется, проблема последовательности; наиболее определенно UB.
Джонатан Фрех
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.