Pascal Üçgeni (Sırala)


24

Buradaki herkes Pascal'ın Üçgeni'ne aşina. Her elemanın iki sol üst ve sağ üst komşusunun toplamı olduğu art arda sıralardan oluşur. İşte ilk 5satırlar ( Generate Pascal'ın üçgeninden alınmış ):

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

Bu satırları sola doğru daralt

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

Onları artan sırada sırala

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

Bu üçgeni satırlarla okuyun

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

Bir giriş Verilen nçıktı, nbu seride inci numarası. Bu OEIS 107430 .

kurallar

  • 0- veya 1 tabanlı dizinlemeyi seçebilirsiniz. Lütfen gönderiminizde hangisi olduğunu belirtiniz.
  • Giriş ve çıktının, dilinizin yerel tamsayı tipine uyduğu varsayılabilir.
  • Giriş ve çıkış herhangi bir uygun yöntemle verilebilir .
  • Tam bir program veya bir işlev kabul edilebilir. Bir işlev varsa, çıktıyı yazdırmak yerine geri gönderebilirsiniz.
  • Standart boşluklar yasaktır.
  • Bu olduğundan, tüm normal golf kuralları geçerlidir ve en kısa kod (bayt cinsinden) kazanır.

6
Çok güzel başlık!
Luis Mendo

1
OEIS bağlantısına göre, binom katsayısı yerine bu sekansı oluşturmak için gereken tek değişiklik bir tamsayı bölmesidir. Bu kesinlikle "önemsiz" altına düşer.
Peter Taylor

5
@PeterTaylor Bu bana açık bir cinayet gibi görünmüyor. Özellikle binom özelliği olmayan diller için ilginç golf fırsatlarına yol açabilecek birçok başka yaklaşım vardır.
Arnauld,

4
@PeterTaylor Bu ikisinin de bir kopyası olduğuna ikna olmadım. Şimdiye kadar MATL, JavaScript ve Pascal cevapları iki zorluk arasında oldukça farklı. Ancak oyum açık bir oy olduğundan, henüz oy kullanmayacağım.
AdmBorkBork

4
@AdmBorkBork ile tamamen aynı fikirdeyim. Bu yüzden beni tekrar oylama olarak say. Bu şimdi 3 yapar. Yeniden açmak için kaç oy gereklidir?
Luis Mendo

Yanıtlar:


9

JavaScript (ES6), 79 bayt

0 endeksli.

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])

gösteri

Nasıl?

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

Bu algoritma doğrudan Pascal Üçgeninin sıralanmış sıralarını oluşturur. Bu günceller , n kadar bir önceki satıra uzunluğuna göre bir [n] bulunmaktadır. Örneğin, n = 19 için 6 yineleme gerekir :

 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 ]
                        ^^

İyi iş. Nasıl çalıştığını tam olarak anladığımdan emin değilim. Benim girişimim sizinkinden daha uzun sürdü.
kamoroso94

@ kamoroso94 Bir açıklama ekledim.
Arnauld,

Bunu seviyorum! Ne yaptığını bulmaktan gerçekten zevk aldım.
Shaggy

6

Oktav , 46 bayt

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

1 tabanlı.

Çevrimiçi deneyin!

açıklama

n=4Örnek olarak düşünün .

pascal(n) Pascal matrisi verir:

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

Pascal üçgeninin satırları bu matrisin antidiagonalleridir. Bu yüzden dikey kullanarak döndürülürflip(···)

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

bu, antidiagonalleri köşegenlere dönüştürür.

spdiags(···) soldan başlayarak (sıfır olmayan) köşegenleri ayıklar ve bunları sıfır dolgulu sütunlar olarak düzenler:

 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(···)bu matrisin her sütununu sıralar ve sonucu değişkene atar 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

Mantıksal indeksleme (···)(~~M)şimdi bu matrisin sıfır olmayan değerlerini sütun ana düzeninde çıkarmak için kullanılır. Sonuç, bir sütun vektörüdür:

 1
 1
 1
 1
···
10
10
20

Son olarak, nbu vektörün -inci girişi, (···)(n)bu durumda, hangi kullanılarak verilir 1.


5

Python 2 , 86 78 72 bayt

Rod sayesinde -8 bayt

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

Çevrimiçi deneyin!

Ungolfed

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)

Çevrimiçi deneyin!

Fonksiyon, tekrar tekrar Pascal Üçgeni satırını hesaplar. Olarak geçerli satır önüne alındığında row, map(sum, zip([0] + row, row + [0])).
Her aramada ngeçerli satırın uzunluğu azalır. Eğer fonksiyon sağ satıra ulaşırsa, sıranın en nthdüşük sayısı iade edilmelidir.
Bir satırın ilk yarısı artan sırada olduğundan ve her satır simetrik olduğundan, sayı indeksindedir n/2(0 indeksli, tam sayı bölümü).


4

Wolfram Dili (Mathematica) , 55 bayt

Endeksleme 1 tabanlıdır.

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

Çevrimiçi deneyin!

açıklama

Bu muhtemelen golf oynamaktadır, çok deneyimli bir Mathematica kullanıcısı değilim.

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

Her n ∈ [0, Giriş] ∩ ℤ için , her k with [0, n] ∩ with ile binom tablosunu oluşturun .

Sort/@

Her birini sırala. Map[function,object]- için bir steno kullanır function/@object.

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

Sonuçta ortaya çıkan listeyi düzleştirin ve listedeki dizini giriş olan öğeyi alın.



3

R , 58 bayt

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

Çevrimiçi deneyin!

Hesaplar n choose kher biri için n,kde [0,1,...,n]bir matris olarak, daha sonra seçer, sıralar (*) artan sıralar ve sıfır kaldırır nelemanından.

(*) Bu aynı zamanda onları sütunlara dönüştürür ancak bu daha iyi olur çünkü R bir matrisi sütun yönünde bir vektör olarak saklar, bu da sırayı korurken doğrudan içine indekslememizi sağlar.


3

Haskell , 143 132 125 123 bayt

((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

İlk satır, bir dizini (0 tabanlı) alan ve dizideki uygun sayıyı döndüren noktasuz bir işlevdir. Çevrimiçi deneyin!

Bu benim ilk Haskell programım! Eminim çok daha kısa olabilir. İpuçları takdir edilir.

Nimi sayesinde 2 bayt kaydedildi

Ungolfed

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

Sanırım , ismini değiştiren hala iişlevin var . Bir infix işlevini kullanıyorsanız, bırakın etrafta : . s!()reverse bs(a,b)=reverse b!a
nimi

@nimi Ah, teşekkürler - TIO'da değiştirdim ancak koddaki bir noktayı kaçırdım. Ve parantez ucu için teşekkürler.
DLosc

3

JavaScript, 57 bayt

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 endeksli.

Bu nasıl geliyor:

Adım 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)

Bu kodun anlaşılması kolaydır:

  • fonksiyon c Kombinasyon kullanım formülünü hesaplar: C (n, k) = C (n-1, k) + C (n-1, k-1); veya eğer k == 0 veya k == n ise
  • işlevi fsatırdaki satır numarasını ve dizini bulmaya çalışın ve sonucu almak için c işlevini çağırın.

Aşama 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)

Bu adımda, biz fonksiyonun çağrısı değiştirmeye çalışırsanız ciçin c(i,r)bir parametre olarak aynı olarak yapar f.

Adım 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İşlev fveya işlev kullanıp kullanmadığınızı test ediyoruz c. Bu yüzden misk i<rtutuyoruz, fonksiyonun tekrarı sırasında dururuz c.

Aşama 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)

Bu adımda, bu iki işlevi birer birime birleştiririz.

Biraz daha golfün ardından nihayet yukarıda açıklanan cevabı aldık.


2

Jöle , 13 bayt

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

Çevrimiçi deneyin!

Uriel'in Dyalog algoritmasını kullanarak.

1 endeksli.

Açıklama:

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

Bir açıklama ekler misiniz? þBurada ne yaptığını çözemiyorum.
Shaggy

1
@Shaggy Dış ürünü, bir açıklama ekleyeceğim.
Outgolfer Erik

2

JavaScript (Node.js) , 65 bayt

Bir dizi bile kullanılmıyor. 0 endeksli.

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)

Çevrimiçi deneyin!

Açıklama:

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

Pascal , 373 bayt

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 fonksiyondur.

Çevrimiçi deneyin!


n=1 thenolabilir n=1then.
Jonathan Frech

Siyasi olarak, if(k=0)thenolabilir gibi görünüyor if k=0then.
Shaggy,

Bazı numaralar her zaman 0'dan büyükse, wordbunun yerine kullanmalısınız integer.
tsh

1

Java 8, 187 bayt

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);}

Açıklama:

Çevrimiçi deneyin.

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 bayt

:qt!XnSXzG)

1 tabanlı.

Çevrimiçi deneyin! Veya tüm test durumlarını doğrulayın .

açıklama

4Bir örnek olarak girişi düşünün . ;matrisler veya sütun vektörleri için satır ayırıcıdır.

:     % 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

Toplu iş, 128 bayt

@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 endeksli.


Bir açıklama ekler misiniz lütfen? Buradaki mantığı tam olarak takip edemiyorum.
AdmBorkBork

@AdmBorkBork İlk üç satır satır hesaplamak rve sütun %1-(s-2)bir %1dizi th. Dördüncü satır daha sonra binom katsayısını hesaplamak için bunu kullanır (n k) = n!/(n-k)!k!= n(n-1)...(n+1-k)/(1)(2)...k= (n/1)((n-1)/2)...((n+1-k)/k). İhtiyacım olduğunda MathJax nerede?
Neil

1

APL (Dyalog Klasik) , 17 bayt

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

Çevrimiçi deneyin!

0 tabanlı dizin oluşturma

unutmayın (49!98) > 2*53, yani 49 üzerinde binom katsayısı 98 2'den büyüktür 53 öylesine Dyalog zaten çünkü IEEE kayan nokta hassas kaybetme başladığını noktada,


@Abigail burada ve burada
ngn

1

05AB1E , 10 bayt

0 endeksli

ÝεDÝc{}˜sè

Çevrimiçi deneyin!

açıklama

Ý             # push range [0 ... input]
 ε    }       # apply to each element
  DÝc         # N choose [0 ... N]
     {        # sort
       ˜      # flatten result to a list
        sè    # get the element at index <input>

1

Jöle , 11 bayt

Ḷc€`Ṣ€Fḟ0ị@

Çevrimiçi deneyin!

Dizini alan ve bir tamsayı döndüren monadik bir bağlantı - 1 tabanlı dizinleme kullanır.

Nasıl?

Mücadeleyi, yazıldığı gibi, sadece Pascal'ın üçgeni (sıfırlar) hakkından daha sonra atılan haklarıyla yapar.

Ḷ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

Kırmızı , 206 bayt

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 tabanlı

Çevrimiçi deneyin!

Açıklama:

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 bayt

içerir +1içinp

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

Temel 0 endekslemesini kullanır.


1

J, 46 41 bayt

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

0 endeksli

Çevrimiçi deneyin!

Notlar:

  • <.2&!@,:^:_1Pascal üçgeninin ilgili satır sayısını tersine çevirerek verir y choose 2.
  • /:~@(i.!<:)@] Satırı hesaplar ve sıralar.
  • [-2!] dizini sıraya verir.

Merhaba. Siteye Hoşgeldiniz! Bu güzel bir ilk cevap :)
DJMcMayhem

1

Julia , 70 bayt

f(x)=map(n->binomial(n-1,ceil(Int,x/2-(n^2-n)/4-1)),round(Int,√(x*2)))

1 tabanlı

Açıklama:

önce satır numarasını, sonra sütun numarasını bulur, sonra binomu hesaplar


PPCG'ye Hoşgeldiniz!
Martin Ender

evet thx mutlu yüz
Jimmy Chen


0

Pyth, 15 bayt

@u+GSm.cHdhHhQY

0 endeksli

Dene

açıklama

@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

Ruby , 56 bayt

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

0 tabanlı

İlk önce üçgenin üstündeki satır ve sütunu alın, ardından o konuma karşılık gelen binom katsayısını hesaplayın.

Çevrimiçi deneyin!


0

Aslında 8 bayt

Büyük ölçüde Jonathan Allan'ın Jelly cevabına dayanıyor . 0 indeksleme kullanır.

;r♂╣♂SΣE

Çevrimiçi deneyin!

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.

Tek bir sayı üretmesi gerekiyordu; nSerinin içindeki th. Bu bir dizi üretir.
özyinelemeli

Whoops. Sabit. Thanks @recursive
Sherlock9



Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.