Answers:
不幸的是,很少的C语言需要大量用于基本I / O的代码,因此缩短所有代码的工作量会使UI变得不太直观。
b;main(a){return~-a?b++,main(a&1?3*a+1:a/2):b;}
例如使用编译gcc -o 1 collatz.c
。输入是一元且以空格分隔的数字,您将在退出代码中找到答案。数字17的示例:
$> ./1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
$> echo $?
12
$>
return~-a?
1.省也正在b++
对?
案件应保存b--
。
$\++,$_*=$_&1?3+1/$_:.5while$_>1}{
$\
像往常一样滥用最终输出。使用-p
命令行选项运行,输入来自stdin
。
由于Elias Van Ootegem节省了一个字节。具体而言,观察到以下两个是等效的:
$_=$_*3+1
$_*=3+1/$_
虽然增加了一个字节,但通过缩短$_/2
为just 节省了两个字节.5
。
用法示例:
$ echo 176 | perl -p collatz.pl
18
<?for(;1<$n=&$argv[1];$c++)$n=$n&1?$n*3+1:$n/2;echo$c;
Javascript的“木汤匙奖”的代名词似乎在这一挑战中有所欠缺。但是,这个问题没有很大的创造空间。输入被当作命令行参数。
用法示例:
$ php collatz.php 176
18
$_
三元似乎浪费,您可以通过使用剃掉另一个字符*=
是这样的:$\++,$_*=$_&1?3+1/$_:.5while$_>1}{
。相乘的1/$_
效果与相同+1
,因此$_*=3+1/$_
效果很好
$_*=3+1/$_
,谢谢!
If[#>1,#0@If[OddQ@#,3#+1,#/2]+1,0]&
用法:
If[#>1,#0[If[OddQ@#,3#+1,#/2]]+1,0]&@16
>> 4
Java中,165,156,154,134,131,129,128,126(详细语言需要一些爱太)
class a{public static void main(String[]a){for(int x=Short.valueOf(a[0]),y=0;x>1;x=x%2<1?x/2:x*3+1,System.out.println(++y));}}
全部在for中完成
for(int x=Short.valueOf(a[0]),y=0;x>1;x=x%2<1?x/2:x*3+1,System.out.println(++y))
那太漂亮了。归功于Pater Taylor !!!,ugoren盗用了for循环的想法
我将Integer替换为Short。
i(,++y)
。您可以使用<
代替来另外保存两个==
。
class a{public static void main(String[]a){for(int x=new Short(a[0]),y=0;x>1;System.out.println(++y))x=x%2<1?x/2:x*3+1;}}
所做的更改:1)替换Short.valueOf(...)
用new Short(...)
的-4字节和2)我已经把x=x%2<1?x/2:x*3+1;
在身体for
-loop摆脱的-1字节的逗号。
u[++jE1 AeEV?a[d2A][a1M3a]]j
在这个简短而数学化的问题上,GolfScript可能会在一定程度上胜过Rebmu(如果不需要说的话,请从互联网上读取文件或生成JPG文件)。但是,我认为大多数人都同意Golfscript的逻辑很难遵循,并且运行它的总可执行堆栈更大。
尽管Rebol自己的创造者Carl Sassenrath告诉我他发现Rebmu“难以理解”,但他很忙,还没有时间通过松软来真正练习类似猪拉丁的转换。这实际上只是转换为:
u [
++ j
e1 a: e ev? a [
d2 a
] [
a1 m3 a
]
]
j
请注意,必须使用空格来获取a:而不是a。这是一个“设定词!” 然后评估者注意到该符号类型可触发分配。
如果它是用未缩写形式编写的(但是笨拙地编写了Rebol),则会得到:
until [
++ j
1 == a: either even? a [
divide a 2
] [
add 1 multiply 3 a
]
]
j
与Ruby一样,Rebol将块评估为最后一个值。UNTIL循环是一种奇怪的循环形式,它没有循环条件,当其块的计算结果不是FALSE或NONE时,它只是停止循环。因此,在1 ==
将A(rebmu的参数)分配给Collatz条件的结果(IF-ELSE的结果是它选择的分支)的结果……循环中断。
J和K在Rebmu中初始化为零。并且如前所述,整个结果的取值为最终值。因此,程序结尾的J引用意味着您可以获得迭代次数。
用法:
>> rebmu/args [u[++jE1 AeEV?a[d2A][a1M3a]]j] 16
== 4
我不相信这里的表达没有比短n=3*n+1;n/=1+n%2*5;
。我可能发现了十二种长度相同的不同表达方式...
i=0
n=input()
while~-n:n=3*n+1;n/=1+n%2*5;i+=1
i
编辑:我发现了另一个解决方案,永远不会竞争,但太有趣了,不能共享。
s='s'
i=s
n=i*input()
while 1:
while n==n[::2]+n[::2]:i+=s;n=n[::2]
if n==s:i.rindex(s);break
n=3*n+s
i+=s
(n//2,n*3+1)[n%2]
更短。
n/2
正常运行,因为我们知道它可以运行吗?
<:#-:`(1+3&*)`]@.(2&|+1&=)^:a:
结果比预期更长
用法:
<:#-:`(1+3&*)`]@.(2&|+1&=)^:a:2
1
<:#-:`(1+3&*)`]@.(2&|+1&=)^:a:16
4
<:#-:`(1+3&*)`]@.(2&|+1&=)^:a:5
5
<:#-:`(1+3&*)`]@.(2&|+1&=)^:a:7
16
<:#-:`(1+3&*)`]@.(2&|+1&=)^:a:27
111
-:`(1+3&*)`]
是由三个动词组成的动名词,在三种情况下使用。-:
表示“一半”,(1+3&*)
或(1+3*])
对乘法步骤进行编码,并且]
(身份)辅助终止。
2&|+1&=
形成动名词的索引。字面意思是“除以2的余数加上是否等于1”。
#verb^:a:
重复执行该功能,直到结果稳定(此处是显式强制),同时收集步骤,然后对其进行计数。从@JB窃取。<:
将步数减一以符合问题要求。
<:
,#-:
,:`(
,&*)
,=)
,)^:
。
<:
表示“减量”或“小于或等于”,#
表示“计数”或“ n次”,-:
表示“减半”或“ε等式”,:`(
依次表示所述“减半”的末尾,在动名词和左括号中的两个动词(用于分组)。&*)
表示“绑定到乘法的某物”(3与乘法绑定创建“乘以三”的运算符)和分组结束。=
执行相等性检查,或一元意义上的自我分类。^:
是幂级联(动词迭代)。由于许多J动词以冒号结尾,... :-)
<:#a:2&(<*|+|6&*%~)
19字节(-11)
Gambit方案,106 98个字符,40个括号
(let((f(lambda(x)(cond((= x 1) 0)((odd? x)(+ 1(f(+ 1(* 3 x)))))(else(+ 1(f(/ x 2))))))))(f(read)))
直接定义 91 89个字符
(define(f x)(cond((= x 1)0)((odd? x)(+ 1(f(+ 1(* 3 x)))))(else(+ 1(f(/ x 2))))))(f(read))
高尔夫代码:
for($i=(read-host);$i-ne1;$x++){$i=(($i/2),(3*$i+1))[$i%2]}$x
笔记:
我最初尝试在不将用户输入强制为整数的情况下进行输入,但这以一种有趣的方式中断了。任何奇数输入都会处理不正确,但即使输入也能正常工作。我花了一分钟才意识到发生了什么。
在执行乘法或加法时,PowerShell首先将未类型化的输入视为字符串。因此,它'5'*3+1
变为'5551'而不是16。偶数输入的表现很好,因为PowerShell没有针对字符串除法的默认操作。即使通过奇数进行的偶数输入也可以正常工作,因为当PowerShell在循环中达到奇数时,无论如何,该变量已被数学运算强制为整数。
感谢Danko Durbic指出,我可以反转乘法运算,而不必强制转换
read-host
为int,因为PowerShell的运算基于第一个对象。
PowerShell Golfer的技巧:在某些情况下,例如这种情况下,switch
心跳加速if/else
。在此,差异为2个字符。
没有错误检查非整数值或小于两个的整数。
如果您要审核脚本,请将脚本放在;$i
最后一个大括号之前。
我不确定PowerShell是否能很好地处理递增为非常大的值的数字,但是我希望精度有时会丢失。不幸的是,我还希望在不严重使脚本膨胀的情况下,可以做很多事情。
取消注释的代码,并带有注释:
# Start for loop to run Collatz algorithm.
# Store user input in $i.
# Run until $i reaches 1.
# Increment a counter, $x, with each run.
for($i=(read-host);$i-ne1;$x++)
{
# New $i is defined based on an array element derived from old $i.
$i=(
# Array element 0 is the even numbers operation.
($i/2),
# Array element 1 is the odd numbers operation.
(3*$i+1)
# Array element that defines the new $i is selected by $i%2.
)[$i%2]
}
# Output $x when the loop is done.
$x
# Variable cleanup. Don't include in golfed code.
rv x,i
测试用例:
以下是一些启用了审核的示例。为了清楚起见,我还对输出进行了一些编辑,方法是在输入和最终计数中添加标签,并留出间距以分隔Collatz值。
---
Input: 2
1
Steps: 1
---
Input: 16
8
4
2
1
Steps: 4
---
Input: 5
16
8
4
2
1
Steps: 5
---
Input: 7
22
11
34
17
52
26
13
40
20
10
5
16
8
4
2
1
Steps: 16
---
Input: 42
21
64
32
16
8
4
2
1
Steps: 8
---
Input: 14
7
22
11
34
17
52
26
13
40
20
10
5
16
8
4
2
1
Steps: 17
---
Input: 197
592
296
148
74
37
112
56
28
14
7
22
11
34
17
52
26
13
40
20
10
5
16
8
4
2
1
Steps: 26
---
Input: 31
94
47
142
71
214
107
322
161
484
242
121
364
182
91
274
137
412
206
103
310
155
466
233
700
350
175
526
263
790
395
1186
593
1780
890
445
1336
668
334
167
502
251
754
377
1132
566
283
850
425
1276
638
319
958
479
1438
719
2158
1079
3238
1619
4858
2429
7288
3644
1822
911
2734
1367
4102
2051
6154
3077
9232
4616
2308
1154
577
1732
866
433
1300
650
325
976
488
244
122
61
184
92
46
23
70
35
106
53
160
80
40
20
10
5
16
8
4
2
1
Steps: 106
---
Input: 6174
3087
9262
4631
13894
6947
20842
10421
31264
15632
7816
3908
1954
977
2932
1466
733
2200
1100
550
275
826
413
1240
620
310
155
466
233
700
350
175
526
263
790
395
1186
593
1780
890
445
1336
668
334
167
502
251
754
377
1132
566
283
850
425
1276
638
319
958
479
1438
719
2158
1079
3238
1619
4858
2429
7288
3644
1822
911
2734
1367
4102
2051
6154
3077
9232
4616
2308
1154
577
1732
866
433
1300
650
325
976
488
244
122
61
184
92
46
23
70
35
106
53
160
80
40
20
10
5
16
8
4
2
1
Steps: 111
---
Input: 8008135
24024406
12012203
36036610
18018305
54054916
27027458
13513729
40541188
20270594
10135297
30405892
15202946
7601473
22804420
11402210
5701105
17103316
8551658
4275829
12827488
6413744
3206872
1603436
801718
400859
1202578
601289
1803868
901934
450967
1352902
676451
2029354
1014677
3044032
1522016
761008
380504
190252
95126
47563
142690
71345
214036
107018
53509
160528
80264
40132
20066
10033
30100
15050
7525
22576
11288
5644
2822
1411
4234
2117
6352
3176
1588
794
397
1192
596
298
149
448
224
112
56
28
14
7
22
11
34
17
52
26
13
40
20
10
5
16
8
4
2
1
Steps: 93
---
关于输入数字的有趣部分,这些不是问题的测试案例中的内容:
14
和197
是基思数31
是Mersenne Prime6174
是卡普雷卡的常数8008135
。还有Numberphile,显然。switch
为$i=(($i/2),($i*3+1))[$i%2]
read-host
为数字,只需更改$i*3
为即可3*$i
。
$i*3
-我为什么还没有想到呢?
param($i)for(;$i-ne1;$x++){$i=(($i/2),(3*$i+1))[$i%2]}$x
-将读取主机交换为参数,以获取56个字节。 在线尝试一下链接
本示例使用AT&T语法和fastcall调用约定,该参数进入ecx
:
collatz:
or $-1,%eax # 3 bytes, eax = -1;
.Loop: inc %eax # 1 byte, eax += 1;
lea 1(%ecx,%ecx,2),%edx # 4 bytes, edx = 3*ecx + 1;
shr %ecx # 2 bytes, CF = ecx & 1;
# ecx /= 2;
# ZF = ecx == 0;
cmovc %edx,%ecx # 3 bytes, if (CF) ecx = edx;
jnz .Loop # 2 bytes, if (!ZF) goto .Loop;
ret # 1 byte, return (eax);
这是机器代码的结果16字节:
83 c8 ff 40 8d 54 49 01 d1 e9 0f 42 ca 75 f4 c3
1b|{/₂ℕ|×₃+₁}↰+₁
Either:
1 The input is 1.
b In which case we unify the output with 0 by beheading the 1
(which removes the leading digit of the 1, and an "empty integer"
is the same as zero).
| Or:
{ This inline predicate evaluates a single Collatz step on the input.
Either:
/₂ Divide the input by 2.
ℕ And ensure that the result is a natural number (which is
equivalent to asserting that the input was even).
| Or:
×₃+₁ Multiply the input by 3 and add 1.
}
↰ Recursively call the predicate on this result.
+₁ And add one to the output of the recursive call.
相同字节数的替代解决方案:
;.{/₂ℕ|×₃+₁}ⁱ⁾1∧
;. The output of this is a pair [X,I] where X is the input and
I will be unified with the output.
{/₂ℕ|×₃+₁} This is the Collatz step predicate we've also used above.
ⁱ⁾ We iterate this predicate I times on X. Since we haven't actually
specified I, it is still a free variable that Brachylog can backtrack
over and it will keep adding on iterations until the next
constraint can be satisfied.
1 Require the result of the iteration to be 1. Once this is
satisfied, the output variable will have been unified with
the minimum number of iterations to get here.
∧ This AND is just used to prevent the 1 from being implicitly
unified with the output variable as well.
Python 68 58 54 52个字符
f=lambda n:1+(n-2and f((n/2,3*n+1)[n%2]));f(input())
感谢Bakuriu和Bootyby的提示:)
n%2and 3*n+1or n/2
保存5个字符。同样在python2中,您可以删除对的调用int
,将大小减小到58个字节。
[n/2,3*n+1][n%2]
。
unsupported operand type(s) for -: 'str' and 'int'
12 个字节 这个答案是非竞争性的,因为挑战早于创建Jelly。
×3‘$HḂ?ß0’?‘
×3‘$HḂ?ß0’?‘ Main link. Argument: n (integer)
Ḃ? Yield the last bit of n is 1:
$ Evaluate the three links to the left as a monadic chain:
×3 Multiply n by 3.
‘ Increment the product by 1.
H Else, halve n.
’? If n-1 is non-zero:
ß Recursively call the main link.
0 Else, yield 0.
‘ Increment the result by 1.
应用布比的黑魔法:
?[d3*1+d2%5*1+/d1<x]dsxxkzp
我真的不知道,如果我知道如何-或者说 -它的工作原理。
用法:$ dc collatz.dc <<< 7
16
我自己的创作;这是一种较为传统的方法,甚至在我不得不纠结于某种语言的情况下,也克服了语句缺乏else
部分的缺点if
:
?[2/2Q]se[dd2%[0=e3*1+]xd1<x]dsxxkzp
在内部,它产生序列的所有编号并将它们存储在堆栈中,然后弹出最后一个1
并显示堆栈高度。
2<x
并摆脱k
。以防万一您想在四年后退还一个字节。:D
,-[<->[[>]+<[-<]>>]>[-<<[++>+<]>->]<<[+>+++<]<<+>>>]<<<.
在线尝试!(稍作修改,易于使用)
输入和输出为字符代码。这对于任意大小的像元更有用,但在有限的像元大小中仍可以使用较小的值。
Tape Format:
Counter 0 Copy Number Binary...
^End ^Start
,-[ Get input, decrement by 1 and start loop
<-> Initialises the copy of the value at -1
[[>]+<[-<]>>] Converts the input to binary while preserving a negative copy
<+>>[-<<[++>+<]>->] If the last digit of the binary is 1 (n-1 is odd), divide by 2 and decrement
<<[+>+++<] If the last digit of the binary is 0 (n-1 is even), multiply by 3
<<+>>> Increment counter and end on n-1
]<<<. End loop and print counter
?(]$_)"){{?{*')}/&!/={:<$["/>&_(.<@2'%<>./>=
展开:
? ( ] $ _
) " ) { { ?
{ * ' ) } / &
! / = . { < $ [
" / > & _ ( . < @
2 ' % < > : / >
= . . . . . .
. . . . . .
. . . . .
需要注意的是失败的1
了呃...... 原因。老实说,我现在还不确定该如何工作。我所知道的是,奇数代码向后运行为偶数?不知何故?
新版本比以前的版本干净得多,但与之相比,它的方向要多一些,并且还会导致被零除的错误。唯一不会出错的情况是它1
正确处理时。
If a number < 2 is input ... output does not matter.
:o)
{i::0;{x>1}{i+:1;$[x mod 2;1+3*x;(_)x%2]}\x;i}
(#)1_(1<){(1+3*x;x%2)0=x mod 2}\
这是一个递归函数。输入读数单独提供。
int c(n){return n==1?0:1+(n%2?c(n*3+1):c(n/2));}
我敢肯定我可以用这些== 0
东西做一些“和/或”把戏,但是我不知道怎么做。
==0
并交换有条件的边
n==1
因为我在问题中指定数字始终大于1
n==1
是基本递归的情况。放在n==2
那里并不会提高分数。
return~-n?
并交换条件边
n==1
== n<2
。
递归函数方法,根据Valentin CLEMENT和daniero:40个字符
sub f(\n){n>1&&1+f n%2??3*n+1!!n/2}(get)
延迟列表方法:32个字符
+(get,{$_%2??$_*3+1!!$_/2}...^1)
\ln;
\::2%:@5*1+2,*+:2=?
像其他> <>答案一样,这会在堆栈上构建序列。一旦序列达到2,堆栈的大小就是执行的步骤数。
感谢@Hohmannfan,通过一种非常聪明的方法直接计算下一个值节省了3个字节。用于计算序列中下一个值的公式为:
分数将偶数映射为0.5,将奇数映射为3。乘以n
和相加即可n%2
完成计算-完全不需要选择下一个值!
编辑2:这是@Hohmannfan之前的版本:
\ln;
\:::3*1+@2,@2%?$~:2=?
这里的技巧是在序列的每个步骤中都计算3n+1
和n/2
,然后选择要从序列中删除的一个。这意味着直到达到1才需要分支代码,并且序列的计算可以驻留在一行代码上。
编辑:意识到可能会导致1的唯一正整数是2之后,打掉另一个字符。由于程序的输出对于输入<2无关紧要,序列生成可以在达到2时结束,从而保留堆栈大小是所需的确切步骤数。
先前版本:
\~ln;
\:::3*1+@2,@2%?$~:1=?
\::2%:@5*1+2,*+:2=?
1+
是的特例)
。