帕斯卡尔的菱形


20

Pascal的菱形(实际上是一个三角形)是通过添加以下模式获得的:

  *
 ***
  x

代替

* *
 x

这意味着每个单元格是该单元格正上方的行中的三个单元格和其上方的行2中的一个单元格的总和。就像Pascal的三角形一样,第零行上也有一个1生成三角形的单。

这是帕斯卡的菱形的前两排

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

任务

给定一个行号(从顶部开始)和一个列号(从该行的第一个非零项目开始)输出该特定单元格的值。两个输入都可以被索引为1或0(如果需要,可以混合和匹配)。

这是因此您应力争使源代码的文件大小尽可能小。

OEIS A059317


4
与帕斯卡的三角形一样,菱形的奇偶性也形成了很好的分形图案
Martin

您的目标应该是使源代码的文件大小尽可能小,如果我将代码作为命令行参数呢?:P
暴民埃里克(Erik the Outgolfer)'17

去搜索快捷方式,显然arxiv.org/abs/1504.04404说,直接计算结果对代码高尔夫不可用。
JollyJoker

Answers:


12

Haskell59 55字节

帕斯卡尔的菱形?更像是Haskell的菱形!我对吗?

ØrjanJohansen节省了4个字节

我以为自己可以解决自己的问题并练习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抱歉,当我发布此消息时,似乎没有人比Jorg在解决问题。我仍然想看看您的解决方案。
小麦巫师

1
您可以使用保存四个字节n!k=sum[(n-2)!(k-2)+sum(map((n-1)!)[k-2..k])|n>1]
与Orjan约翰森

10

帕斯卡,122字节

好吧,这是帕斯卡(Pascal)的菱形。

@manatwork节省了37个字节

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条件的括号是没有意义的。(首先,if您保存2个字符,在第二个if1个字符时,在then关键字和前一位数字之间不留空格。)哦,变量r完全没有必要。
manatwork'7

Pascal对Ideone的怪异动物。以前从未在任何Pascal变体中看到双引号分隔字符串。您可以删除的另一件事:的;之前functionend
manatwork'jul

@manatwork是的,现在您提到它时,所有其他在线编辑都抱怨它
Uriel

@manatwork我不确定我是否理解。会不会只是用加长代码>= <=?我仍然需要保留if n=0
Uriel

抱歉@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;
manatwork'7

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,以实际改善它:)
Uriel's


3

MATL22 20 19字节

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

两个输入均基于0。

在线尝试!

说明

rc表示两个输入,分别指定基于0的行和列。

通过与内核进行卷积[1 1 1; 0 1 0]并保持交换结果的最后两行,可以从包含前两行的矩阵中构建Pascal菱形中的每一行。这是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-th元素。此用途线性索引,即,矩阵由索引单指数列优先顺序。由于索引是模块化的,所以0-entry是右下角(值1),第-2-th个条目是在右上角的两个步骤(值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

Mathematica,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

Mathematica,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)。整体功能是Python and or招,其中,所述第一条件检查如果k是在三角形内没有对边界,在这种情况下,递归公式被使用。如果不是,or则返回后面的部分,该部分检查kin 是否位于(1, 2*n-1),即在边界上,返回TrueFalsek+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因为它的行为类似于1python。这样一来,您可以+(...)在最后删除。我知道您是否不想这样做,因为这会使输出看起来有些奇怪,这是一个选择。
小麦巫师

@WheatWizard哇,这很有趣。谢谢你的提示。
C McAvoy


0

Python 3,75字节

这是一个递归lambda,它将列和行作为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)
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.