Сделай мне метапоследовательность


25

Задний план

Для этой задачи «метапоследовательность» будет определяться как последовательность чисел, где будут увеличиваться не только сами числа, но также и приращение, и приращение будет увеличиваться при увеличении значения и т. Д.

Например, метапоследовательность уровня 3 будет начинаться как:

1 2 4 8 15 26 42 64 93 130 176

потому что:

    1 2 3  4  5  6  7  8   9       >-|
      ↓+↑ = 7                        | Increases by the amount above each time
  1 2 4 7  11 16 22 29 37  46  >-| <-|
                                 | Increases by the amount above each time
1 2 4 8 15 26 42 64 93 130 176 <-|

Вызов

Учитывая положительное целое число, выведите первые двадцать элементов метапоследовательности этого уровня.

Контрольные примеры

Вход: 3Выход:[ 1, 2, 4, 8, 15, 26, 42, 64, 93, 130, 176, 232, 299, 378, 470, 576, 697, 834, 988, 1160 ]

Вход: 1Выход:[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ]

Вход: 5Выход:[ 1, 2, 4, 8, 16, 32, 63, 120, 219, 382, 638, 1024, 1586, 2380, 3473, 4944, 6885, 9402, 12616, 16664 ]

Вход: 13Выход:[ 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16383, 32752, 65399, 130238, 258096, 507624 ]

Как вы можете понять, первые элементы T+1 каждой последовательности уровня являются первыми степенями 2 ...TT+1

правила

  • Применяются стандартные лазейки
  • Это , поэтому выигрывает самый короткий ответ в байтах

2
Я полагаю, вы имеете в виду 20 терминов, а не цифры?
Quintec


6
Вы можете уточнить, должны ли решения работать для ввода 20 или выше.
FryAmTheEggman

4
Можем ли мы выбрать индекс 0 (то есть выходной уровень 1 для ввода 0, 2-й уровень для ввода 1и т. Д.)?
Линн

1
@ MilkyWay90, не очень понятно, что вы имеете в виду: 219 (с уровня 5) встречается только в треугольнике Паскаля как и . (2191)(219218)
Питер Тейлор

Ответы:


8

Желе , 8 7 байт

20ḶcþŻS

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

   cþ       Table of binom(x,y) where:
20Ḷ           x = [0..19]
     Ż        y = [0..n]    e.g.  n=3 → [[1, 1, 1, 1, 1, 1,  …]
                                         [0, 1, 2, 3, 4, 5,  …]
                                         [0, 0, 1, 3, 6, 10, …]
                                         [0, 0, 0, 1, 4, 10, …]]

      S     Columnwise sum.           →  [1, 2, 4, 8, 15, 26, …]

Здесь используется понимание @ alephalpha, что

мета-последовательностьN(я)знак равноΣКзнак равно0N(яК),


Это жестоко лаконично. Просто восхитительно.
Дон

22

Wolfram Language (Mathematica) , 34 байта

0~Range~19~Binomial~i~Sum~{i,0,#}&

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

Метапоследовательность уровня является суммой первых элементов каждой строки треугольника Паскаля.NN+1


1
Для этого есть почти встроенная функция , но, к сожалению, она длиннее.
Питер Тейлор

1
Я не знаю достаточно WL, чтобы сделать что-нибудь полезное в нем, но мне кажется, что он может выиграть от тождества
T(N,К)знак равно{1если Кзнак равно02T(N,К-1)-(К-1N)иначе
Питер Тейлор,

17

Haskell , 34 байта

(iterate(init.scanl(+)1)[1..20]!!)

Использует 0-индексированные входы ( f 4возвращает уровень 5.)

Haskell , 36 байт

f 1=[1..20]
f n=init$scanl(+)1$f$n-1

Попробуйте онлайн! Использует 1-индексированные входы ( f 5возвращает уровень 5.)

объяснение

scanl (+) 1это функция, которая принимает частичные суммы списка, начиная с (и предварительно) 1.

Например: scanl (+) 1 [20,300,4000]равно [1,21,321,4321].

Оказывается, что уровень - это просто эта функция, примененная раз к списку .N(N-1)[1,2,3,...]

(Или, что то же самое: раз в список всех.)N

Мы используем либо, initлибо [1..20-n]для учета увеличения списка на каждое приложение.1


1
[1..20-n]не будет работать для N>20
Питер Тейлор

take 20.(iterate(scanl(+)1)[1..]!!)будет стоить только на байт больше, чтобы это исправить
H.PWiz

1
Ваш pointfree ответ может быть обратно до 34 байт , используя ваш другой ответ: (iterate(init.scanl(+)1)[1..20]!!).
xnor

7

Brain-Flak , 84 82 байта

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

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

аннотированный

<>               Switch to the off stack
((()()()()()){}) Push 10
{({}[((()))])}{} Make twice that many 1s
<>               Switch back
{                While ...
({}[(())]<       Subtract one from the input and push 1
<>               Switch
{                For every x on the stack
({}<>({}))<>     Remove x and add it to a copy of the other TOS
}                End loop
<>{}             Remove 1 element to keep it 20
{({}<>)<>}       Copy everything back to the other stack
>)}<>            End scopes and loops

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


3
Вы знаете, это забавно, как это короче, чем Rust
наденьте яркий

7

R , 36 байт

rowSums(outer(0:19,0:scan(),choose))

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

Спасибо @Giuseppe за предложение outer.

Это основано на подходе @alephalpha, описанном


Вы могли бы использовать Mapвместо внешнего?
JDL

@JDL Я не вижу, как это будет работать. Мне нужны все возможные комбинации, а не просто пары комбинаций.
Ник Кеннеди

5

Python 2 , 69 58 55 байт

Сохраненные байты благодаря ovs и Джо Кинг ; Кроме того, теперь он работает и в Python 3.

m=lambda t:[1+sum(m(t-1)[:n])for n in range(~t and 20)]

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

Математика

Пусть a(T,N) будет термином NTчас (с индексами 0) последовательности на уровне T . Небольшой анализ приводит к следующей формуле повторения:

a(T,N)знак равно1+Σязнак равно0N-1a(T-1,я)

Работая в обратном направлении, определим a(0,N)знак равно1 и a(-1,N)знак равно0 для всех N . Эти определения упростят наш базовый случай.

Код

Мы определяем функцию, m(t)которая возвращает первые 20 элементов последовательности на уровне t. Если tнеотрицательный, мы используем рекурсивную формулу выше; если tесть -1, мы возвращаем пустой список. Пустой список работает как базовый случай, потому что результат каждого рекурсивного вызова нарезается ( [:n]), а затем суммируется. Нарезка пустого списка дает пустой список, а суммирование пустого списка дает 0. Это то результат , который мы хотим, так как ярус -1 должно вести себя как постоянная последовательность всех 0 -х гг.

m=lambda t:                     # Define a function m(t):
 [          ]                   # List comprehension
     for n in range(         )  # for each n from 0 up to but not including...
                    ~n and 20   # 0 if n is -1, else 20:
  1+sum(          )             # a(t,n) = 1 + sum of
              [:n]              # the first n elements of
        m(t-1)                  # the previous tier (calculated recursively)

61 байт как рекурсивная лямбда-функция (значительно более неэффективная).
Ов

@ovs Спасибо! Я нашел еще пару байтов, используя другой базовый вариант.
DLosc


1
(t>=0)*range(20)сохраняет байт, хотя, возможно, есть еще более короткое выражение.
XNOR

1
if~tсохраняет еще два за @xnor
Джо Кинг

4

dzaima / APL REPL, 14 байтов

(+\1,19↑)⍣⎕⍳20

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

(+\1,19↑)⍣⎕⍳20
(       )⍣⎕     repeat the function below input times:
 +\               cumulative sum of
   1,             1 prepended to
     19          the first 19 items of the previous iteration
           20  starting with the first 20 integers

-1 байт с использованием dzaima / APL: 1∘,1,
Adám

@ Adám, о-о-о ... верно
dzaima

Полная программа в 17:(≢↑(+\1∘,)⍣⎕)20⍴1
Адам

14 байтов с использованием REPL (добавьте -sфлаг).
Эрик Outgolfer

Если вы используете флаг, язык становится между -sпрочим (разве -sэто не флаг repl?)
только ASCII


3

Perl 6 , 34 32 байта

-2 байта благодаря Джо Кингу

{(@,{[\+] 1,|.[^19]}...*)[$_+1]}

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

объяснение

{                              }  # Anonymous block
   ,                ...*  # Construct infinite sequence of sequences
  @  # Start with empty array
    {              }  # Compute next element as
     [\+]     # cumulative sum of
          1,  # one followed by
            |.[^19]  # first 19 elements of previous sequence
 (                      )[$_+1]  # Take (n+1)th element

29 байтов ( $^aвместо $_необходимого)
Джо Кинг

1
@JoKing Хорошо, но это предполагает, что $_это не определено при вызове функции. Я предпочитаю решения, которые не зависят от состояния глобальных переменных.
nwellnhof

3

Python 3.8 (предварительная версия) , 62 байта

f=lambda n:[t:=1]+[t:=t+n for n in(n and f(n-1)[:-1]or[0]*19)]

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


объяснение

f=lambda n:     # funtion takes a single argument
     [t:=1]     # This evaluates to [1] and assigns 1 to t
                # assignment expressions are a new feature of Python 3.8
       +        # concatenated to
     [  ....  ] # list comprehension

# The list comprehesion works together with the
# assignment expression as a scan function:
[t := t+n for n in it]
# This calculates all partial sums of it 
# (plus the initial value of t, which is 1 here)

# The list comprehension iterates
# over the first 19 entries of f(n-1)
# or over a list of zeros for n=0
 for n in (n and f(n-1)[:-1] or [0]*19)

3

R ( 63 47 байт)

function(n,k=0:19)2^k*pbeta(.5,pmax(k-n,0),n+1)

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

Октава ( 66 46 байт)

@(n,k=0:19)2.^k.*betainc(.5,max(k-n,1E-9),n+1)

Демо онлайн . Точно такая же концепция, но немного страшнее, потому что betainc, в отличие от R pbeta, требуется, чтобы второй и третий аргументы были больше нуля.

Большое спасибо Джузеппе за помощь в векторизации, со значительной экономией.


2

Рубин, 74 байта

a=->b{c=[1];d=0;b==1?c=(1..20).to_a: 19.times{c<<c[d]+(a[b-1])[d];d+=1};c}

Безголовая версия:

def seq num
    ary = [1]
    index = 0
    if num == 1
        ary = (1..20).to_a
    else
        19.times{ary << ary[index]+seq(num-1)[index]; index+=1}
    end
    return ary
end

Довольно ресурсоемкий - онлайн-версия не может рассчитать 13-ую последовательность.

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



2

JavaScript (Node.js) , 58 байт

t=>Array(20).fill(t).map(g=(t,i)=>i--*t?g(t,i)+g(t-1,i):1)

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

Это тривиально записать следующую рекурсивную формулу на основе описания в вопросе

г(T,я)знак равно{г(T,я-1)+г(T-1,я-1)еслияT>01еслияTзнак равно0
[г(T,0)...г(T,19)]


2

05AB1E , 11 9 байтов

20LIF.¥>¨

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

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

Объяснение:

20L        # Create a list in the range [1,20]
   IF      # Loop the input amount of times:
         #  Get the cumulative sum of the current list with 0 prepended automatically
       >   #  Increase each value in this list by 1
        ¨  #  Remove the trailing 21th item from the list
           # (after the loop, output the result-list implicitly)

1
Хорошее использование !
Эминья

2

R , 59 49 байт

f=function(n)`if`(n,Reduce(`+`,f(n-1),1,,T),1:20)

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

Рекурсивно Reduceс +, init=1и accumulation=TRUEчтобы избежать необходимости подмножества. Спасибо Criminally Vulgar за предложение рекурсивного подхода!


tio это только 39 байтов (используя биномиальный подход)
Ник Кеннеди

@NickKennedy - это отдельный подход, поэтому я бы порекомендовал опубликовать его самому, и использовать его лучше, outerчем sapplyдля 36 байтов
Джузеппе

1
Преобразование этого подхода в рекурсивную функцию дает 53 байта (я думаю, что в рекурсивах нам нужно включить назначение? Если нет, 51) TIO
CriminallyVulgar

1
@CriminallyVulgar мы можем получить до 49 байтов :-)
Джузеппе

@ Джузеппе Хаха, я знал, что это игра в гольф, просто не мог ее увидеть! Некоторое cumsumвремя я пытался заставить его работать, но это Reduceтак здорово. Приятно иметь возможность также убрать индекс на 1, не замечая этого в комментариях.
Преступно-


1

J , 24 байта

<:(1+/\@,])^:[(1+i.20)"_

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

ПРИМЕЧАНИЕ: Оказывается, это перевод ответа APL от dzaima, хотя я на самом деле не заметил его до того, как написал это.

объяснение

<: (1 +/\@, ])^:[ (1+i.20)"_
<:                           NB. input minus 1 (left input)
                  (1+i.20)"_ NB. 1..20 (right input)
   (         )^:[            NB. apply verb in parens 
                             NB. "left input" times
   (1     , ])               NB. prepend 1 to right input
   (  +/\@   )               NB. and take scan sum

1

Рубин, 49 байтов

f=->n{n<1?[1]*20:[o=1]+f[n-1][0,19].map{|x|o+=x}}

Рекурсивное определение: уровень 0 равен 0, 1,1,1,1...а каждый последующий уровень равен 1, за которым следует последовательность, первыми отличиями которой являются предыдущий уровень. Досадно, что это дало бы мне 21 значение, если бы я не вырезал явно первые 20; кажется, должен быть способ сократить это, избегая этого.





1

Сетчатка , 59 байт

.+
19*$(_,

Заменить вход на 19 1с (в унарном виде). (20-е значение равно 0, потому что оно всегда удаляется при первом прохождении цикла.)

"$+"{`
)`

Повторите цикл исходного ввода количество раз.

(.+),_*
_,$1

Удалить последний элемент и префикс а 1.

_+(?<=((_)|,)+)
$#2*

Рассчитать накопленную сумму.

_+
$.&

Преобразовать в десятичную.

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



1

Ржавчина , 135 байт

fn t(m:u64)->Vec<u64>{let f=|y|(1..=y).fold(1,|a,n|a*n);(0..20).map(|i| (0..=u64::min(i,m)).fold(0,|a,x|a+f(i)/f(x)/f(i-x))).collect()}

использовал идею @alephalpha, как и несколько других. нет встроенного факториала, который занимал бы по крайней мере 36 байтов (плюс работа с негативами). нет встроенного выбора, еще 16 байтов. iterator-> объявленный векторный тип, 20 байтов .. и т. д. и т. д.

Разрушенный на play.rust-lang.org


1
Есть лучший способ вычислить биномиальные коэффициенты для той же стоимости, но который позволяет удалить min: fn t(m:i64)->Vec<i64>{let b=|n,k|(1..=k).fold(1,|a,j|a*(n-j+1)/j);(0..20).map(|i|(0..=m).fold(0,|a,x|a+b(i,x))).collect()}(122 байта)
Питер Тейлор

1
Фактически, бином может быть встроенным: fn t(m:i64)->Vec<i64>{(0..20).map(|i|(0..=m).fold(0,|a,x|a+(1..=x).fold(1,|a,j|a*(i-j+1)/j))).collect()}(104 байта). Что было бы неплохо, так это объединить две складки, но я не уверен, насколько лаконичны кортежи.
Питер Тейлор

1
Достаточно кратко: fn t(m:i64)->Vec<i64>{(0..20).map(|i|(0..=m).fold((0,1),|a,b|(a.0+a.1,a.1*(b-i)/!b)).0).collect()}(98 байт)
Питер Тейлор

это удивительно ... я изо всех сил пытаюсь даже понять, как это работает, но это удивительно.
Дон

N!К!(N-К)!знак равноN!(К-1)!(N-(К-1))!×N-К+1К

1

R ( 60 59 байт)

function(n)Reduce(function(p,q)2*p-choose(q-1,n),1:19,1,,1)

Онлайн демо

Простая реализация наблюдения

T (n, k) = 2 T (n-1, k) - бином (n-1, k). - М. Ф. Хаслер, 30 мая 2010 г.

из OEIS A008949 . Аргументами Reduceявляются (очевидно) функция, массив для сопоставления, начальное значение, ложное значение (для сгибания слева, а не справа) и истинное значение для накопления промежуточных результатов в массиве.


1

К (ок) , 17 байт

-1 байт благодаря ngn (переключение с 0 на 1)

{x(+\1,19#)/20#1}

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

1-индексированных

K (ок) , 18 байт

{x(+\1,19#)/1+!20}

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

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


1
сделайте его 1 индексированным и сохраните байт: 1+!20->20#1
ngn

@ngn Спасибо, как всегда есть кое-что, что я пропустил :)
Гален Иванов




0

CJam (20 байтов)

1aK*{1\{1$+}/;]}q~*p

Демо онлайн . Это программа, которая принимает входные данные из stdin и печатает в stdout; за тот же счет анонимный блок (функция) может быть получен как

{1aK*{1\{1$+}/;]}@*}

рассечение

Это применяет определение буквально:

1aK*      e# Start with an array of 20 1s
{         e# Loop:
  1\      e#   Push a 1 before the current list
  {1$+}/  e#   Form partial sums (including that bonus 1)
  ;]      e#   Ditch the last and gather in an array (of length 20)
}
q~*       e# Take input and repeat the loop that many times
p         e# Pretty print
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.