Ромб Паскаля


20

Ромб Паскаля (який насправді є трикутником) отримується додаванням у візерунок:

  *
 ***
  x

замість

* *
 x

Це означає, що кожна комірка - це сума трьох комірок рядка безпосередньо над нею та однієї комірки ряду 2 над нею. Так само, як і трикутник Паскаля, у нульовому ряду на ньому є одиничний, 1який генерує трикутник.

Ось перша пара рядків Ромба Паскаля

      1
    1 1 1
  1 2 4 2 1
1 3 8 9 8 3 1

Завдання

З огляду на номер рядка (починаючи з верхнього) та номер стовпця (починаючи з першого ненульового елемента в цьому рядку) виводить значення у цій конкретній комірці. Обидва входи можуть бути індексованими як 1, так і 0 (ви можете змішувати та поєднувати, якщо хочете).

Це тому ви повинні прагнути зробити розмір файлу вихідного коду якомога меншим.

OEIS A059317



ви повинні прагнути зробити розмір файлу вашого вихідного коду якомога меншим, що робити, якщо я ставлю свій код як аргумент командного рядка? : P
Ерік Вигнавець

Пішов гугл на ярлики і, мабуть, arxiv.org/abs/1504.04404 говорить, що підрахунок результату безпосередньо не корисний для гольфу з кодом.
JollyJoker

Відповіді:


12

Haskell , 59 55 байт

Ромб Паскаля? Більше схожий на Ромб Haskell! я правий?

4 байти збережено завдяки Ørjan Johansen

Я думав, що я спробую зіткнутися зі своєю власною проблемою і практикувати свій Haskell. Сподіваємось, це надихне більше людей відповісти на це.

1!1=1
n!k=sum[(n-2)!(k-2)+sum(map((n-1)!)[k-2..k])|n>1]

Спробуйте в Інтернеті!

Пояснення

Це трохи застаріло з останнім гольфом

Замість розрахунку

  *
 ***
  x

Розраховуємо

*
***
  x

Це нахиляє весь наш трикутник, щоб стати

1
1 1 1
1 2 4 2 1
1 3 8 9 8 3 1

Це вирівнює всі наші рядки, що полегшує індексацію n-го пункту будь-якого стовпця. Потім ми визначаємо наші базові випадки.

Нульовий ряд - це всі нулі так

0!_=0

Є 1позиція сингла, 1,1тому ми визначимо це

1!1=1

А решту першого ряду ми визначаємо також як нулі

1!_=0

Потім визначаємо загальний випадок рекурсивно, використовуючи описаний вище шаблон:

n!k=(n-2)!(k-2)+(sum$map((n-1)!)[k-2..k])

Бий мене до цього! Це також набагато чистіше, ніж у мене.
Джуліан Вольф

@JulianWolf Вибачте за це, коли я опублікував це, схоже, що ніхто, крім Йорга, не робив проблеми. Я все одно хотів би бачити ваше рішення.
Пшеничний майстер

1
Ви можете зберегти чотири байти за допомогою n!k=sum[(n-2)!(k-2)+sum(map((n-1)!)[k-2..k])|n>1].
Ørjan Johansen

10

Паскаль , 122 байти

Ну, це ром Паскаля .

37 байт збережено завдяки @manatwork

function f(n,k:integer):integer;begin f:=1-Ord((k<0)or(k>n*2));if n>0then f:=f(n-1,k-2)+f(n-1,k-1)+f(n-1,k)+f(n-2,k-2)end;

Спробуйте в Інтернеті!


Парентези навколо всієї ifумови безглузді. (На 1-му ifви зберігаєте 2 символи, на другому - if1 символ, не залишаючи пробілу між thenключовим словом та попередньою цифрою.) О, змінна r абсолютно непотрібна.
манатура

Дивна тварина, що Паскаль на Ідеоне. Ніколи не бачив подвійних цитат з обмеженими рядками в жодному варіанті Pascal. Ще одна річ , яку ви можете видалити: ;до function«з end.
манатура

@manatwork так, тепер, коли ви це згадали, всі інші редактори в Інтернеті скаржилися на це
Uriel

@manatwork Я не впевнений, що зрозумів. хіба що просто подовжити код за допомогою >= <=? Мені ще потрібно зберегтиif n=0
Уріель

Вибачте @Uriel, у мене вже немає такої версії. На даний момент я function f(n,k:integer):integer;begin f:=1-Ord((k<0)or(k>n*2));if n>0then f:=f(n-1,k-2)+f(n-1,k-1)+f(n-1,k)+f(n-2,k-2)end;
завітаю

7

PHP , 86 байт

рекурсивним чином лише функціональний рядок і стовпець 0-індексований

function f($r,$c){return$r|$c?$r<0?0:f($r-=1,$c)+f($r,$c-1)+f($r,$c-=2)+f($r-1,$c):1;}

Спробуйте в Інтернеті!

PHP , 114 байт

рекурсивний спосіб повного рядка програми та стовпця 0-індексовано

<?=f(...$_GET);function f($r,$c){return$r|$c?$r<0|$c<0|$c>2*$r?0:f($r-=1,$c)+f($r,$c-1)+f($r,$c-=2)+f($r-1,$c):1;}

Спробуйте в Інтернеті!

PHP , 129 байт

рядок і стовпчик 0-індексовано

for(;$r<=$argv[1];$l=$t[+$r++])for($c=~0;$c++<$r*2;)$t[+$r][$c]=$r|$c?$t[$r-2][$c-2]+$l[$c]+$l[$c-1]+$l[$c-2]:1;echo$l[$argv[2]];

Спробуйте в Інтернеті!


та +1 за те, що насправді покращує його :)
Уріель


3

MATL , 22 20 19 байт

Ti:"2Y6Y+FT_Y)]!i_)

Обидва входи засновані на 0.

Спробуйте в Інтернеті!

Пояснення

Нехай rі cпозначають два входи із зазначенням рядка та стовпця на основі 0.

Кожен новий рядок у ромба Паскаля може бути побудований з матриці, що містить попередні два ряди, з'єднавшись з ядром [1 1 1; 0 1 0]і зберігаючи два останні ряди результату. Це робиться rразів, починаючи з матриці 1.

Виявляється, коротше використовувати ядро [0 1 0; 1 1 1; 0 1 0], яке є заздалегідь заданим літералом. Це створить додатковий рядок, який буде відкинутий.

Розглянемо для прикладу r = 3, тому є 3ітерації.

  1. Починаючи з

    1
    

    згортання з [0 1 0; 1 1 1; 0 1 0]дає

    0 1 0
    1 1 1
    0 1 0
    

    Зберігання останніх двох рядків (вся матриця, в даному випадку) та заміна їх дає

    0 1 0
    1 1 1
    
  2. Згортання вище [0 1 0; 1 1 1; 0 1 0]дає

    0 0 1 0 0
    0 1 1 1 0
    1 2 4 2 1
    0 1 1 1 0
    

    Матриця, утворена двома останніми рядками, що помінялася, є

    0 1 1 1 0
    1 2 4 2 1
    

    Він містить новий рядок внизу, а попередній розширений нулями.

  3. Повторне залучення врожайності

    0 0 1 1 1 0 0
    0 1 2 3 2 1 0
    1 3 8 9 8 3 1
    0 1 2 4 2 1 0
    

    Прийняття останніх двох рядків замінено дає

    0 1 2 4 2 1 0
    1 3 8 9 8 3 1
    

Після завершення rітерацій висновок міститься в останньому рядку підсумкової матриці. Наприклад, для c = 2(на основі 0) результат був би 8. Замість індексації останнього рядка та потрібного стовпця може бути використаний трюк, який використовує симетрію кожного рядка: остаточну матрицю переносять

0 1
1 3
2 8
4 9
2 8
1 3
0 1

і -cбереться його -й елемент. При цьому використовується лінійна індексація, тобто матриця індексується одним індексом у стовпчиковому порядку. Оскільки індексація є модульною , 0-entry - це нижній правий кут (значення 1), а -2-та запис - на два кроки вище (значення 8).

T       % Push true
i       % Input row number
:"      % Do the following that many times
  2Y6   %   Push predefined literal [0 1 0; 1 1 1; 0 1 0]
  Y+    %   2D convolution, increasing size
  FT_   %   Push [0 -1]
  Y)    %   Matrix with rows 0 (last) and -1 (second-last), in that order
]       % End
!       % Transpose
i       % Input: colun number
_       % Negate
)       % Entry with that index. Implicitly display



2

Математика, 56 байт

If[#<1,Boole[##==0],Sum[#0[#-i,#2-j],{i,2},{j,2i-2,2}]]&

Чиста функція, приймаючи два цілих аргументи (перший рядок, другий стовпець) і повертає ціле число. Працює і для негативних цілих аргументів, повертаючись 0. Досить прямолінійна рекурсивна структура: If[#<1,Boole[##==0],...]визначає поведінку базового випадку для 0-го ряду (і вище), в той час як Sum[#0[#-i,#2-j],{i,2},{j,2i-2,2}]реалізує рекурсивне визначення.



1

JavaScript (ES6), 68 байт

f=(y,x)=>x<0|x>y+y?0:x>0&x<y+y?f(--y,x)+f(y,--x)+f(y,--x)+f(--y,x):1

1

Математика, 53 байти

D[1/(1-x(1+y+y^2(1+x))),{x,#},{y,#2}]/#!/#2!/.x|y->0&

Використання функції генерації.


0

Python 3 , 82 84 байт

Це рекурсивна реалізація з 1-індексованими рядками та стовпцями. (Технічно потрібен f=фронт, хтось дасть мені знати, чи варто змінити його на 84 байти. Ще новий і не на 100% впевнений у правилах.)

Для цього використовується рекурсивна формула, знайдена на сторінці OEIS , але з рухомk вліво, щоб правильно вирівнятися. Випадково, sum(f(n-1,k-i)for i in(0,1,2))такий же розмір, як f(n-1,k)+f(n-1,k-1)+f(n-1,k-2). Вся функція - and orфокус Python , де перша умова перевіряє, чи k знаходиться всередині трикутника, а не на межі, і в цьому випадку використовується рекурсивна формула. Якщо ні, то частина після orповертається, яка перевіряє, чи kзнаходиться (1, 2*n-1), тобто на межі, повертається Trueі False. k+1in(2,2*n)на один байт коротший за k in(1,2*n-1). Обгортання, що в дужках і поставлення +фронту перетворюється на ціле число, що і потрібно.

f=lambda n,k:2*n-1>k>1and sum(f(n-1,k-i)for i in(0,1,2))+f(n-2,k-2)or+(k+1in(2,2*n))

Спробуйте в Інтернеті!


Рекурсивні функції потрібні f=.
Пшеничний майстер

Хоча я особисто не згоден з цим відповідно до цього дещо закопаного мета-консенсусу, ви можете вийти Trueзамість того, 1що він поводиться як 1пітон. Це дозволяє видалити +(...)в кінці. Я розумію, якщо ви не хочете цього робити, тому що це зробить висновок дещо дивним, це варіант.
Пшеничний майстер

@WheatWizard Вау, це дуже цікаво. Дякую за пораду.
C McAvoy


0

Пітон 3 , 75 байт

Це рекурсивна лямбда, яка приймає стовпчик і рядок як цілі числа, що індексуються 0.

p=lambda r,c:(r<0 or((c==0)|p(r-1,c-2)+p(r-1,c)+p(r-1,c-1)+p(r-2,c-2))+1)-1

Ось (трохи) більш читана версія з функцією друку:

p = lambda r,c:(r<0 or ((c==0) | p(r-1,c-2)+p(r-1,c)+p(r-1,c-1)+p(r-2,c-2))+1)-1

def pp(r):
    ml = len(str(p(r,r)))+1
    for i in range(0, r):
            a=" "*ml*(r-i)
            for j in range(0,i*2 + 1):
                    a+=str(p(i,j))+(" "*(ml-len(str(p(i,j)))))
            print(a)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.