# 易裂变数字

47

``````       24
/|\
/ | \
/  |  \
7   8   9
/ \     /|\
3   4   / | \
/ \     /  |  \
1   2   2   3   4
/ \
1   2
``````

``````1, 1, 3, 1, 5, 6, 5, 1, 6, 7, 12, 10, 12, 11, 12, 1, 8, 16, 14, 17, 18, 18,
23, 13, 21, 18, 22, 23, 24, 19, 14, 1, 22, 20, 23, 24, 31, 27, 25, 26
``````

## 挑战

mathmandan

1
@mathmandan很好，我可能会提出一个更正（以及第一个图表）。

@mathmandan仅供参考，我现在已经纠正了序列和示例，还添加了我的参考实现和前10k项。
Martin Ender 2015年

mathmandan 2015年

16

# Pyth，23 22 21字节

``````Lh&lJfqbsT.:tUb)syMeJ
``````

### 说明：

``````L                      define a function y(b): return ...
tUb          the list [1, 2, ..., b-1]
.:   )         generate all consecutive sub-sequences
f                   filter for sub-sequences T, which satisfy:
qbsT                   b == sum(T)
J                    and store them in J

return
lJ                        len(J)
&                        and (if len(J) == 0 then 0 else ...)
eJ       last element of J (=longest sub-sequence)
yM         recursive calls for all these numbers
s           sum
h                         incremented by one (counting the current node)
``````

52

# 裂变，1328 989 887 797字节

`````` R'0@+\
/  Y@</ /[@ Y]_L
[? % \  / \ J
\\$@  [Z/;[{+++++++++L
UR+++++++++>/;
9\   ;    7A9
SQS  {+L  /\$     \/\/\/\/\/   5/ @  [~ &@[S\/ \  D /8/
~4X /A@[  %5                   /; &    K  } [S//~KSA /
3    \  A\$@S  S\/  \/\/\/   \/>\ /S]@A  /  \ { +X
W7           X  X    /> \      +\ A\ /   \ /6~@/ \/
/   ~A\;     +;\      /@
ZX [K    / {/  / @  @ }  \ X @
\AS   </      \V /    }SZS S/
X   ;;@\   /;X  /> \ ; X X
;       \@+  >/ }\$S SZS\+;    //\V
/ \\  /\; X X @  @  \~K{
\0X /     /~/V\V /   0W//
\        Z      [K \  //\
W       /MJ \$\$\\ /\7\A  /;7/\/ /
4}K~@\ &]    @\  3/\
/     \{   }\$A/1 2  }Y~K <\
[{/\  ;@\@  /   \@<+@^   1;}++@S68
@\ <\    2        ;   \    /
\$  ;}++ +++++++L
%@A{/
M  \@+>/
~     @
SNR'0YK
\  A!/
``````

``````g++ -g --std=c++11 *.cpp -o Fission
``````

## 到底怎么回事？

### `atoi`

``````     ;
R'0@+\
/  Y@</ /[@ Y]_L
[? % \  / \ J
\\$@  [Z/;[{+++++++++L
UR+++++++++>/;
O
``````

• `R``L`在底部简单地得到它们的质量增量（与`+`）成为`(10,0)`然后分别存储在裂变和聚变反应堆，。我们将使用这些反应堆来解析以10为基的输入。
• `L`在右上角被它的质量递减（用`_`），以成为`(0,0)`与被存储在聚变反应堆的侧`Y`。这是为了跟踪正在读取的数字-在读取数字时，我们将逐渐增加并乘以该数字。
• `R`设置左上角的质量为`0`（48）的字符代码`'0`，然后与质量和能量交换，`@`最后质量增加一次，`+`得到`(1,48)`。然后用对角镜将其重定向`\``/`存储在裂变反应堆中。我们将使用`48`for减法将ASCII输入转换为数字的实际值。我们还必须增加质量`1`以避免被除以`0`
• 最后，`U`左下角的实际使一切运动，最初仅用于控制流。

`@`之前的核聚变反应堆再次交换物质和能量，这样我们将添加`(3,0)`到我们的运行总和的`Y`。请注意，运行总计本身将始终具有`0`能量。

``````/ \
[Z/
``````

### `itoa`

``````           /     \
input ->  [{/\  ;@
@\ <\
\$  ;}++ +++++++L
%@A{/
M  \@+>/
~     @
SNR'0YK
\  A!/
``````

`%`一旦迭代变量达到0 ，中止循环。由于这或多或少是一个do-while循环，因此该代码甚至可以用于打印`0`（否则将不创建前导零）。离开循环后，我们想清空堆栈并打印数字。`S`与的相反`Z`，因此它是一个开关，它将使非正能量的入射原子向右偏转90度。因此，原子实际上在`S`直线上从边缘移到，`K`从而弹出一个数字（请注意，`~`这确保了传入的原子具有能量`-1`）。该数字将递增`48`以获取相应数字字符的ASCII码。该`A`分裂数字打印一个副本`!`并将另一份副本反馈到`Y`反应堆中以获取下一位数字。所打印的副本将用作堆栈的下一个触发器（请注意，镜像还会将其发送到边缘周围，以`M`从左侧命中）。

### 计算裂变数：框架

``````fission[n_] := If[
(div =
SelectFirst[
Reverse@Divisors[2 n],
(OddQ@# == IntegerQ[n/#]
&& n/# > (# - 1)/2) &
]
) == 1,
1,
1 + Total[fission /@ (Range@div + n/div - (div + 1)/2)]
]
``````

``````                      +--- input goes in here
v

SQS ---> compute div from n          D /8/
~4X               |                /~KSA /
3               +----------->    { +X
initial trigger ---> W                               6~@/ \/
4
W        ^                     /
|              3
^     generate range    |
|     from n and div  <-+----- S6
|         -then-
+---- release new trigger
``````

### 计算裂变数：环体

`````` ;
{+L  /\$     \/\/\/\/\/   5/ @  [~ &@[S\/ \
/A@[  %5                   /; &    K  } [S/
\  A\$@S  S\/  \/\/\/   \/>\ /S]@A  /  \
X  X    /> \      +\ A\ /   \ /
/   ~A\;     +;\      /@
ZX [K    / {/  / @  @ }  \ X @
\AS   </      \V /    }SZS S/
X   ;;@\   /;X  /> \ ; X X
\@+  >/ }\$S SZS\+;    //\V
/ \\  /\; X X @  @  \~K{
\0X /     /~/V\V /   0W//
\        Z      [K \  //\
\ /\7\A  /;7/\/
``````

`````` /MJ \$\$\
4}K~@\ &]    @\  3/\
\{   }\$A/1 2  }Y~K <\
\@  /   \@<+@^   1;}++@
2        ;   \    /
``````

``````[K
\A --> output
``````

1
`Now with 100% fewer scrollbars.`所以你说..，它仍然要继续...

13

corsiKa 2015年

C0deH4cker 2015年

C0deH4cker

12

# CJam，42 41字节

``````ri]{_{:X,:)_few:+W%{1bX=}=}%{,(},e_}h]e_,
``````

``````ri]                                       e# This represents the root of the fissile tree
{                               }h     e# Now we run a do-while loop
_{                    }%              e# Copy the nodes at the current level and map them
e# via this code block to get next level nodes
:X,:)                               e# Store the node value in X and get array [1..X]
_few                           e# Copy the array and get continuous slices of
e# length 1 through X from the array [1..X]
:+W%                       e# Right now, we have an array of array with each
e# array containing slice of same length. We join
e# those arrays and reverse them to get slices of
e# higher length in front of lower lengths
{1bX=}=                e# Choose the first slice whose sum is same as X
e# The reversal above makes sure that we give
e# preference to slice of higher length in case of
e# multiple slices add up to X
{,(},         e# Filter out slices of length 1 which basically
e# mean that the current node cannot be split up
e_       e# Join all slices in a single array. This is our
e# next level in the Fissile tree. If this is empty
e# it means that all no further node can be
e# decomposed. In an {}h do-while loop, this fact
e# itself becomes the stopping condition for the
e# loop
]e_, e# Wrap all levels in an array. Flatten the array
e# and take its length
``````

10

# Python 3，112字节

``````def f(n,c=0):
d=n-c;s=(n-d*~-d/2)/d
return(s%1or s<1)and f(n,c+1)or+(d<2)or-~sum(f(int(s)+i)for i in range(d))``````

@FryAmTheEggman节省了4个字节。

2 + 3 + 4 + 5 = 14这并不奇怪。您将偶数长度序列的参数更改为“偶数长度序列的总和是两个中间数字的和，这是奇数，乘以长度的一半”。您的其余陈述不受影响。

@BrunoLeFloch谢谢！已更正。
randomra 2015年

corsiKa

@corsiKa我通常只这样做以作重大改进。否则会有太多的罢工数字。
randomra 2015年

8

# Python 2中，111个102 97字节

``def f(n,c=0):a=n-c;b=n-a*~-a/2;return 1/a or-~sum(map(f,range(b/a,b/a+a)))if b>b%a<1else f(n,c+1)``

``def f(n,a=0):b=n-a*~-a/2;return b>0and(f(n,a+1)or b%a<1and(1/a or-~sum(map(f,range(b/a,b/a+a)))))``

`b``n`减去`(a-1)th`三角数。如果是`b % a == 0`，则`n``a`从开始的连续数字的总和`b`

8

Alex A.

Optimizer

Python 2不允许`1else`。仅第二种解决方案有效。直到Python 3 `else`可以立即跟随数字。
mbomb007

@ mbomb007据我所知，它工作正常，从2.7.8开始
SP3000

mbomb007

7

# 蟒蛇2，86

``f=lambda n,R={1}:n-sum(R)and f(n,R^{[min(R),max(R)+1][n>sum(R)]})or-~sum(map(f,R-{n}))``

``````def f(n,R={1}):
d=sum(R)-n
if d==0:return (sum(map(f,R-{n}))
if d<0:return f(n,R|{max(R)+1})
if d>0:return f(n,R-{min(R)})``````

• 如果总和太大，则会在运行中切出最小的元素。
• 如果总和太小，我们通过将其最大值增大1来扩展行程。
• 如果总和正确，则进行递归，映射`f`到运行，求和，然后为当前节点加1。如果运行为`{n}`，我们已经尝试了所有非平凡的总和，`n`请先删除来停止递归。

7

# Python 2，85

``f=lambda n,a=1,d=1:a/n or[f(a)+f(n-a,1+1%d*a)+1/d,f(n,a+d/n,d%n+1)][2*n!=-~d*(2*a+d)]``

``f=lambda n,a=1,d=1:a/n or~d*(2*a+d)+n*2and f(n,a+d/n,d%n+1)or f(a)+f(n-a,1+1%d*a)+1/d ``

xnor 2015年

“我对这个答案感到非常自豪，因为对于n = 9，它已经花费了数十秒，对于n = 10，它已经花费了5-10分钟。在代码高尔夫中，这被认为是程序的理想属性。” 为此+1了。
Soham Chowdhury

6

``````f x=head\$[1+sum(map f[y..z])|y<-[1..x-1],z<-[y..x],sum[y..z]==x]++[1]
``````

``````*Main> map f [1..40]
[1,1,3,1,5,6,5,1,6,7,12,10,12,11,12,1,8,16,14,17,18,18,23,13,21,18,22,23,24,19,14,1,22,20,23,24,31,27,25,26]
``````

``````[  [y..z] |y<-[1..x-1],z<-[y..x],sum[y..z]==x]

make a list of lists with all consecutive integers (at least 2 elements)
that sum up to x, sorted by lowest number, e.g. 9 -> [[2,3,4],[4,5]].

1+sum(map f[...])

recursively calculate the Fission Number for each list

[...]++[1]

always append the 1 to the list of Fission Numbers.

take the first element, which is either the Fission Number of the
longest list or if there's no list, the 1 appended in the step before.
``````

3

# 视网膜，66字节

``````^|\$
,
(`,(1+?)(?=(?<1>1\1)+\D)
\$0;
+)`,(1*);1\1
,\$1,1\$1;
^,|1

.
1
``````

``````> echo -n 1111111|retina -s fission
11111
``````

• 我们保留要分割的数字的逗号分隔列表。
• 对于每个数字，我们采用最小的起始值，该值可以创建有效的拆分，并用分号将其与其余的分隔。
• 如果数字内有分号，我们将其更改为逗号，并界定数字的下一个适当大小的部分（前一个元素的长度+ 1）。
• 重复步骤2和3，直到发生更改为止。
• 我们为每个叶子得到一个逗号，为每个内部节点得到一个分号，再加上一个额外的逗号，因为我们从两个逗号开始。因此，我们删除逗号和数字的部分（`1`），然后将其余部分转换为`1`

``````,11111111111111,
,11;111111111111,
,11,1;11,1111,11;111;,
,11,1,11;,1111,11,1;11;;,
,11,1,11;,1111,11,1,11;;;,
,,;,,,,;;;,
11111111111
``````

3

## CJam（43字节）

``````qi,{):X),_m*{{_)*2/}/-X=}=~\,>0\{~\$+}/)}%W=
``````

`,_m*`可以替换为`2m*`。算术级数公式可以替换`~,>:Y_,+:+``~\,>0\ ``!Y`。最后，如果使用`{}#`代替`{}=`，则不需要`)`after `X`。全部放在一起：`ri{):X2m*{~,>:Y_,+:+X=}#!Y{~\$+}/)}%W=`

2

# Go，133个字节

``````func 算(n int)int{Σ:=1;for i:=0;i<n;i++{for j:=0;j<n;j++{if i*i+i-j*j-j==2*n{for k:=j+1;k<=i;k++{Σ+=算(k)};j,i=n,n}}};return Σ}
``````

``````  A: 1 2 3 4 5 6 7  sum = 28
B: 1 2 3 4 5      sum = 15
A-B:           6 7  sum = 13, which is also 28-15 = 13
``````

Martin Ender

1

# CJam，40 35 33字节

``````ri{__,f-_few:+{1b1\$=}=|{F}*}:F~],
``````

CJam解释器中在线尝试。

### 这个怎么运作

``````ri      e# Read an integer from STDIN.
{       e# Define function F(X):
_     e# Push X.
_,    e# Push [0 ... X-1].
f-    e# Subract each from X. Pushes Y := [X ... 1].
_few  e# Push all overlapping slices of Y of length in Y.
:+    e# Consolidate the slices of different lenghts in a single array.
{     e# Find the first slice S such that...
1b  e#   the sum of its elements...
1\$= e#   equals X.
}=    e#   Since Y is in descending order, the first matching slice is also the longest.
|     e# Set union with [X]. This adds X to the beginning of the S if S != [X].
{F}*  e# Execute F for each element of S except the first (X).
}:F     e#
~       e# Execute F for the input.
],      e# Count the integers on the stack.
``````

@Optimizer：很好。这样可以进行其他改进。谢谢！