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=2n−1a(k)⋅a(n−1−k)

где

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=2n−1a(k)⋅a(n−2−k)

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.