赛德尔三角


14

Seidel三角形是类似于Pascal三角形的数学结构,并因其与伯努利数的关系而闻名。

前几行是:

      1
      1  1
   2  2  1
   2  4  5  5
16 16 14 10 5
16 32 46 56 61 61

每行生成如下:

如果行号是偶数(1索引):

  • 调低上一行的第一项

  • 每个下一个项目是上一个项目及其上一个项目的总和

  • 复制最后一个项目

如果行号是奇数:

  • 调低上一行的最后一项

  • 走向倒退,每一项都是前一个项目的总和,它上面的项目

  • 复制现在的第一项。

基本上,我们以锯齿形构造三角形:

    1
    v
    1 > 1
        v
2 < 2 < 1
v
2 > 4 > 5 > 5

有关更多信息,请参见 伯努利数字上的Wikipedia页面

挑战:

给定n,作为函数参数或来自STDIN,打印或返回nSeidel三角形的第t行或第一个行n行。您可以使用0或1索引。

您无需处理负数或非整数输入(如果为1索引,则也不能为0)。您不必处理大于2147483647 = 2^31 - 1

由于这是代码高尔夫,因此请以尽可能少的字节为单位。

例子:

在这些示例中,返回值是n第0行,从0开始。

Input   ->  Output

0           1
1           1 1
2           2 2 1
6           272 272 256 224 178 122 61
13          22368256 44736512 66750976 88057856 108311296 127181312 144361456 159575936 172585936 183194912 191252686 196658216 199360981 199360981

“您不必处理比您的语言的默认int类型大的输出”对于只有1位int的语言来说,这是微不足道的
仅ASCII

可以始终按从小到大的顺序输出行吗?
Angs

仅限
@ASCII

@Angs否,行应如图所示进行排序
Bolce Bussiere

@ ASCII-only这是默认的漏洞(尽管IMO措辞有点差,因为它取决于人们认为“合理”的东西)
user202729 '18

Answers:


7

脑筋急转弯,66字节

<>(())<>{({}[()]<(()[{}]<<>{(({}<>{}))<>}>)>)}{}{{}<>{({}<>)<>}}<>

在线尝试!

行的索引为0。

# Push 1 (the contents of row 0) on other stack; use implicit zero as parity of current row
<>(())<>

# Do a number of times equal to input:
{({}[()]<

  # Subtract the row parity from 1
  (()[{}]<

    # For each entry in old row:
    <>{

      # Add to previous entry in new row and push twice
      (({}<>{}))<>

    }

  >)

>)}{}

# If row parity is odd:
{{}

  # Reverse stack for output
  <>{({}<>)<>}

# Switch stacks for output
}<>

4

JavaScript(SpiderMonkey),67字节

此代码滥用了该sort()方法,并且不适用于所有引擎。

行的索引为0。

f=(n,a=[1],r)=>n--?f(n,[...a.map(n=>k+=n,k=0),k].sort(_=>n|r),!r):a

在线尝试!

怎么样?

我们通过将sort()方法与回调函数一起使用来有条件地反转数组,该回调函数将忽略其参数并返回0或正整数。不要在家尝试!这仅在SpiderMonkey上可靠地工作。

let A = [1,2,3,4,5] and B = [1,2,3,4,5,6,7,8,9,10,11]

             | SpiderMonkey (Firefox)  | V8 (Chrome)             | Chakra (Edge)
-------------+-------------------------+-------------------------+------------------------
A.sort(_=>0) | 1,2,3,4,5               | 1,2,3,4,5               | 1,2,3,4,5
A.sort(_=>1) | 5,4,3,2,1               | 5,4,3,2,1               | 1,2,3,4,5
B.sort(_=>0) | 1,2,3,4,5,6,7,8,9,10,11 | 6,1,3,4,5,2,7,8,9,10,11 | 1,2,3,4,5,6,7,8,9,10,11
B.sort(_=>1) | 11,10,9,8,7,6,5,4,3,2,1 | 6,11,1,10,9,8,7,2,5,4,3 | 1,2,3,4,5,6,7,8,9,10,11

请注意,根据数组的长度(少于或超过10个元素),V8可能会使用不同的排序算法。

已评论

f = (                     // f = recursive function taking:
  n,                      //   n   = row counter
  a = [1],                //   a[] = current row, initialized to [1]
  r                       //   r   = 'reverse' flag, initially undefined
) =>                      //
  n-- ?                   // decrement n; if it was not equal to zero:
    f(                    //   do a recursive call with:
      n,                  //     - the updated value of n
      [ ...a.map(n =>     //     - a new array:
          k += n, k = 0   //       - made of the cumulative sum of a[]
        ), k              //         with the last value appended twice
      ].sort(_ => n | r), //       - reversed if n is not equal to 0 or r is set
      !r                  //     - the updated flag r
    )                     //   end of recursive call
  :                       // else:
    a                     //   stop recursion and return a[]

这会使用哪些蜘蛛猴特定功能?
Downgoat

@Downgoat正在利用sort()此引擎中的特定实现。我添加了一个解释。
Arnauld


3

Haskell89 87 82字节

(cycle[r,id]!!)<*>s
r=reverse
s 0=[1]
s n=let a=zipWith(+)(0:a)$(r.s$n-1)++[0]in a

只是 s按之字形顺序打印行,第一行的匿名函数将反转一半的行。

感谢@nimi节省了5个字节!

在线尝试!



2

Python 3中98个 91字节

from itertools import*
f=lambda n:n and[*accumulate(f(n-1)[::n&1or-1]+[0])][::n&1or-1]or[1]

在线尝试!

切换到基于0的行编号可节省7个字节。


2

朱莉娅0.6,85字节

r(l,n=cumsum(l))=[n...,n[end]]
w=reverse
f(n)=n<2?[1]:n%2<1?r(f(n-1)):w(r(w(f(n-1))))

在线尝试!

这是Julia中的递归解决方案。请注意,它具有基于1的索引。因此进行测试。

非高尔夫版本,了解逻辑:

function new_row(last_row)
    new_row = cumsum(last_row)
    push!(new_row, new_row[end])
    return new_row
end


function triangle(n)
    if n == 1
        return [1]
    elseif mod(n,2) == 0
        return new_row(triangle(n-1))
    else
        return reverse(new_row(reverse(triangle(n-1))))
    end
end

作为一个好处,这是一个非递归版本,但是更长:

w=reverse;c=cumsum
r(l,i)=i%2<1?c([l...,0]):w(c(w([0,l...])))
f(n,l=[1])=(for i=2:n l=r(l,i)end;l)

1

Python 2中103个 97字节

f=lambda n,r=[1],k=2:n and f(n-1,[sum(r[-2::-1][:i],r[-1])for i in range(k)],k+1)or r[::-(-1)**k]

在线尝试!

非递归版本(易于阅读):

Python 2,106个字节

def f(n,r=[1],j=1):
 while n:
	a=r[-2::-1];r=r[-1:];n-=1;j=-j
	for x in a+[0]:r+=[r[-1]+x]
 return r[::-j]

在线尝试!

当然,更好是可能的!


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.