Answers:
·LÉœÙεÅγo;P}O
由于内置置换,因此非常慢。
说明:
· # Double the (implicit) input
L # Create a list in the range [1, doubled_input]
É # Check for each if they're odd (1 if truthy, 0 is falsey)
# We now have a list of n 0s and n 1s (n being the input)
œ # Get all permutations of that list
Ù # Only leave the unique permutations
ε } # Map each permutation to:
Åγ # Run-length encode the current value (short for `γ€g`)
o # Take 2 to the power for each
; # Halve each
P # Take the product of the mapped permutation
O # Sum all mapped values together (and output implicitly)
经过大量的绘图和编程示例后,我发现这与车队的问题相同:
在一个棋盘,一车从去多少种方法在那里到通过只向右移动或高达?
基本上,您具有网格的顶行和底行。现在,您必须填写非水平行。每个三角形必须有两条非水平线。它的侧面之一是顶线还是底线的一部分,对应于您在车队问题中所走的方向和长度。这是OEIS A051708。为了说明这种对应关系,请考虑以下示例。在此,顶线对应于上移,而底线对应于右移。
感谢@PeterTaylor提供-6个字节,以及@PostLeftGarfHunter提供-2个字节!
b 0=1
b 1=2
b n=div((10*n-6)*b(n-1)-9*(n-2)*b(n-2))n
A051708(n+1)
。因此,我发布了第一个正确答案:-P
0?0=1
a?b=sum[a?i+i?a|i<-[0..b-1]]
f n=n?n
一个相当直接的实现,它重复两个变量。
这是我们如何获得此解决方案的方法。从实现直接递归公式的代码开始:
54字节
0%0=1
a%b=sum$map(a%)[0..b-1]++map(b%)[0..a-1]
f n=n%n
使用frank的车队移动解释,a%b
是将车队从(a,b)
转到的路径数(0,0)
,仅使用移动减少坐标。第一步减少a
或减少b
,另一步保持不变,因此是递归公式。
49个字节
a?b=sum$map(a%)[0..b-1]
0%0=1
a%b=a?b+b?a
f n=n%n
我们可以map(a%)[0..b-1]++map(b%)[0..a-1]
通过注意两个半部分相同a
并b
互换来避免重复。辅助呼叫a?b
计算第一个移动减少的路径a
,因此b?a
计算第一个移动减少的路径b
。这些通常是不同的,它们增加了a%b
。
的总和a?b
也可以写成列表理解a?b=sum[a%i|i<-[0..b-1]]
。
42字节
0?0=1
a?b=sum[a?i+i?a|i<-[0..b-1]]
f n=n?n
最后,我们摆脱%
,只是写在条款递归?
通过更换a%i
与a?i+i?a
在递归调用。
新的基本情况使它的?
输出?
是49字节版本的两倍,因为有了0?0=1
,我们就可以了0%0=0?0+0?0=2
。这样就可以使用define f n=n?n
而不需要我们其他需要做的一半。
a%b
使用0,1,...,a
顶行的节点和0,1,..,b
底端的节点对分区数进行计数。如果底部节点已在使用中,则操作员a?b
计算从顶部节点添加新行的方式。(您可以连接到所有的节点,但你必须改乘每个那些。)a
b
a
[0,1,...,b-1]
?
我不知道的42字节字节,而特别奇怪的是它不是对称的。
map...
用列表理解代替;第二步,我们只需插入的定义%
:a?b=sum$map(a%)[0..b-1], a%b=a?b+b?a
a?b=sum[a%i|i<-[0..b-1]], a%b=a?b+b?a
a?b=sum[a?i+i?a|i<-[0..b-1]]
{2,*e!{e`0f=:(1b2\#}%1b}
{ e# Define a block
2,* e# Given input n, create an array of n 0s and n 1s
e! e# Generate all permutations of that array
{ e# Map:
e` e# Run-length encode
0f=:( e# Extract just the lengths and decrement them
1b e# Sum
2\# e# Raise 2 to the power of that sum
}%
1b e# Sum the mapped values
}
{_1aa{_2$,f{j}@@,f{j}+1b}2j}
三角形都有一个水平边和两个连接水平线的边。用两个x坐标的元组标记非水平边缘,然后按字典顺序排序。然后,第一个边缘为(0,0)
,最后一个边缘为(n,n)
,并且两个连续的边缘恰好在两个位置之一不同。这实现了一个简单的递归,我已经使用记忆化的递归运算符实现了它j
:
{ e# Define a block
_ e# Duplicate the argument to get n n
1aa e# Base case for recursion: 0 0 => 1
{ e# Recursive body taking args a b
_2$,f{j} e# Recurse on 0 b up to a-1 b
@@,f{j} e# Recurse on a 0 up to a b-1
+1b e# Combine and sum
}2j e# Memoised recursion with 2 args
}
这不是我第一次希望fj
获得CJam支持。在这里它也将分数降低到24个字节。也许我应该尝试写一个补丁...
Ø.xŒ!QŒɠ€’§2*S
-1个字节,基于Peter Taylor的评论。
直接使用fuerr的插图,而不使用结果公式。
Ø.xŒ!QŒɠ€’§2*S Main link (monad). Input: positive integer N.
Ø.x Make an array containing N zeros and ones
Œ!Q All unique permutations
Œɠ€ Run-length encode on each permutation
’§ Decrement and sum each
2*S Raise to power of 2 and sum
在正方形网格上走所有可能的路线。作为车队,在一个方向上移动L个单位的方式为2**(L-1)
。将其应用到每条路线,并汇总遍历每条路线的方式数量。
F⊕θ«≔⟦⟧ηF⊕θ⊞ηΣ∨⁺ηEυ§λκ¹⊞υη»I⊟⊟υ
在线尝试!说明:通过计算将相对边长的梯形划分为m,n
全部位于整数偏移量上的三角形的方式来工作。这只是n
问题中矩形大小的一般情况。递归给出分区的数目,作为所有边m,0..n-1
和的分区数目之和n,0..m-1
。这等效于车队的普遍问题OEIS A035002。该代码简单地计算工作的分区数量,0,0
直到n,n
使用之前计算的值为止。
F⊕θ«
在行上循环0..n
。
≔⟦⟧η
从空行开始。
F⊕θ
循环浏览行中的列0..n
。
⊞ηΣ∨⁺ηEυ§λκ¹
将当前行和当前行中前几行中的值相加,然后将总和添加到当前行中。但是,如果根本没有值,则用替代值1
代替总和。
⊞υη»
将完成的行添加到到目前为止的行列表中。
I⊟⊟υ
输出计算出的最终值。