对于素数 p,因式分解树仅有一种方式的单顶点,因此 a(p) = 1。
对于复合数 n,n 处的两棵子树将 n 拆分为两个因子 n = d * (n/d),无序,因此
a(n) \ = \sum_{\substack{d\, |\, n \\ 2\, \le \, d \, \le \, n/d}} a(d)\, a\left(\frac{n}{d}\right).
按照惯例,a(1) = 1 将 1 视为具有一个空分解因子。
例子:对于 n = 12 和 n = 16,有 2 个因式树:
12 12
/ \ / \
2 6 3 4
/ \ / \
2 3 2 2
16 16
/ \ / \
2 8 4 4
/ \ / \ / \
2 4 2 2 2 2
/ \
2 2
对于 n = 12,树结构相同,但值不同,因此是不同的因式分解。
30 30 30
/ \ / \ / \
2 15 3 10 5 6
/ \ / \ / \
3 5 2 5 2 3
概括:
输入:一个正整数 n。
输出: a(n),n 的完全二叉无序树分解的数量。
可选:为了简化问题,可以忽略 n = 1 的情况。
鸣谢:该想法来自于尚未发表且仍在考虑中的 OEIS 序列。
这是代码高尔夫,因此每种语言以字节为单位的最短代码获胜。
\endgroup
3
8 个解决方案
8
,14
ḊŒċP⁼¥Ƈ⁸߀€ZPS
一个单子链接,接受一个正整数并产生因式分解树的数量。
如何?
ḊŒċP⁼¥Ƈ⁸߀€ZPS - Link: positive integer, N
Ḋ - dequeue -> [2..N] (an empty list for N=1)
Œċ - unordered pairs with replacement -> [[2,2],[2,3],...,[2,N],[3,3],...,[N,N]]
(an empty list for N=1)
Ƈ - keep those Pairs for which:
¥ ⁸ - last two links as a dyad - f(Pair, N):
P - product
⁼ - equals {N}?
߀€ - call this Link for each value of each remaining pair
Z - transpose (an empty list for N=1)
P - product (vectorises) (product of an empty list is 1)
S - sum
\endgroup
|
,35字节
F⊕N⊞υ∨ΣEΦ…²ι¬∨›×κκι﹪ικקυκ§υ÷ικ¹I⊟υ
链接为代码的详细版本。说明:
F⊕N
循环n+1
次数。
⊞υ∨ΣEΦ…²ι¬∨›×κκι﹪ικקυκ§υ÷ικ¹
从其非平凡次要因子计算下一个a(n)
,除非没有,在这种情况下假设a(n)=1
。请注意,Sum
空列表的实际上是None
Charcoal 中的,但在这里并不重要,因为它仍然是假的。
I⊟υ
输出第 个条目。(如果您想要从到的n
所有条目,那么您可以删除。)0
n
⊟
如果您愿意接受浮点不准确性,那么对于 31 个字节:
F⊕N⊞υ∨ΣEΦ…·²₂ι¬﹪ικקυκ§υ÷ικ¹I⊟υ
链接为代码的详细版本。说明:迭代到浮点平方根,而不是过滤不大于被分解数字的平方。
实际上,浮点库可以足够准确地对数值进行平方根计算,而2¹⁰⁶
这个数值远远超过了 Charcoal 在宇宙热寂之前能够迭代的数值。
\endgroup
|
,57 54 50 字节
f=(n,i=1)=>n%1?0:n>=++i*i&&f(n,i)+f(n/i)*f(i)||i<3
如果没有办法分解,那么它就是素数并返回 1
\endgroup
|
,49字节
f n=max 1$sum[f a*f b|a<-[2..n],b<-[2..a],a*b==n]
\endgroup
|
,13字节
λKḢṪvxḂ*Ih∑1∴
有点丑,但确实管用。
λ # Define a recursive function f taking n
vx # Do a recursive call on each of
K # the divisors of n
ḢṪ # aside from 1 and n
Ḃ* # Multiply each f(k) by f(n/k)
Ih # Take the first half
∑ # and sum it
1∴ # or return 1 if it's empty
\endgroup
|
,77 字节
a@1=1
a@n_?PrimeQ:=1
a@n_:=Sum[a[d]*a[n/d],{d,Select[Divisors@n,2<=#<=n/#&]}]
\endgroup
|
,98 # 9692字节
s=z#1
z=0:z
(h:t)#i|n<-max 1h=n:zipWith(+)t(do p<-tail$take i s++z;(0<$[2..i])++[p*n])#(i+1)
-2 记住我总是忘记的事情
-4 感谢 xnor 哈哈哈
无限输出。有点儿像 DP/筛选法,因式分解会不断累加。
s=z#1
z=0:z
z
是无限的零列表(即在其自身前面添加 0)。该序列是应用于和 1 的s
函数。(#)
z
(h:t)#i|n<-max 1h
(#)
将其第一个参数解构为其第一个元素h
和余数t
,其第二个参数称为i
。n
是h
,除非h
为0,在这种情况下它为1。
=n: [...] #(i+1)
(#)
返回一个列表,其中第一个值是n
,然后是其自身,按递增方式调用i
…
zipWith(+)t( [...] )
每个元素t
添加到的相应元素…
do p<-tail$take i s++z;
的连接,对于除第一个之外的每个p
第一个元素(用无限填充,因此不会截断)……i
s
z
zipWith
(0<$[2..i])++[p*n]
i
p
-1 个零后跟和的乘积n
。
\endgroup
1
-
1\begingroup
z=0:z
节省一些字节
\endgroup
–
|
,91字节
a=lambda n:1 if is_prime(n) else sum(a(d)*a(n//d) for d in range(2,n) if n%d==0 and d*d<=n)
Python 除了函数‘is_prime’之外。
\endgroup
1
-
\begingroup
如果它确实是 Python,那么您可以执行诸如删除不必要的空格并更改1 if is_prime(n) else
为 之类的操作is_prime(n)or
。
\endgroup
–
|
不错的挑战,但是你能添加数学代码块的英文表述吗?这里很多人不懂这样的符号。此外,如果您在
\$
两侧用 LaTeX 括起来(注意反斜杠) ,此网站支持 LaTeX(MathJax)格式。\endgroup
–
更多的测试用例将会很有帮助
\endgroup
–
我认为数字a (n )= 1一个(n)=1a(n)=1是和以下号码a (n )> 1一个(n)>1a(n)>1为。
\endgroup
–
|