Трикутник Паскаля (сортування)


24

Більшість усіх тут знайомі з трикутником Паскаля. Він утворений послідовними рядами, де кожен елемент є сумою двох верхньо-лівих та верхньо-правих сусідів. Ось перші 5рядки (запозичені з трикутника Паскаля ):

    1
   1 1
  1 2 1
 1 3 3 1
1 4 6 4 1
  . . .

Згорніть ці рядки зліва

1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
. . .

Сортуйте їх у порядку зростання

1
1 1
1 1 2
1 1 3 3
1 1 4 4 6
. . .

Прочитайте цей трикутник рядками

[1, 1, 1, 1, 1, 2, 1, 1, 3, 3, 1, 1, 4, 4, 6 ...]

З огляду на введення n, виведіть nчисло з цього ряду. Це OEIS 107430 .

Правила

  • Ви можете вибрати індексацію на основі 0 або 1. Будь ласка, вкажіть, хто у ваших поданнях.
  • Можна вважати, що вхід і вихід відповідають цілому цілому типу вашої мови.
  • Введення та вихід можуть бути надані будь-яким зручним методом .
  • Прийнятна або повна програма, або функція. Якщо функція, ви можете повернути вихід, а не надрукувати його.
  • Стандартні лазівки заборонені.
  • Це тому діють усі звичайні правила гольфу, і найкоротший код (у байтах) виграє.

6
Дуже приємний заголовок!
Луїс Мендо

1
Згідно з посиланням OEIS, єдине зміна, необхідне для створення цієї послідовності замість двочленного коефіцієнта, - це ціле ділення. Це звичайно підпадає під "тривіальне".
Пітер Тейлор

5
@PeterTaylor Це не схоже на явну дурність для мене. Існує багато інших можливих підходів, які можуть призвести до цікавих можливостей для гольфу, особливо для мов, які не мають вбудованого двочлену.
Арнольд

4
@PeterTaylor Я також не переконаний, що це дублікат. Поки відповіді MATL, JavaScript та Pascal досить різняться між двома проблемами. Однак, оскільки мій голос відкритий, я поки що не проголосую.
AdmBorkBork

4
Цілком погоджуюся з @AdmBorkBork. Тож вважайте мене за повторне голосування. Це робить 3 зараз. Скільки голосів потрібно для повторного відкриття?
Луїс Мендо

Відповіді:


9

JavaScript (ES6), 79 байт

0-індексований.

f=(n,a=[L=1])=>a[n]||f(n-L,[...a.map((v,i)=>k=(x=v)+~~a[i-1-i%2]),L++&1?k:2*x])

Демо

Як?

f = (                       // f = recursive function taking:
  n,                        //   n = target index
  a = [L = 1]               //   a[] = current row, L = length of current row
) =>                        //
  a[n] ||                   // if a[n] exists, stop recursion and return it
  f(                        // otherwise, do a recursive call to f() with:
    n - L,                  //   n minus the length of the current row
    [                       //   an array consisting of:
      ...a.map((v, i) =>    //     replace each entry v at position i in a[] with:
        k =                 //       a new entry k defined as:
        (x = v) +           //       v +
        ~~a[i - 1 - i % 2]  //       either the last or penultimate entry
      ),                    //     end of map()
      L++ & 1 ?             //     increment L; if L was odd:
        k                   //       append the last updated entry
      :                     //     else:
        2 * x               //       append twice the last original entry
    ]                       //   end of array update
  )                         // end of recursive call

Цей алгоритм безпосередньо генерує впорядковані рядки трикутника Паскаля. Він оновлюється n відповідно до довжини попереднього рядка, поки не існує [n] . Наприклад, для n = 19 потрібно 6 ітерацій :

 L | n  | a[]
---+----+------------------------
 1 | 19 | [ 1 ]
 2 | 18 | [ 1, 1 ]
 3 | 16 | [ 1, 1, 2 ]
 4 | 13 | [ 1, 1, 3, 3 ]
 5 |  9 | [ 1, 1, 4, 4, 6 ]
 6 |  4 | [ 1, 1, 5, 5, 10, 10 ]
                        ^^

Хороша робота. Я не впевнений, чи розумію, як саме це працює. Моя спроба виявилася набагато довшою, ніж ваша.
kamoroso94

@ kamoroso94 Я додав пояснення.
Арнольд

Мені це подобається! Дійсно отримав насолоду від з'ясування того, що це робить.
Кудлатий

6

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

@(n)(M=sort(spdiags(flip(pascal(n)))))(~~M)(n)

На основі 1.

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

Пояснення

Розглянемо n=4як приклад.

pascal(n) дає матрицю Паскаля:

 1     1     1     1
 1     2     3     4
 1     3     6    10
 1     4    10    20

Рядки трикутника Паскаля є антидіагоналями цієї матриці. Так воно перевертається вертикально за допомогоюflip(···)

 1     4    10    20
 1     3     6    10
 1     2     3     4
 1     1     1     1

що перетворює антидіагоналі в діагоналі.

spdiags(···) витягує (ненульові) діагоналі, починаючи з лівого нижнього кута, і розташовує їх як стовпчики з нульовими колонками:

 1     1     1     1     0     0     0
 0     1     2     3     4     0     0
 0     0     1     3     6    10     0
 0     0     0     1     4    10    20

M=sort(···)сортує кожен стовпець цієї матриці та присвоює результат змінній M:

 0     0     0     1     0     0     0
 0     0     1     1     4     0     0
 0     1     1     3     4    10     0
 1     1     2     3     6    10    20

Логічне індексування (···)(~~M)тепер використовується для вилучення ненулів цієї матриці в порядку основного стовпця (вниз, потім впоперек). Результат - вектор стовпця:

 1
 1
 1
 1
···
10
10
20

Нарешті, n-те введення цього вектора витягується за допомогою (···)(n), що в даному випадку дає 1.


5

Python 2 , 86 78 72 байт

-8 байт завдяки Роду

g=lambda n,r=[1]:r[n:]and r[n/2]or g(n-len(r),map(sum,zip([0]+r,r+[0])))

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

Безумовно

def g(n, row=[1]):
  if n < len(row):
    return row[n/2]
  else:
    next_row = map(sum, zip([0] + row, row + [0]))
    return g(n - len(row), next_row)

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

Функція рекурсивно обчислює рядок трикутника Паскаля. З огляду на поточну рядок , як row, map(sum, zip([0] + row, row + [0])).
При кожному виклику nзменшується на довжину поточного ряду. Якщо функція надходить у правий nthрядок, слід повернути найменше число рядка.
Оскільки перша половина рядка знаходиться у порядку зростання і кожен рядок є симетричним, число знаходиться в індексі n/2(0-індексований, ціле ділення).


4

Мова Вольфрама (Mathematica) , 55 байт

Індексація проводиться на основі 1.

(##&@@@Sort/@Table[n~Binomial~k,{n,0,#},{k,0,n}])[[#]]&

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

Пояснення

Це, мабуть, гольф, я не дуже досвідчений користувач Mathematica.

Table[n~Binomial~k,{n,0,#},{k,0,n}]

Для кожного n ∈ [0, Input] ∩ ℤ сгенеруйте таблицю біноміалів з кожним k ∈ [0, n] ∩ ℤ .

Sort/@

Сортування кожного. Використовує скорочення до Map[function,object]- function/@object.

(##&@@@...)[[#]]

Вирівняйте отриманий список і отримайте елемент, індекс якого в списку є вхідним.



3

R , 58 байт

function(n)(m=apply(outer(0:n,0:n,choose),1,sort))[m>0][n]

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

Обчислює n choose kдля кожногоn,k в [0,1,...,n]якості матриці, сортує рядки по зростанню (*), і видаляє нулі, а потім вибираєn й елемент.

(*) Це також перетворює їх у стовпці, але це краще, оскільки R зберігає матрицю як вектор стовпчиком, що дозволяє нам індексувати її безпосередньо, зберігаючи порядок.


3

Haskell , 143 132 125 123 байт

((p>>=s.h)!!)
p=[1]:map(\r->zipWith(+)(0:r)(r++[0]))p
h r=splitAt(div(length r)2)r
s(a,b)=reverse b!a
(h:t)!b=h:(b!t)
x!_=x

Перший рядок - це точкова функція, яка приймає індекс (на основі 0) і повертає відповідне число в послідовності. Спробуйте в Інтернеті!

Це моя перша в історії програма Haskell! Я впевнений, що це може стати набагато коротшим. Поради цінуються.

Збережено 2 байти завдяки німі

Безумовно

pascalRows = [1] : map (\row -> zipWith (+) (0:row) (row++[0])) pascalRows
halves row = splitAt (div (length row) 2) row
joinSorted (first, second) = interleave (reverse second) first
interleave [] _ = []
interleave longer shorter = (head longer) : (interleave shorter (tail longer))
f n = (concatMap (joinSorted.halves) pascalRows) !! n

Ви все ще маєте iфункцію s, яку перейменовано !, я думаю. Якщо ви використовуєте функцію інфіксне ви можете упустити ()навколо reverse b: s(a,b)=reverse b!a.
німі

@nimi Ах, дякую - я змінив його на TIO, але тут пропустив місце на коді. І спасибі за підказку в дужках.
DLosc

3

JavaScript, 57 байт

f=(i,r=1)=>i<r?i>1?f(i-2,--r)+f(i<r?i:r-1,r):1:f(i-r,r+1)

0-індексований.

Як це виходить:

Крок 0:

c=(i,r)=>i?r&&c(i-1,r-1)+c(i,r-1):1
f=(i,r=1)=>i<r?c(i>>1,r-1):f(i-r,r+1)

Цей код легко зрозуміти:

  • функція c обчислити формулу використання комбінації: C (n, k) = C (n-1, k) + C (n-1, k-1); або 1, якщо k == 0 або k == n
  • функція fспробуйте дізнатися номер рядка та індекс у рядку, а потім викликайте функцію c для отримання результату.

Крок 1:

c=(i,r)=>i>1?--r&&c(i-2,r)+c(i,r):1
f=(i,r=1)=>i<r?c(i,r):f(i-r,r+1)

На цьому кроці ми намагаємося змінити виклик функції, cдля c(i,r)якої вона робить так само, як параметр f.

Крок 2:

c=(i,r)=>i>1?--r&&c(i-2,r)+c(i<r?i:r-1,r):1
f=(i,r=1)=>i<r?c(i,r):f(i-r,r+1)

Ми перевіряємо, i<rчи використовується функція fчи функціяc . Ось чому ми маскуємо дотримуючись i<rпід час рекурсії функції c.

Крок 3:

f=(i,r=1)=>i<r?i>1?--r&&f(i-2,r)+f(i<r?i:r-1,r):1:f(i-r,r+1)

На цьому кроці ми об'єднуємо ці дві функції в одну.

Після ще трохи гольфу ми нарешті отримали відповідь, описану вище.


2

Желе , 13 байт

0rcþ`ZṢ€Ẏḟ0⁸ị

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

Використання алгоритму Діалога Уріеля.

1-індексований.

Пояснення:

0rcþ`ZṢ€Ẏḟ0⁸ị
0r            Return inclusive range from 0 to n
    `         Call this dyad with this argument on both sides
   þ           Outer product with this dyad
  c             Binomial coefficient
     Z        Zip
       €      Call this link on each element
      Ṣ        Sort
        Ẏ     Concatenate elements
         ḟ0   Remove 0s
           ⁸ị Take the nth element

Чи можете ви додати пояснення? Я не можу зрозуміти, що þтут робиться.
Кудлатий

1
@Shaggy Це зовнішній продукт, я додам пояснення.
Ерік Аутгольфер

2

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

Не використовується навіть масив. 0-індексований.

f=(n,i=0,g=x=>x?x*g(x-1):1)=>n>i?f(n-++i,i):g(i)/g(c=n>>1)/g(i-c)

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

Пояснення:

f=(n,i=0,                 )=>                                     // Main Function
         g=x=>x?x*g(x-1):1                                        // Helper (Factorial)
                             n>i?                                 // Is n > i?
                                 f(n-++i,i):                      // If so, call function
                                                                  // f(n-i-1, i+1) to skip
                                                                  // . i+1 terms
                                            g(i)/g(c=n>>1)/g(i-c) // If not, since sorting 
                                                                  // . the binomial coeffs
                                                                  // . equals to writing
                                                                  // . the first floor(i/2)
                                                                  // . coefficients twice
                                                                  // . each, so a shortcut

1

Паскаль , 373 байт

function t(n,k,r:integer):integer;begin if(n<k)then t:=r-1 else t:=t(n,k+r,r+1)end;
function s(n,k:integer):integer;begin if(k=0)then s:=n else s:=s(n+k,k-1)end;
function f(n,k:integer):integer;begin if((k<1)or(k>n))then f:=0 else if n=1 then f:=1 else f:=f(n-1,k-1)+f(n-1,k)end;
function g(n:integer):integer;var k:integer;begin k:=t(n,0,1);g:=f(k,(n-s(0,k-1)+2)div 2)end;

g є функцією.

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


n=1 thenможе бути n=1then.
Джонатан Фрех

SImilarly, схоже, це if(k=0)thenможе стати if k=0then.
Кудлатий

якщо деяка кількість завжди більше 0, слід використовувати wordзамість integer.
тш

1

Java 8, 187 байт

n->{int r=~-(int)Math.sqrt(8*n+1)/2+1,a[]=new int[r],k=r,x=0;for(;k-->0;a[k]=p(r,k))x+=k;java.util.Arrays.sort(a);return a[n-x];}int p(int r,int k){return--r<1|k<2|k>r?1:p(r,k-1)+p(r,k);}

Пояснення:

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

n->{                   // Method with integer as both parameter and return-type
  int r=~-(int)Math.sqrt(8*n+1)/2+1,
                       //  Calculate the 1-indexed row based on the input
      a[]=new int[r],  //  Create an array with items equal to the current row
      k=r,             //  Index integer
      x=0;             //  Correction integer
  for(;k-->0;          //  Loop down to 0
    a[k]=p(r,k))       //   Fill the array with the Pascal's Triangle numbers of the row
    x+=k;              //   Create the correction integer
  java.util.Arrays.sort(a);
                       //  Sort the array
  return a[n-x];}      //  Return the `n-x`'th (0-indexed) item in this sorted array

// Separated recursive method to get the k'th value of the r'th row in the Pascal Triangle
int p(int r,int k){return--r<1|k<2|k>r?1:p(r,k-1)+p(r,k);}

1

MATL , 11 байт

:qt!XnSXzG)

На основі 1.

Спробуйте в Інтернеті! Або перевірити всі тестові випадки .

Пояснення

Розглянемо вклад 4як приклад. ;- роздільник рядків для матриць або векторів стовпців.

:     % Implicit input: n. Push the row vector [1 2 ... n]          
      S STACK: [1 2 3 4]
q     % Subtract 1, emlement-wise: gives [0 1 ... n-1]
      % STACK: [0 1 2 3]
t!    % Duplicate and transpose into a column vector
      % STACK: [0 1 2 3], [0; 1; 2; 3]
Xn    % Binomial coefficient, element-wise with broadcast. Gives an
      % n×n matrix where entry (i,j) is binomial(i,j), or 0 for i<j
      % STACK: [1 1 1 1;
                0 1 2 3;
                0 0 1 3;
                0 0 0 1]
S     % Sort each column
      % STACK: [0 0 0 1;
      %         0 0 1 1;
      %         0 1 1 3;
      %         1 1 2 3]
Xz    % Keep only nonzeros. Gives a column vector
      % STACK: [1; 1; 1; 1; 1; 2; 1; 1; 3; 3]
G)    % Get the n-th element. Implicitly display
      % STACK: 1

1

Пакетна, 128 байт

@set/as=2,t=r=m=i=1
:l
@if %1 geq %t% set/as+=r,t+=r+=1&goto l
@for /l %%i in (%s%,2,%1)do @set/ar-=1,m=m*r/i,i+=1
@echo %m%

0-індексований.


Чи можете ви додати пояснення, будь ласка? Я не можу повністю слідувати логіці.
AdmBorkBork

@AdmBorkBork Перші три рядки обчислити рядок rі стовпець %1-(s-2)з %1ї серії. Потім четвертий рядок використовує це для обчислення біноміального коефіцієнта (n k) = n!/(n-k)!k!= n(n-1)...(n+1-k)/(1)(2)...k= (n/1)((n-1)/2)...((n+1-k)/k). Де MathJax, коли мені це потрібно?
Ніл

1

APL (Dyalog Classic) , 17 байт

⎕⊃∊i!⍨,\⌊.5×i←⍳99

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

Індексація на основі 0

зауважимо, що (49!98) > 2*53, тобто коефіцієнт біноміна 98 над 49 перевищує 2 53 , тож у цей момент Діялог вже почав втрачати точність через плаваючу точку IEEE


@Abigail дивіться тут і тут
ngn


1

Желе , 11 байт

Ḷc€`Ṣ€Fḟ0ị@

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

Монадійне посилання, що приймає індекс і повертає ціле число - використовує індексацію на основі 1.

Як?

Виконує виклик так само, як написано, лише з більшою правою частиною трикутника Паскаля (нулі), який потім викидається ...

Ḷc€`Ṣ€Fḟ0ị@ - Link: integer, i    e.g. 1   or    9
Ḷ           - lowered range            [0]       [0,1,2,3,4,5,6,7,8]
   `        - repeat left as right arg [0]       [0,1,2,3,4,5,6,7,8]
 c€         - binomial choice for €ach [[1]]     [[1,0,0,0,0,0,0,0,0],[1,1,0,0,0,0,0,0,0],[1,2,1,0,0,0,0,0,0],[1,3,3,1,0,0,0,0,0],[1,4,6,4,1,0,0,0,0],[1,5,10,10,5,1,0,0,0],[1,6,15,20,15,6,1,0,0],[1,7,21,35,35,21,7,1,0],[1,8,28,56,70,56,28,8,1]]
    Ṣ€      - sort €ach                [[1]]     [[0,0,0,0,0,0,0,0,1],[0,0,0,0,0,0,0,1,1],[0,0,0,0,0,0,1,1,2],[0,0,0,0,0,1,1,3,3],[0,0,0,0,1,1,4,4,6],[0,0,0,1,1,5,5,10,10],[0,0,1,1,6,6,15,15,20],[0,1,1,7,7,21,21,35,35],[1,1,8,8,28,28,56,56,70]]
      F     - flatten                  [1]       [0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,2,0,0,0,0,0,1,1,3,3,0,0,0,0,1,1,4,4,6,0,0,0,1,1,5,5,10,10,0,0,1,1,6,6,15,15,20,0,1,1,7,7,21,21,35,35,1,1,8,8,28,28,56,56,70]
       ḟ0   - filter discard zeros     [1]       [1,1,1,1,1,2,1,1,3,3,1,1,4,4,6,1,1,5,5,111,1,6,6,15,15,21,1,7,7,21,21,35,35,1,1,8,8,28,28,56,56,70]
         ị@ - index into (sw@p args)    1         3 --------------^

1

Червоний , 206 байт

f: func[n][t: copy[[1]]l: 0
while[l < n][a: copy last t insert append a 0 0 b: copy[]repeat i k:(length? a)- 1[append b a/(i) + a/(i + 1)]append t reduce[b]l: l + k]foreach p t[sort p]pick split form t{ }n]

На основі 1

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

Пояснення:

f: func [n] [
    t: copy [[1]]                       ; start with a list with one sublist [1]
    l: 0                                ; there are 1 items overall
    while [l < n] [                     ; while the number of items is less than the argument
        a: copy last t                  ; take the last sublist 
        insert append a 0 0             ; prepend and append 0 to it  
        b: copy []                      ; prepare a list for the sums  
        repeat i k: (length? a) - 1 [   ; loop throught the elements of the list
            append b a/(i) + a/(i + 1)] ; and find the sum of the adjacent items
        append t reduce [b]             ; append the resulting list to the total list
        l: l + k                        ; update the number of the items
    ]
    foreach p t [sort p]                ; sort each sublist
    v: pick split form t { } n          ; flatten the list and take the n-th element
]

1

Perl, 48 байт

Включає +1дляp

perl -pe '$_-=$%until$_<++$%;$./=$_/--$%for 1..$_/2;$_=$.' <<< 19

Використовує базу 0 індексування.


1

J, 46 41 байт

f=:](([-2!]){/:~@(i.!<:)@])[:<.2&!@,:^:_1

0-індексований

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

Примітки:

  • <.2&!@,:^:_1дає відповідне число рядка трикутника Паскаля шляхом округлення вниз оберну y choose 2.
  • /:~@(i.!<:)@] обчислює рядок і сортує його.
  • [-2!] дає індекс у рядок.

Привіт. Ласкаво просимо на сайт! Це хороша перша відповідь :)
DJMcMayhem



0

Pyth, 15 байт

@u+GSm.cHdhHhQY

0-індексований

Спробуй це

Пояснення

@u+GSm.cHdhHhQY
 u          hQY   Reduce on [0, ..., input], starting with the empty list...
  +G              ... append to the accumulator...
    Sm.cHdhH      ... the sorted binomial coefficients.
@              Q  Take the 0-indexed element.


0

Рубін , 56 байт

->n{a=0;n-=a until n<a+=1;[*2..a].combination(n/2).size}

На основі 0

Спочатку знайдіть рядок і стовпець у трикутнику, потім обчисліть біноміальний коефіцієнт, відповідний цьому положенню.

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


0

Власне , 8 байт

В основному на основі відповіді Джонатана Аллана Желе . Використовує 0-індексацію.

;r♂╣♂SΣE

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

Ungolfing

          Implicit input n.
;         Duplicate n.
 r        Lowered range. [0..n-1].
  ♂╣      Pascal's triangle row of every number.
    ♂S    Sort every row.
      Σ   Sum each row into one array.
       E  Get the n-th element of the array (0-indexed).
          Implicit return.

Він повинен створити єдине число; n- й у серії. Це створює масив.
рекурсивний

Уопс. Виправлено. Дякую @recursive
Sherlock9



Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.