Зейдель Треугольник

14

Треугольник Зейделя - это математическая конструкция, похожая на треугольник Паскаля, и известная своей связью с числами Бернулли.

Первые несколько строк:

      1
      1  1
   2  2  1
   2  4  5  5
16 16 14 10 5
16 32 46 56 61 61

Каждая строка генерируется следующим образом:

Если номер строки четный (1-индексированный):

  • Сбить первый элемент предыдущего ряда

  • Каждый следующий элемент является суммой предыдущего элемента и элемента над ним

  • Дублировать последний элемент

Если номер строки нечетный:

  • Сбить последний элемент предыдущего ряда

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

  • Дублируйте то, что сейчас является первым предметом.

По сути, мы строим треугольник в виде зигзага:

    1
    v
    1 > 1
        v
2 < 2 < 1
v
2 > 4 > 5 > 5

Для получения дополнительной информации см. Страницу Википедии о числах Бернулли.

Соревнование:

Если nв качестве аргумента функции или из STDIN, выведите или вернете либо т- nю строку треугольника Зейделя, либо первые nстроки. Вы можете использовать либо 0, либо 1 индексирование.

Вам не нужно обрабатывать отрицательный или нецелочисленный ввод (ни 0, если индексирован 1). Вам не нужно обрабатывать выходы больше2147483647 = 2^31 - 1

Поскольку это код-гольф, делайте это как можно меньше байтов.

Примеры:

В этих примерах возвращаемое значение является nстрокой с 0 индексами.

Input   ->  Output

0           1
1           1 1
2           2 2 1
6           272 272 256 224 178 122 61
13          22368256 44736512 66750976 88057856 108311296 127181312 144361456 159575936 172585936 183194912 191252686 196658216 199360981 199360981
Bolce Bussiere
источник
«Вам не нужно обрабатывать выходные данные, превышающие тип int по умолчанию для вашего языка», что делает это тривиальным для языков с только 1-битными целочисленными значениями
только для ASCII
Могут ли строки выводиться всегда отсортированы от малого к большому?
Анг
@ ASCII-only Изменено в соответствии с максимальным значением C ++
Bolce Bussiere
@Angs Нет, строки должны быть упорядочены, как показано
Bolce Bussiere
@ ASCII-only Это лазейка по умолчанию (хотя IMO это немного плохо сформулировано, поскольку это зависит от того, что люди считают «разумным»)
user202729

Ответы:

7

Brain-Flak , 66 байт

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

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

Строка имеет индекс 0.

# Push 1 (the contents of row 0) on other stack; use implicit zero as parity of current row
<>(())<>

# Do a number of times equal to input:
{({}[()]<

  # Subtract the row parity from 1
  (()[{}]<

    # For each entry in old row:
    <>{

      # Add to previous entry in new row and push twice
      (({}<>{}))<>

    }

  >)

>)}{}

# If row parity is odd:
{{}

  # Reverse stack for output
  <>{({}<>)<>}

# Switch stacks for output
}<>
Nitrodon
источник
4

JavaScript (SpiderMonkey) , 67 байт

Этот код злоупотребляет sort()методом и работает не на всех движках.

Строки нумерованы.

f=(n,a=[1],r)=>n--?f(n,[...a.map(n=>k+=n,k=0),k].sort(_=>n|r),!r):a

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

Как?

Мы условно обращаем массив, используя sort()метод с функцией обратного вызова, которая игнорирует его параметры и возвращает либо 0, либо положительное целое число. Не пытайтесь сделать это дома! Это надежно работает только на SpiderMonkey.

let A = [1,2,3,4,5] and B = [1,2,3,4,5,6,7,8,9,10,11]

             | SpiderMonkey (Firefox)  | V8 (Chrome)             | Chakra (Edge)
-------------+-------------------------+-------------------------+------------------------
A.sort(_=>0) | 1,2,3,4,5               | 1,2,3,4,5               | 1,2,3,4,5
A.sort(_=>1) | 5,4,3,2,1               | 5,4,3,2,1               | 1,2,3,4,5
B.sort(_=>0) | 1,2,3,4,5,6,7,8,9,10,11 | 6,1,3,4,5,2,7,8,9,10,11 | 1,2,3,4,5,6,7,8,9,10,11
B.sort(_=>1) | 11,10,9,8,7,6,5,4,3,2,1 | 6,11,1,10,9,8,7,2,5,4,3 | 1,2,3,4,5,6,7,8,9,10,11

Обратите внимание, что V8, вероятно, использует разные алгоритмы сортировки в зависимости от длины массива (менее или более 10 элементов).

комментарии

f = (                     // f = recursive function taking:
  n,                      //   n   = row counter
  a = [1],                //   a[] = current row, initialized to [1]
  r                       //   r   = 'reverse' flag, initially undefined
) =>                      //
  n-- ?                   // decrement n; if it was not equal to zero:
    f(                    //   do a recursive call with:
      n,                  //     - the updated value of n
      [ ...a.map(n =>     //     - a new array:
          k += n, k = 0   //       - made of the cumulative sum of a[]
        ), k              //         with the last value appended twice
      ].sort(_ => n | r), //       - reversed if n is not equal to 0 or r is set
      !r                  //     - the updated flag r
    )                     //   end of recursive call
  :                       // else:
    a                     //   stop recursion and return a[]
Arnauld
источник
Какую особенность паука-обезьяны это использует?
Вниз,
@Downgoat Использует преимущества конкретной реализации sort()этого движка. Я добавил объяснение.
Арно
3

Haskell , 89 87 82 байта

(cycle[r,id]!!)<*>s
r=reverse
s 0=[1]
s n=let a=zipWith(+)(0:a)$(r.s$n-1)++[0]in a

Только s печатает строки в зигзагообразном порядке, анонимная функция в первой строке переворачивает половину строк.

Спасибо @nimi за сохранение 5 байтов!

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

Angs
источник
2

Python 3 , 98 91 байт

from itertools import*
f=lambda n:n and[*accumulate(f(n-1)[::n&1or-1]+[0])][::n&1or-1]or[1]

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

Переключение на нумерацию строк на основе 0 сэкономило 7 байтов.

RootTwo
источник
2

Юлия 0,6 , 85 байт

r(l,n=cumsum(l))=[n...,n[end]]
w=reverse
f(n)=n<2?[1]:n%2<1?r(f(n-1)):w(r(w(f(n-1))))

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

Это рекурсивное решение в Юлии. Обратите внимание, что он имеет индексирование на основе 1. Отсюда и тесты.

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

function new_row(last_row)
    new_row = cumsum(last_row)
    push!(new_row, new_row[end])
    return new_row
end


function triangle(n)
    if n == 1
        return [1]
    elseif mod(n,2) == 0
        return new_row(triangle(n-1))
    else
        return reverse(new_row(reverse(triangle(n-1))))
    end
end

Как бонус, вот нерекурсивная версия, но она длиннее:

w=reverse;c=cumsum
r(l,i)=i%2<1?c([l...,0]):w(c(w([0,l...])))
f(n,l=[1])=(for i=2:n l=r(l,i)end;l)
niczky12
источник