帕斯卡三角(排序)


24

这里的大多数人都熟悉Pascal的Triangle。它由连续的行组成,其中每个元素是其两个左上和右上邻居的总和。以下是第一5行(从Generate Pascal的三角形借用):

    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此系列中的th号。这是OEIS 107430

规则

  • 您可以选择基于0或1的索引。请在您的提交中说明。
  • 可以假定输入和输出适合您语言的本机整数类型。
  • 输入和输出可以通过任何方便的方法给出。
  • 完整的程序或功能都是可以接受的。如果是函数,则可以返回输出而不是打印输出。
  • 禁止出现标准漏洞
  • 这是因此所有常见的高​​尔夫规则都适用,并且最短的代码(以字节为单位)获胜。

6
很好的标题!
路易斯·门多

1
根据OEIS链接,生成此序列而不是二项式系数所需的唯一更改是整数除法。那当然属于“琐碎的”。
彼得·泰勒,

5
@PeterTaylor对我来说这似乎不是一个明显的欺骗。还有许多其他可能的方法可以带来有趣的高尔夫机会,尤其是对于没有内置二项式的语言。
Arnauld

4
@PeterTaylor我也不相信这是重复的。到目前为止,在两个挑战之间,MATL,JavaScript和Pascal的答案都大相径庭。但是,由于我的投票是一锤定音,所以我暂时不会投票。
AdmBorkBork '18

4
完全同意@AdmBorkBork。所以算我为重新投票。现在等于3。重新开放需要多少票?
路易斯·门多

Answers:


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

该算法直接生成Pascal三角形的排序行。它根据上一行的长度更新n,直到a [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 '18 -2-7

@ kamoroso94我添加了一个解释。
Arnauld

我喜欢这个!真的很喜欢弄清楚它在做什么。
毛茸茸的

6

八度,46字节

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

基于1。

在线尝试!

说明

考虑n=4一个例子。

pascal(n) 给出一个Pascal矩阵:

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

Pascal三角形的行是此矩阵的对角线。所以它使用垂直翻转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使用提取此向量的第th个条目(···)(n),在这种情况下为1


5

Python 2中86个 78 72字节

-8字节归功于Rod

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)

在线尝试!

该函数递归计算Pascal三角形的行。鉴于当前行rowmap(sum, zip([0] + row, row + [0]))
每次调用n都会减少当前行的长度。如果函数到达右行,nth则应返回该行的最低编号。
由于一行的前半部分按升序排列,并且每一行都是对称的,所以该数字位于索引处n/2(0索引,整数除法)。


4

Wolfram语言(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,输入]∩,生成每个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,kin 计算[0,1,...,n],对升序(*)的行进行排序,并删除零,然后选择n th元素。

(*)还将它们转换为列,但这更好,因为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程序!我敢肯定它会变得更短。提示,不胜感激。

感谢nimi,节省了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 bs(a,b)=reverse b!a
nimi

@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);如果k == 0或k == n则为1
  • 功能 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)

在这一步中,我们尝试修改函数的调用 cc(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在function递归期间保持保留的原因c

第三步:

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⁸ị

在线尝试!

使用Uriel的Dyalog算法。

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这是外部产品,我将添加一个解释。
Erik the Outgolfer

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
乔纳森·弗雷希

相似地,看起来if(k=0)then可以成为if k=0then
毛茸茸的

如果某个数字始终大于0,则应使用word代替integer
tsh

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

05AB1E,10个字节

0索引

ÝεDÝc{}˜sè

在线尝试!

说明

Ý             # 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

果冻,11 字节

Ḷc€`Ṣ€Fḟ0ị@

在线尝试!

取索引并返回整数的单子链接-使用基于1的索引。

怎么样?

正好按照编写的方式执行挑战,只是将Pascal三角形的右边(零)中的更多部分丢掉了……

Ḷ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通过舍入的逆来给出Pascal三角形的相关行号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个字节

主要基于乔纳森·艾伦(Jonathan Allan)的果冻答案。使用0索引。

;r♂╣♂SΣE

在线尝试!

开球

          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系列中的th。这将产生一个数组。
递归

哎呀 固定。感谢@recursive
Sherlock9



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.