柯拉兹猜想(OEIS A006577)


66

这是Collat​​z猜想(OEIS A006577):

  • 以整数n > 1 开头。
  • 重复以下步骤:
    • 如果n为偶数,则将其除以2。
    • 如果n为奇数,则将其乘以3并加1。

事实证明,对于所有最多5 * 2 60或大约5764000000000000000的正整数,n最终将变为1

您的任务是找出达到1所需的迭代次数(减半或三倍加一)。

相关的xkcd :)

规则:

  • 最短的代码胜出。
  • 如果输入的数字<2,或者非整数或非数字,则输出无关紧要。

测试用例

2  -> 1
16 -> 4
5  -> 5
7  -> 16

Answers:



15

C- 50 47个字符

不幸的是,很少的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
$>

1
return~-a?1.省也正在b++?案件应保存b--
ugoren 2013年

呵呵你弯曲的规则,从而为创意P + 1,并用语言通常不用于高尔夫球:太多
门把手

谢谢ugoren!我写的时候一定喝醉了。:)
Fors

12

Perl 34(+1)个字符

$\++,$_*=$_&1?3+1/$_:.5while$_>1}{

$\像往常一样滥用最终输出。使用-p命令行选项运行,输入来自stdin

由于Elias Van Ootegem节省了一个字节。具体而言,观察到以下两个是等效的:

$_=$_*3+1
$_*=3+1/$_

虽然增加了一个字节,但通过缩短$_/2为just 节省了两个字节.5

用法示例:

$ echo 176 | perl -p collatz.pl
18

PHP 54字节

<?for(;1<$n=&$argv[1];$c++)$n=$n&1?$n*3+1:$n/2;echo$c;

Javascript的“木汤匙奖”的代名词似乎在这一挑战中有所欠缺。但是,这个问题没有很大的创造空间。输入被当作命令行参数。

用法示例:

$ php collatz.php 176
18

1
花了我一段时间才能弄清楚无与伦比的括号在做什么:)
marinus

1
重复$_三元似乎浪费,您可以通过使用剃掉另一个字符*=是这样的:$\++,$_*=$_&1?3+1/$_:.5while$_>1}{。相乘的1/$_效果与相同+1,因此$_*=3+1/$_效果很好
Elias Van Ootegem 2015年

@EliasVanOotegem太棒了$_*=3+1/$_,谢谢!
primo

11

Mathematica(35)

If[#>1,#0@If[OddQ@#,3#+1,#/2]+1,0]&

用法:

If[#>1,#0[If[OddQ@#,3#+1,#/2]]+1,0]&@16
>> 4

这不是有效的函数,10.3最终抱怨流氓@
CalculatorFeline

@引起争论,我不知道它为什么在那儿,只是快速编辑
英里

一定要小心:)
CalculatorFeline

10

和平常一样,我将从自己的答案开始。

JavaScript,46个 44个字符(在控制台上运行)

for(n=prompt(),c=1;n>1;n=n%2?n*3+1:n/2,++c)c

如果您说输出不是整数,那么~~ prompt()有什么意义?您可以通过摆脱~~来保存两个字符。
2013年

@Resorath Ah,忘记了JS的自动投影片:P谢谢
Doorknob

9

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。


1
您可以很容易地保存的长度i(,++y)。您可以使用<代替来另外保存两个==
彼得·泰勒

@PeterTaylor,您是对的,我的比较会用<缩短,但我不了解预递增的部分
jsedano

2
第二个三进制的两侧在结构上是相同的,因此您可以将三进制推入递归调用的第一个参数中。
彼得·泰勒

1
噢,我的
天哪太辉煌了

2
我知道它已经约3.5年,但你仍然可以通过高尔夫球其5个字节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字节的逗号。
凯文·克鲁伊森

9

雷布姆:28

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的参数)分配给Collat​​z条件的结果(IF-ELSE的结果是它选择的分支)的结果……循环中断。

J和K在Rebmu中初始化为零。并且如前所述,整个结果的取值为最终值。因此,程序结尾的J引用意味着您可以获得迭代次数。

用法:

>> rebmu/args [u[++jE1 AeEV?a[d2A][a1M3a]]j] 16
== 4

8

Python代表,48

我不相信这里的表达没有比短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

1
我的脑袋现在疼。
daniero

1
@daniero第二种解决方案只适合您。
2013年

哇哦 我很荣幸!
daniero

4
(n//2,n*3+1)[n%2]更短。
Evpok 2014年

1
@Evpok不能n/2正常运行,因为我们知道它可以运行吗?
乔治,

7

APL(31)

A←0⋄A⊣{2⊤⍵:1+3×⍵⋄⍵÷2}⍣{⍺=A+←1}⎕

答案仍然是27:{1=⍵:0⋄2|⍵:1+∇1+3×⍵⋄1+∇⍵÷2}
Uriel

1
{1=⍵:0⋄1+∇⊃⍵⌽0 1+.5 3×⍵}
ngn

7

J,30个字符

<:#-:`(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窃取<:将步数减一以符合问题要求。


6
每当我看到J提交内容时,我都会计算表情符号。这其中确实相当不错:<:#-::`(&*)=))^:
2013年

3
@primo不错; 想要他们的解释吗?:-) <:表示“减量”或“小于或等于”,#表示“计数”或“ n次”,-:表示“减半”或“ε等式”,:`(依次表示所述“减半”的末尾,在动名词和左括号中的两个动词(用于分组)。&*)表示“绑定到乘法的某物”(3与乘法绑定创建“乘以三”的运算符)和分组结束。=执行相等性检查,或一元意义上的自我分类。^:是幂级联(动词迭代)。由于许多J动词以冒号结尾,... :-)
John Dvorak

几年后...改进的循环块:'-&2#(>&1 *-:+ 2&| * +:+>:@-:)^:a:'-> -1个字符。:P
randomra

更多年后... <:#a:2&(<*|+|6&*%~)19字节(-11)
英里

6

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))


我已经待了很长时间了,但是我注意到通常人们每种编程语言都会发布1个答案。
jsedano

抱歉,我没有意识到:)
Valentin CLEMENT 2013年

编辑删除了Python之一。
Valentin CLEMENT

1
不对!人们倾向于每种编程语言发布一个答案,但这是因为他们正试图不直接与答案较短的其他人竞争。但是,如果您用相同的语言发布不同的答案,没有人会抱怨。
面包盒

@breadbox不正确。如果每种解决方案本身都比另一种有趣,我会用每种语言发布一个答案。如果两个解决方案都像它们一样有趣(相同的算法,没有有趣的语言技巧),我将它们作为一个发布。通常,我不会发布多个解决方案,因为我先选择一种语言,然后用该语言解决问题-然后我通常懒得用另一种语言编写相同的语言-或者我踏上了学习另一门编程的旅程语言。
约翰·德沃夏克

6

PowerShell:77 74 71 70 61

高尔夫代码:

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个字符。

Danko Durbic提供的提示:对于这种特殊情况,可以使用数组代替switch,以节省8个以上的字符!

没有错误检查非整数值或小于两个的整数。

如果您要审核脚本,请将脚本放在;$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

测试用例:

以下是一些启用了审核的示例。为了清楚起见,我还对输出进行了一些编辑,方法是在输入和最终计数中添加标签,并留出间距以分隔Collat​​z值。

---
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
---

关于输入数字的有趣部分,这些不是问题的测试案例中的内容:


2
真好!您仍然可以通过将其替换switch$i=(($i/2),($i*3+1))[$i%2]
DankoDurbić13年

2
另外,您不必转换read-host为数字,只需更改$i*3为即可3*$i
DankoDurbić2013年

数组而不是开关?辉煌!和交换$i*3-我为什么还没有想到呢?
Iszi 2013年

1
param($i)for(;$i-ne1;$x++){$i=(($i/2),(3*$i+1))[$i%2]}$x-将读取主机交换为参数,以获取56个字节在线尝试一下链接
TessellatingHeckler

6

80386汇编,16字节

本示例使用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

6

Brachylog,16个字节

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.


5

F#-65个字符

let rec c n=function 1->n|i->c(n+1)(if i%2=0 then i/2 else i*3+1)

5

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个字节。
Bakuriu

哦,你甚至可以比这更短:[n/2,3*n+1][n%2]
13年

那太好了!
Valentin CLEMENT 2013年

这是python 2.7吗?我在Python 3.5.1中收到错误?unsupported operand type(s) for -: 'str' and 'int'
乔治,

5

视网膜,43字节

11
2
(2+)1
$1$1$0$0$0$0
2.*
$0x
)`2
1
1?x
1

接受输入并以一元打印输出。

每行应转到其自己的文件。每个额外的文件1个字节添加到字节数中。

您可以将代码与-s标志一起作为一个文件运行。例如:

> echo -n 1111111|retina -s collatz
1111111111111111

该算法是一个循环,使用一进制数执行Collat​​z步骤,x如果数字不是1,则在字符串的末尾添加新的步骤标记。

当循环以结束时1,我们将标记转换1为所需输出的一元数(删除前导)。


5

果冻,不竞争

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.

4

dc,27个字符

应用布比的黑魔法

?[d3*1+d2%5*1+/d1<x]dsxxkzp

我真的不知道,如果我知道如何-或者 -它的工作原理。

用法:
$ dc collatz.dc <<< 7
16

dc,36个字符

我自己的创作;这是一种较为传统的方法,甚至在我不得不纠结于某种语言的情况下,也克服了语句缺乏else部分的缺点if

?[2/2Q]se[dd2%[0=e3*1+]xd1<x]dsxxkzp

在内部,它产生序列的所有编号并将它们存储在堆栈中,然后弹出最后一个1并显示堆栈高度。


1
平价不是黑魔法。

1
不,但这是一个非常巧妙的技巧!我本人实际上也做过类似的事情,在这种情况下我只是没有考虑过。令我失望的是除法,但我明白了:除以六,如果奇偶校验错误,则将第一个运算(* = 3,+ = 1)还原为第二个运算,并且由于整数除法,也走了,我们基本上已经完成/ = 2。非常聪明:)
daniero

1
+1。我以为我要用DC克服这个挑战,但最多只能达到40。我看到了您的27个答案。那好吧。
Digital Trauma 2014年

我没见过这个挑战,但是不久前写了一篇关于在DC中打印Collat​​z序列的博文。我的方法与您的方法相似,但会丢失一个字节,因此我真的看不出发布它的理由。但是,当我查看我的方法以了解如何轻松地从打印每个步骤到打印步骤数时,我发现可以从您的步骤中获取一个字节的东西...由于Collat​​z序列始终从2变为1,您可以将条件更改为2<x并摆脱k。以防万一您想在四年​​后退还一个字节。:D
brhfl

4

疯子59 56字节

,-[<->[[>]+<[-<]>>]>[-<<[++>+<]>->]<<[+>+++<]<<+>>>]<<<.

在线尝试!(稍作修改,易于使用)

输入和输出为字符代码。这对于任意大小的像元更有用,但在有限的像元大小中仍可以使用较小的值。

这个怎么运作

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

4

六角48 44字节

?(]$_)"){{?{*')}/&!/={:<$["/>&_(.<@2'%<>./>=

在线尝试!

展开:

     ? ( ] $ _
    ) " ) { { ?
   { * ' ) } / &
  ! / = . { < $ [
 " / > & _ ( . < @
  2 ' % < > : / >
   = . . . . . .
    . . . . . .
     . . . . .

需要注意的是失败的1了呃...... 原因。老实说,我现在还不确定该如何工作。我所知道的是,奇数代码向后运行为偶数?不知何故?

新版本比以前的版本干净得多,但与之相比,它的方向要多一些,并且还会导致被零除的错误。唯一不会出错的情况是它1正确处理时。


If a number < 2 is input ... output does not matter.:o)
Sok

@Sok Yep,这就是为什么我发布它而不是发疯地试图解决该问题的原因
Jo King

3

C,70 69个字符

很简单,没有花招。
从标准输入读取输入。

a;
main(b){
    for(scanf("%d",&b);b-1;b=b%2?b*3+1:b/2)a++;
    printf("%d",a);
}

3

Q 46

{i::0;{x>1}{i+:1;$[x mod 2;1+3*x;(_)x%2]}\x;i}

32个字节,带(#)1_(1<){(1+3*x;x%2)0=x mod 2}\
streetster

3

Ruby 1.9,49个字符

Rubyfied Valentin CLEMENT的Python答案,使用稳定的lambda语法。将其压缩为一个语句,以增加可读性。

(f=->n{n>1&&1+f[[n/2,3*n+1][n%2]]||0})[gets.to_i]

造成一些开销的原因是,Ruby与Python不同,对将数字与布尔值混合不满意。


3

C ++(51 48)

这是一个递归函数。输入读数单独提供。

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那里并不会提高分数。
Joe Z.

嗯,那么您可以将其替换为:return~-n?并交换条件边
门把手

n==1== n<2
CalculatorFeline

3

〜-〜!(无可奉告)-71 53

这种语言显然不适合打高尔夫球,因为它缺乏大量的本机功能,但这就是它的美。

'=|*;~~[*,~~~-~]*/~~|:''=|'''==~[*]'''='&''':''&*+~|:

首先,设置'''为您的输入。''然后可以使用%输入函数来调用该函数,并返回答案,如下所示:

'''=~~~~~:''&%:

这将返回~~~~~。它实际上适用于n==1(它与永远循环n==0)。

与这种语言一样,未经测试。


3

JavaScript(ES6)-29个字符

f=x=>x>1?f(x%2?x*3+1:x/2)+1:0

创建一个f接受单个参数并返回迭代次数的函数。

JavaScript-31个字符

for(c=0;n>1;n=n%2?n*3+1:n/2)++c

假定输入在变量中,n并创建一个c包含迭代次数的变量(并且还将c作为最后一条命令输出到控制台)。



3

Perl 6,40位元组

递归函数方法,根据Valentin CLEMENTdaniero40个字符

sub f(\n){n>1&&1+f n%2??3*n+1!!n/2}(get)

延迟列表方法:32个字符

+(get,{$_%2??$_*3+1!!$_/2}...^1)

3

> <>,27 26 23字节

\ln;
\::2%:@5*1+2,*+:2=?

像其他> <>答案一样,这会在堆栈上构建序列。一旦序列达到2,堆栈的大小就是执行的步骤数。

感谢@Hohmannfan,通过一种非常聪明的方法直接计算下一个值节省了3个字节。用于计算序列中下一个值的公式为:

f(n)=n5(nmod2)+12+(nmod2)

分数将偶数映射为0.5,将奇数映射为3。乘以n和相加即可n%2完成计算-完全不需要选择下一个值!

编辑2:这是@Hohmannfan之前的版本:

\ln;
\:::3*1+@2,@2%?$~:2=?

这里的技巧是在序列的每个步骤中都计算3n+1n/2,然后选择要从序列中删除的一个。这意味着直到达到1才需要分支代码,并且序列的计算可以驻留在一行代码上。

编辑:意识到可能会导致1的唯一正整数是2之后,打掉另一个字符。由于程序的输出对于输入<2无关紧要,序列生成可以在达到2时结束,从而保留堆栈大小是所需的确切步骤数。

先前版本:

\~ln;
\:::3*1+@2,@2%?$~:1=?

1
如果您进一步展开第二行,则可以打至23:\::2%:@5*1+2,*+:2=?
Hohmannfan 2016年
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.