受http://xkcd.com/710/的启发,这是一个高尔夫代码。
挑战
给定大于0的正整数,打印出该数字的冰雹序列。
冰雹序列
有关详细信息,请参阅Wikipedia。
使用生成的数字重复此操作,直至达到1.(如果在1之后继续,它将进入无限循环1 -> 4 -> 2 -> 1...
)
有时候代码是最好的解释方式,所以这里有一些来自维基百科
function collatz(n)
show n
if n > 1
if n is odd
call collatz(3n + 1)
else
call collatz(n / 2)
此代码有效,但我正在增加额外的挑战。 程序不得容易受到堆栈溢出的影响。所以它必须使用迭代或尾递归。
此外,奖励点是因为它可以计算大数字并且语言尚未实现。 (或者如果使用固定长度的整数重新实现大数字支持)
测试用例
Number: 21
Results: 21 -> 64 -> 32 -> 16 -> 8 -> 4 -> 2 -> 1
Number: 3
Results: 3 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1
此外,代码高尔夫必须包括完整的用户输入和输出。
答案 0 :(得分:129)
;
; To assemble and link this program, just run:
;
; >> $ nasm -f elf collatz.asm && gcc -o collatz collatz.o
;
; You can then enjoy its output by passing a number to it on the command line:
;
; >> $ ./collatz 123
; >> 123 --> 370 --> 185 --> 556 --> 278 --> 139 --> 418 --> 209 --> 628 --> 314
; >> --> 157 --> 472 --> 236 --> 118 --> 59 --> 178 --> 89 --> 268 --> 134 --> 67
; >> --> 202 --> 101 --> 304 --> 152 --> 76 --> 38 --> 19 --> 58 --> 29 --> 88
; >> --> 44 --> 22 --> 11 --> 34 --> 17 --> 52 --> 26 --> 13 --> 40 --> 20 --> 10
; >> --> 5 --> 16 --> 8 --> 4 --> 2 --> 1
;
; There's even some error checking involved:
; >> $ ./collatz
; >> Usage: ./collatz NUMBER
;
section .text
global main
extern printf
extern atoi
main:
cmp dword [esp+0x04], 2
jne .usage
mov ebx, [esp+0x08]
push dword [ebx+0x04]
call atoi
add esp, 4
cmp eax, 0
je .usage
mov ebx, eax
push eax
push msg
.loop:
mov [esp+0x04], ebx
call printf
test ebx, 0x01
jz .even
.odd:
lea ebx, [1+ebx*2+ebx]
jmp .loop
.even:
shr ebx, 1
cmp ebx, 1
jne .loop
push ebx
push end
call printf
add esp, 16
xor eax, eax
ret
.usage:
mov ebx, [esp+0x08]
push dword [ebx+0x00]
push usage
call printf
add esp, 8
mov eax, 1
ret
msg db "%d --> ", 0
end db "%d", 10, 0
usage db "Usage: %s NUMBER", 10, 0
答案 1 :(得分:64)
&>:.:1-|
>3*^ @
|%2: <
v>2/>+
答案 2 :(得分:52)
LOLCODE:406 CHARAKTERZE
HAI
BTW COLLATZ SOUNDZ JUS LULZ
CAN HAS STDIO?
I HAS A NUMBAR
BTW, I WANTS UR NUMBAR
GIMMEH NUMBAR
VISIBLE NUMBAR
IM IN YR SEQUENZ
MOD OF NUMBAR AN 2
BOTH SAEM IT AN 0, O RLY?
YA RLY, NUMBAR R QUOSHUNT OF NUMBAR AN 2
NO WAI, NUMBAR R SUM OF PRODUKT OF NUMBAR AN 3 AN 1
OIC
VISIBLE NUMBAR
DIFFRINT 2 AN SMALLR OF 2 AN NUMBAR, O RLY?
YA RLY, GTFO
OIC
IM OUTTA YR SEQUENZ
KTHXBYE
JUSTIN J. MEZA'S INTERPRETR下的测试。 KTHXBYE!
答案 3 :(得分:51)
显然不会产生堆栈溢出。
n=input()
while n>1:n=(n/2,n*3+1)[n%2];print n
答案 4 :(得分:23)
我决定有点反竞争,并展示你通常如何在Perl中编写这样的问题。
最后还有一个46(总)char code-golf条目。
前三个例子都是从这个标题开始的。
#! /usr/bin/env perl
use Modern::Perl;
# which is the same as these three lines:
# use 5.10.0;
# use strict;
# use warnings;
while( <> ){
chomp;
last unless $_;
Collatz( $_ );
}
简单的递归版
use Sub::Call::Recur;
sub Collatz{
my( $n ) = @_;
$n += 0; # ensure that it is numeric
die 'invalid value' unless $n > 0;
die 'Integer values only' unless $n == int $n;
say $n;
given( $n ){
when( 1 ){}
when( $_ % 2 != 0 ){ # odd
recur( 3 * $n + 1 );
}
default{ # even
recur( $n / 2 );
}
}
}
简单的迭代版
sub Collatz{
my( $n ) = @_;
$n += 0; # ensure that it is numeric
die 'invalid value' unless $n > 0;
die 'Integer values only' unless $n == int $n;
say $n;
while( $n > 1 ){
if( $n % 2 ){ # odd
$n = 3 * $n + 1;
} else { #even
$n = $n / 2;
}
say $n;
}
}
优化的迭代版
sub Collatz{
my( $n ) = @_;
$n += 0; # ensure that it is numeric
die 'invalid value' unless $n > 0;
die 'Integer values only' unless $n == int $n;
#
state @next;
$next[1] //= 0; # sets $next[1] to 0 if it is undefined
#
# fill out @next until we get to a value we've already worked on
until( defined $next[$n] ){
say $n;
#
if( $n % 2 ){ # odd
$next[$n] = 3 * $n + 1;
} else { # even
$next[$n] = $n / 2;
}
#
$n = $next[$n];
}
say $n;
# finish running until we get to 1
say $n while $n = $next[$n];
}
现在,我将展示如何使用v5.10.0之前的Perl版本完成最后一个示例
#! /usr/bin/env perl
use strict;
use warnings;
while( <> ){
chomp;
last unless $_;
Collatz( $_ );
}
{
my @next = (0,0); # essentially the same as a state variable
sub Collatz{
my( $n ) = @_;
$n += 0; # ensure that it is numeric
die 'invalid value' unless $n > 0;
# fill out @next until we get to a value we've already worked on
until( $n == 1 or defined $next[$n] ){
print $n, "\n";
if( $n % 2 ){ # odd
$next[$n] = 3 * $n + 1;
} else { # even
$next[$n] = $n / 2;
}
$n = $next[$n];
}
print $n, "\n";
# finish running until we get to 1
print $n, "\n" while $n = $next[$n];
}
}
首先关闭IO始终是缓慢的部分。因此,如果您实际对它们进行基准测试,那么您应该获得与每个基准相同的速度。
为了测试这些,我打开了/dev/null
($null
)的文件句柄,并编辑了每个say $n
而不是say {$null} $n
。这是为了减少对IO的依赖。
#! /usr/bin/env perl
use Modern::Perl;
use autodie;
open our $null, '>', '/dev/null';
use Benchmark qw':all';
cmpthese( -10,
{
Recursive => sub{ Collatz_r( 31 ) },
Iterative => sub{ Collatz_i( 31 ) },
Optimized => sub{ Collatz_o( 31 ) },
});
sub Collatz_r{
...
say {$null} $n;
...
}
sub Collatz_i{
...
say {$null} $n;
...
}
sub Collatz_o{
...
say {$null} $n;
...
}
运行10次之后,这是一个代表性的样本输出:
Rate Recursive Iterative Optimized Recursive 1715/s -- -27% -46% Iterative 2336/s 36% -- -27% Optimized 3187/s 86% 36% --
最后,真正的代码高尔夫球场:
perl -nlE'say;say$_=$_%2?3*$_+1:$_/2while$_>1'
总共46个字符
如果您不需要打印起始值,则可以删除5个以上的字符。
perl -nE'say$_=$_%2?3*$_+1:$_/2while$_>1'
总共41个字符
实际代码部分的 31个字符,但没有-n
开关,代码将无法工作。所以我将整个例子包含在我的计数中。
答案 5 :(得分:23)
c 1=[1]
c n=n:c(div(n`mod`2*(5*n+2)+n)2)
main=readLn>>=print.c
用户输入,打印输出,使用常量内存和堆栈,使用任意大整数。
这段代码的A sample run,给出了所有'1'(!)作为输入的80位数字,看起来非常有趣。
原创,仅限功能版本:
Haskell 51 chars
f n=n:[[],f([n`div`2,3*n+1]!!(n`mod`2))]!!(1`mod`n)
@&amp; ^#究竟是谁需要条件?
(编辑:我是“聪明”并使用修复。没有它,代码下降到54个字符。
edit2:通过分解f()
)
答案 6 :(得分:22)
~{(}{3*).1&5*)/}/1+`
#
# Usage: echo 21 | ruby golfscript.rb collatz.gs
这相当于
stack<int> s;
s.push(21);
while (s.top() - 1) {
int x = s.top();
int numerator = x*3+1;
int denominator = (numerator&1) * 5 + 1;
s.push(numerator/denominator);
}
s.push(1);
return s;
答案 7 :(得分:19)
我想这类问题是bc
发明的:
for(n=read();n>1;){if(n%2)n=n*6+2;n/=2;n}
测试:
bc1 -q collatz.bc
21
64
32
16
8
4
2
1
正确的代码:
for(n=read();n>1;){if(n%2)n=n*3+1else n/=2;print n,"\n"}
bc
处理的数字最多为 INT_MAX
位数
修改 Wikipedia article提到此猜想已检查所有值 20x2 58 (aprox。 5.76e18 )。这个计划:
c=0;for(n=2^20000+1;n>1;){if(n%2)n=n*6+2;n/=2;c+=1};n;c
在 68 秒内测试 2 20,000 +1 (aprox。 3.98e6,020 ) > 144,404 周期。
答案 8 :(得分:16)
perl -nE 'say$_=$_%2?$_*3+1:$_/2while$_>1'
# 123456789 123456789 123456789 1234567
编辑删除2个不必要的空格。
编辑删除1个不必要的空间。
答案 9 :(得分:15)
MS Excel,35个字符
=IF(A1/2=ROUND(A1/2,0),A1/2,A1*3+1)
直接从Wikipedia:
In cell A1, place the starting number.
In cell A2 enter this formula =IF(A1/2=ROUND(A1/2,0),A1/2,A1*3+1)
Drag and copy the formula down until 4, 2, 1
只需复制/粘贴公式111次即可得到起始编号为1000的结果。;)
答案 10 :(得分:14)
main(x){for(scanf("%d",&x);x>=printf("%d,",x);x=x&1?3*x+1:x/2);}
#include <stdlib.h>
#define B (w>=m?d=realloc(d,m=m+m):0)
#define S(a,b)t=a,a=b,b=t
main(m,w,i,t){char*d=malloc(m=9);for(w=0;(i=getchar()+2)/10==5;)
B,d[w++]=i%10;for(i=0;i<w/2;i++)S(d[i],d[w-i-1]);for(;;w++){
while(w&&!d[w-1])w--;for(i=w+1;i--;)putchar(i?d[i-1]+48:10);if(
w==1&&*d==1)break;if(*d&1){for(i=w;i--;)d[i]*=3;*d+=1;}else{
for(i=w;i-->1;)d[i-1]+=d[i]%2*10,d[i]/=2;*d/=2;}B,d[w]=0;for(i=0
;i<w;i++)d[i+1]+=d[i]/10,d[i]%=10;}}
注意:在没有至少原型化malloc / realloc的情况下不要删除#include <stdlib.h>
,因为这样做在64位平台上是不安全的(64位void *将被转换为32位int)。
这个尚未经过大力测试。它也可以使用一些缩短。
以前的版本:
main(x){for(scanf("%d",&x);printf("%d,",x),x-1;x=x&1?3*x+1:x/2);} // 66
(删除了12个字符,因为没有人遵循输出格式......:|)
答案 11 :(得分:12)
另一个汇编程序版本。这个数字不限于32位数字,它可以处理最多10个 65534 的数字,尽管MS-DOS使用的“.com”格式限制为80位数字。为A86汇编程序编写,需要运行Win-XP DOS框。汇编为180字节:
mov ax,cs
mov si,82h
add ah,10h
mov es,ax
mov bh,0
mov bl,byte ptr [80h]
cmp bl,1
jbe ret
dec bl
mov cx,bx
dec bl
xor di,di
p1:lodsb
sub al,'0'
cmp al,10
jae ret
stosb
loop p1
xor bp,bp
push es
pop ds
p2:cmp byte ptr ds:[bp],0
jne p3
inc bp
jmp p2
ret
p3:lea si,[bp-1]
cld
p4:inc si
mov dl,[si]
add dl,'0'
mov ah,2
int 21h
cmp si,bx
jne p4
cmp bx,bp
jne p5
cmp byte ptr [bx],1
je ret
p5:mov dl,'-'
mov ah,2
int 21h
mov dl,'>'
int 21h
test byte ptr [bx],1
jz p10
;odd
mov si,bx
mov di,si
mov dx,3
dec bp
std
p6:lodsb
mul dl
add al,dh
aam
mov dh,ah
stosb
cmp si,bp
jnz p6
or dh,dh
jz p7
mov al,dh
stosb
dec bp
p7:mov si,bx
mov di,si
p8:lodsb
inc al
xor ah,ah
aaa
stosb
or ah,ah
jz p9
cmp si,bp
jne p8
mov al,1
stosb
jmp p2
p9:inc bp
jmp p2
p10:mov si,bp
mov di,bp
xor ax,ax
p11:lodsb
test ah,1
jz p12
add al,10
p12:mov ah,al
shr al,1
cmp di,bx
stosb
jne p11
jmp p2
答案 12 :(得分:10)
dc
是这个序列的好工具:
?[d5*2+d2%*+2/pd1<L]dsLx
dc -f collatz.dc 21 64 32 16 8 4 2 1
另外24个字符使用Golfscript条目中的公式:
?[3*1+d2%5*1+/pd1<L]dsLx
57个字符符合规格:
[Number: ]n?[Results: ]ndn[d5*2+d2%*+2/[ -> ]ndnd1<L]dsLx
dc -f collatz-spec.dc Number: 3 Results: 3 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1
答案 13 :(得分:9)
计划:72
(define(c n)(if(= n 1)`(1)(cons n(if(odd? n)(c(+(* n 3)1))(c(/ n 2))))))
这使用递归,但调用是尾递归的,所以我认为它们将被优化为迭代。在一些快速测试中,我无法找到堆栈溢出的数字。仅举例:
(c 9876543219999999999000011234567898888777766665555444433332222 7777777777777777777777777777777798797657657651234143375987342987 5398709812374982529830983743297432985230985739287023987532098579 058095873098753098370938753987)
......运行得很好。 [这是所有一个数字 - 我刚刚打破它以适应屏幕。]
答案 14 :(得分:8)
c=NestWhileList[If[OddQ@#,3#+1,#/2]&,#,#>1&]&
答案 15 :(得分:7)
基本上是makapuf's Python solution的直接翻录:
def c(n)while n>1;n=n.odd?? n*3+1: n/2;p n end end
基本上是直接翻录问题中提供的代码:
def c(n)p n;n.odd?? c(3*n+1):c(n/2)if n>1 end
答案 16 :(得分:7)
Python 45 Char
从makapuf的回答中删除了一个字符。
n=input()
while~-n:n=(n/2,n*3+1)[n%2];print n
答案 17 :(得分:7)
import java.math.BigInteger;
public class SortaJava {
static final BigInteger THREE = new BigInteger("3");
static final BigInteger TWO = new BigInteger("2");
interface BiFunc<R, A, B> {
R call(A a, B b);
}
interface Cons<A, B> {
<R> R apply(BiFunc<R, A, B> func);
}
static class Collatz implements Cons<BigInteger, Collatz> {
BigInteger value;
public Collatz(BigInteger value) { this.value = value; }
public <R> R apply(BiFunc<R, BigInteger, Collatz> func) {
if(BigInteger.ONE.equals(value))
return func.call(value, null);
if(value.testBit(0))
return func.call(value, new Collatz((value.multiply(THREE)).add(BigInteger.ONE)));
return func.call(value, new Collatz(value.divide(TWO)));
}
}
static class PrintAReturnB<A, B> implements BiFunc<B, A, B> {
boolean first = true;
public B call(A a, B b) {
if(first)
first = false;
else
System.out.print(" -> ");
System.out.print(a);
return b;
}
}
public static void main(String[] args) {
BiFunc<Collatz, BigInteger, Collatz> printer = new PrintAReturnB<BigInteger, Collatz>();
Collatz collatz = new Collatz(new BigInteger(args[0]));
while(collatz != null)
collatz = collatz.apply(printer);
}
}
答案 18 :(得分:5)
不是最短的,而是一种新颖的方法。对于大型序列来说肯定要大幅减速,但它不应该溢出。
PROGRAM:COLLATZ
:ClrHome
:Input X
:Lbl 1
:While X≠1
:If X/2=int(X/2)
:Then
:Disp X/2→X
:Else
:Disp X*3+1→X
:End
:Goto 1
:End
答案 19 :(得分:4)
使用nroff -U hail.g
.warn
.pl 1
.pso (printf "Enter a number: " 1>&2); read x; echo .nr x $x
.while \nx>1 \{\
. ie \nx%2 .nr x \nx*3+1
. el .nr x \nx/2
\nx
.\}
1。 groff版
答案 20 :(得分:4)
Scala + Scalaz
import scalaz._
import Scalaz._
val collatz =
(_:Int).iterate[Stream](a=>Seq(a/2,3*a+1)(a%2)).takeWhile(1<) // This line: 61 chars
行动中:
scala> collatz(7).toList
res15: List[Int] = List(7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2)
Scala 2.8
val collatz =
Stream.iterate(_:Int)(a=>Seq(a/2,3*a+1)(a%2)).takeWhile(1<) :+ 1
这也包括尾随1。
scala> collatz(7)
res12: scala.collection.immutable.Stream[Int] = Stream(7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1)
使用以下隐式
implicit def intToEven(i:Int) = new {
def ~(even: Int=>Int, odd: Int=>Int) = {
if (i%2==0) { even(i) } else { odd(i) }
}
}
这可以缩短为
val collatz = Stream.iterate(_:Int)(_~(_/2,3*_+1)).takeWhile(1<) :+ 1
编辑 - 58个字符(包括输入和输出,但不包括初始编号)
var n=readInt;while(n>1){n=Seq(n/2,n*3+1)(n%2);println(n)}
如果您不需要换行,可以减少2 ...
答案 21 :(得分:4)
不是最短的,而是优雅的clojure解决方案
(defn collatz [n]
(print n "")
(if (> n 1)
(recur
(if (odd? n)
(inc (* 3 n))
(/ n 2)))))
答案 22 :(得分:4)
c 1=[1];c n=n:(c$if odd n then 3*n+1 else n`div`2)
答案 23 :(得分:4)
支持bignum,堆栈溢出易感性:
def c(n)p n;n%2>0?c(3*n+1):c(n/2)if n>1 end
...还有50个字符,支持bignum,没有堆栈溢出:
def d(n)while n>1 do p n;n=n%2>0?3*n+1:n/2 end end
感谢乔丹。我不知道'p'代替看跌期权。
答案 24 :(得分:4)
C#:216个字符
using C=System.Console;class P{static void Main(){var p="start:";System.Action<object> o=C.Write;o(p);ulong i;while(ulong.TryParse(C.ReadLine(),out i)){o(i);while(i > 1){i=i%2==0?i/2:i*3+1;o(" -> "+i);}o("\n"+p);}}}
长篇:
using C = System.Console;
class P
{
static void Main()
{
var p = "start:";
System.Action<object> o = C.Write;
o(p);
ulong i;
while (ulong.TryParse(C.ReadLine(), out i))
{
o(i);
while (i > 1)
{
i = i % 2 == 0 ? i / 2 : i * 3 + 1;
o(" -> " + i);
}
o("\n" + p);
}
}
}
新版本,通过命令行接受一个数字作为输入,无输入验证。 173 154个字符。
using System;class P{static void Main(string[]a){Action<object>o=Console.Write;var i=ulong.Parse(a[0]);o(i);while(i>1){i=i%2==0?i/2:i*3+1;o(" -> "+i);}}}
长篇:
using System;
class P
{
static void Main(string[]a)
{
Action<object>o=Console.Write;
var i=ulong.Parse(a[0]);
o(i);
while(i>1)
{
i=i%2==0?i/2:i*3+1;
o(" -> "+i);
}
}
}
我可以通过在answer中删除想法来使用for循环而不是一段时间来削减一些字符。 150个字符。
using System;class P{static void Main(string[]a){Action<object>o=Console.Write;for(var i=ulong.Parse(a[0]);i>1;i=i%2==0?i/2:i*3+1)o(i+" -> ");o(1);}}
答案 25 :(得分:3)
@set/pd=
:l
@set/ad=(d+d%%2*(d*5+2))/2&echo %d%&if %d% NEQ 1 goto:l
答案 26 :(得分:3)
与其他JS(以及大多数其他语言)不同,这个实际上遵循输出中的->
。
for(s='',c=' -> ',i=readline();i>1;i=i%2?i*3+1:i/2)s+=i+c
print(s+1)
如果我们避免这种情况,这是 53 char 替代方案,每行打印一个数字:
for(p=print,i=readline(),p(i);i>1;)p(i=i%2?i*3+1:i/2)
想要使用SpiderMonkey运行:
echo 21 | js thisfile.js
21 -> 64 -> 32 -> 16 -> 8 -> 4 -> 2 -> 1
答案 27 :(得分:3)
using System.Linq;using C=System.Console;class Program{static void Main(){var v=C.ReadLine();C.Write(v);while(v!="1"){C.Write("->");if(v[v.Length-1]%2==0){v=v.Aggregate(new{s="",o=0},(r,c)=>new{s=r.s+(char)((c-48)/2+r.o+48),o=(c%2)*5}).s.TrimStart('0');}else{var q=v.Reverse().Aggregate(new{s="",o=0},(r, c)=>new{s=(char)((c-48)*3+r.o+(c*3+r.o>153?c*3+r.o>163?28:38:48))+r.s,o=c*3+r.o>153?c*3+r.o>163?2:1:0});var t=(q.o+q.s).TrimStart('0').Reverse();var x=t.First();q=t.Skip(1).Aggregate(new{s=x>56?(x-57).ToString():(x-47).ToString(),o=x>56?1:0},(r,c)=>new{s=(char)(c-48+r.o+(c+r.o>57?38:48))+r.s,o=c+r.o>57?1:0});v=(q.o+q.s).TrimStart('0');}C.Write(v);}}}
<强> Ungolfed 强>
using System.Linq;
using C = System.Console;
class Program
{
static void Main()
{
var v = C.ReadLine();
C.Write(v);
while (v != "1")
{
C.Write("->");
if (v[v.Length - 1] % 2 == 0)
{
v = v
.Aggregate(
new { s = "", o = 0 },
(r, c) => new { s = r.s + (char)((c - 48) / 2 + r.o + 48), o = (c % 2) * 5 })
.s.TrimStart('0');
}
else
{
var q = v
.Reverse()
.Aggregate(
new { s = "", o = 0 },
(r, c) => new { s = (char)((c - 48) * 3 + r.o + (c * 3 + r.o > 153 ? c * 3 + r.o > 163 ? 28 : 38 : 48)) + r.s, o = c * 3 + r.o > 153 ? c * 3 + r.o > 163 ? 2 : 1 : 0 });
var t = (q.o + q.s)
.TrimStart('0')
.Reverse();
var x = t.First();
q = t
.Skip(1)
.Aggregate(
new { s = x > 56 ? (x - 57).ToString() : (x - 47).ToString(), o = x > 56 ? 1 : 0 },
(r, c) => new { s = (char)(c - 48 + r.o + (c + r.o > 57 ? 38 : 48)) + r.s, o = c + r.o > 57 ? 1 : 0 });
v = (q.o + q.s)
.TrimStart('0');
}
C.Write(v);
}
}
}
答案 28 :(得分:3)
使用ruby -n hail
n=$_.to_i
(n=n%2>0?n*3+1: n/2
p n)while n>1
答案 29 :(得分:3)
程序frm Jerry Coffin有整数溢出,试试这个:
#include <iostream>
int main(unsigned long long i)
{
int j = 0;
for( std::cin>>i; i>1; i = i&1? i*3+1:i/2, ++j)
std::cout<<i<<" -> ";
std::cout<<"\n"<<j << " iterations\n";
}
用进行测试
总停止时间最长的不到1亿的数字是63,728,127,步数为949步。
总停止时间最长的不到10亿的数字为670,617,279,步数为986.
答案 30 :(得分:3)
Common Lisp,141个字符:
(defun c ()
(format t"Number: ")
(loop for n = (read) then (if(oddp n)(+ 1 n n n)(/ n 2))
until (= n 1)
do (format t"~d -> "n))
(format t"1~%"))
试运行:
Number: 171
171 -> 514 -> 257 -> 772 -> 386 -> 193 -> 580 -> 290 -> 145 -> 436 ->
218 -> 109 -> 328 -> 164 -> 82 -> 41 -> 124 -> 62 -> 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
答案 31 :(得分:3)
let c=Seq.unfold(function|n when n<=1->None|n when n%2=0->Some(n,n/2)|n->Some(n,(3*n)+1))
> c 21;;
val it : seq<int> = seq [21; 64; 32; 16; ...]
或者,如果您没有使用F#interactive来显示结果,则包含102个字符:
let c=Seq.unfold(function|n when n<=1->None|n when n%2=0->Some(n,n/2)|n->Some(n,(3*n)+1))>>printf"%A"
答案 32 :(得分:2)
Ruby,41个字符
n=gets.to_i
p n=[n/2,n*3+1][n%2]while n>1
答案 33 :(得分:2)
在我读完Pickover书中的序列之后,我实际上大约两年前写了这个程序。我清理了一下,这是我能做到的最小的,仍然有用户输入和一个漂亮的,可读的输出:
<?$n=fgets(STDIN);while($n!=1){$n=(($n&1)==0)?($n/2):(($n*3)+1);echo"$n\n";}?>
必须假设启用了短标签,而我不确定输入是否适用于所有控制台。但它在我的Windows机器上完美运行。
更新:通过稍微欺骗数学,我们可以减少一些角色:
<?$n=fgets(STDIN);while($n!=1){$n=(($n&1)==0)?$n/2:$n*3+1;echo"$n\n";}?>
<强>更新强>
$n&1
返回1
或0
,我们可以利用PHP的松散类型并删除更多字符。?>
,我们可以删除另外两个字符:最终结果:
<?$n=fgets(STDIN);while($n>1){$n=(!($n&1))?$n/2:$n*3+1;echo"$n\n";}
答案 34 :(得分:2)
n=1
1 if(n==1)read*,n
n=merge(n/2,3*n+1,mod(n,2)==0)
print*,n
goto1
end
因为有人必须这样做:)
计数包括所需的换行符。完全符合Fortran 95(及更高版本)代码。包括完整的I / O,并且可以根据需要执行多次!
使用goto编辑:少一个字符(为样式指点!)
答案 35 :(得分:2)
for(a=[i=prompt()];i-1;a.push(i=i%2?i*3+1:i/2));alert(a)
答案 36 :(得分:2)
n=input('');while n>1,n=n/2+rem(n,2)*(n*5+2)/2;disp(n);end
测试用例:
>> n=input('');while n>1,n=n/2+rem(n,2)*(n*5+2)/2;disp(n);end
21
64
32
16
8
4
2
1
答案 37 :(得分:2)
<强> PHP 强>
function Collatz($n)
{
$i = 0;
while($n>1)
{
if($n % 2)
{
$n = (3*$n) + 1;
$i++;
echo "step $i: $n <br/>";
}
else
{
$n = $n/2;
$i++;
echo "step $i: $n <br/>";
}
}
}
答案 38 :(得分:2)
由于对LOLCODE解决方案似乎有点兴趣,我想我会用这种语言比较两种解决方案(迭代和尾递归)的实现。
首先,有203个字符的迭代解决方案:
HAI 1.2
I HAS A n
GIMMEH n
IM IN YR l
VISIBLE n
BOTH SAEM 1 BIGGR OF 1 n
O RLY?
YA RLY
GTFO
OIC
MOD OF n 2
WTF?
OMG 0
n R QUOSHUNT OF n 2
GTFO
OMG 1
n R SUM OF 1 PRODUKT OF 3 n
OIC
IM OUTTA YR l
KTHXBYE
为您提供有关正在发生的事情的要点:
GIMMEH
关键字IM IN YR <loopname>
和IM OUTTA YR <loopname>
语句VISIBLE
用于打印到STDOUT O RLY?
,YA RLY
和OIC
语句处理条件If / Then / Else逻辑WTF?
,OMG <expression>
和OIC
语句处理条件切换/案例逻辑<variable> R <value>
然后有一个尾递归解决方案,设法削减2个额外的字符,最终计数为201:
HAI 1.2
HOW DUZ I c YR n
VISIBLE n
DIFFRINT 1 BIGGR OF 1 n
O RLY?
YA RLY
MOD OF n 2
WTF?
OMG 0
c QUOSHUNT OF n 2
GTFO
OMG 1
c SUM OF 1 PRODUKT OF 3 n
OIC
OIC
IF U SAY SO
I HAS A i
GIMMEH i
c i
KTHXBYE
这里的差异是HOW DUZ I <funcname> YR <args>
和IF U SAY SO
语句之间的函数定义。使用<funcname> <args>
调用函数。
答案 39 :(得分:1)
的Python:
def collatz(n):
if (n%2) == 0:
return n/2
else:
return 3*n+1
def do_collatz(n):
while n > 1:
print n
n = collatz(n)
print n
do_collatz(int(input("Start number: ")))
不容易受到堆栈溢出的影响,但不会在不收敛于1的序列上终止。 (编辑:忘记输入部分)
答案 40 :(得分:1)
TextWindow.Write( "Number: " )
n = TextWindow.ReadNumber()
TextWindow.Write( "Results: " )
While ( n > 1 )
TextWindow.Write( n + " -> " )
If Math.Remainder( n, 2 ) = 0 Then
n = n / 2
Else
n = n * 3 + 1
EndIf
EndWhile
TextWindow.WriteLine(1)
您可以在以下位置运行: http://smallbasic.com/program/?ZZR544
答案 41 :(得分:1)
Perl,59个字符:
sub c{print my$x="@_\n";@_=$x&1?$x*3+1:$x/2,goto&c if$x!=1}
答案 42 :(得分:1)
VB.Net ,大约180个字符
Sub Main()
Dim q = New Queue(Of Integer)
q.Enqueue(CInt(Console.ReadLine))
Do
q.Enqueue(CInt(If(q.Peek Mod 2 = 0, q.Dequeue / 2, q.Dequeue * 3 + 1)))
Console.WriteLine(q.Peek)
Loop Until q.Peek = 1
End Sub
有趣的是将此代码转换为c#创建更多字符
使其在空的.vb文件(大约245个字符)中工作
Imports System.Collections.Generic
Imports System
Module m
Sub Main()
Dim q = New Queue(Of Integer)
q.Enqueue(CInt(Console.ReadLine))
Do
q.Enqueue(CInt(If(q.Peek Mod 2 = 0, q.Dequeue / 2, q.Dequeue * 3 + 1)))
Console.WriteLine(q.Peek)
Loop Until q.Peek = 1
End Sub
End Module
答案 43 :(得分:1)
J,45个字符
(-: * 0&=@(2&|)) + (1 + 3&*) * -.@(0&=@(2&|))
我不是J.的专家。因为平均值的函数是+ /%#,我确信这可以缩短。
答案 44 :(得分:1)
let rec f n=printfn "%A" n;if n>1I then if n%2I=0I then f(n/2I)else f(3I*n+1I)
答案 45 :(得分:1)
Bash,130包括空格和换行符:
#!/bin/bash
if [ $1 == 1 ]; then echo $1
else if [ $(($1%2)) == 0 ]; then n=$(($1/2))
else n=$(($1*3+1))
fi
echo "$1 -> `c $n`"
fi
这假定c是脚本文件的名称,它位于运行脚本的用户的路径中。
答案 46 :(得分:1)
1INPUT N
2N=(N+(N*5+2)*(N MOD 2))/2:?N:IF N>1GOTO 2
答案 47 :(得分:0)
((fn[n](prn n)(if(> n 1)(recur(if(odd? n)(+(* 3 n)1)(/ n 2)))))(read))
或者,使用适当的空格和缩进:
((fn [n]
(prn n)
(if (> n 1)
(recur
(if (odd? n)
(+ (* 3 n) 1)
(/ n 2)))))
(read))
recur
强制Clojure使用尾调用递归,因此没有堆栈溢出。使用任意大数字。包括输入和输出,但如果输入非数字:)它会崩溃。
注意:在发布我的回答后不久,我注意到另一个Clojure实现与几乎相同的算法。但是,由于那个不会试图做空,我会在这里留下我的答案,因为它的价值。
答案 48 :(得分:0)
Erlang,120个字符
-module (f).
-export ([f/1]).
f(1)->1;
f(N)->
io:format("~p ",[N]),
if N rem 2 =:= 0
->f(trunc(N/2));
true->f(3*N+1)
end.
试验:
f:f(171).
171 514 257 772 386 193 580 290 145 436 218 109 328 164 82 41 124 62 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
答案 49 :(得分:0)
Josl - 58个字符
由于尾递归,此版本不会出现堆栈溢出。
c dup println dup 1 > if dup odd? if 3 * 1+ else 2 / end c
使用:
main 21 c
或者,其他例子:
main
21 c
63,728,127 c
答案 50 :(得分:0)
感谢DankoDurbić为fgets(STDIN),希望你不要介意:)
<?$i=fgets(STDIN);while($i!=1){echo ($i=$i%2?$i*3+1:$i/=2),"\r\n";}?>
答案 51 :(得分:0)
int n=args[0] as int
while(n>1){println n=n%2==0?n/2:n*3+1}
实施例
$ ./collatz.groovy 5
16
8
4
2
1
更漂亮的输出( 66个字符)
int n=args[0] as int
while(n>1){print " -> ${n=n%2==0?n/2:n*3+1}"}
实施例
$ ./collatz.groovy 5
-> 16 -> 8 -> 4 -> 2 -> 1
答案 52 :(得分:0)
-:`(>:@(3&*))`1:@.(1&=+2&|)^:a:
用法:
-:`(>:@(3&*))`1:@.(1&=+2&|)^:a: 9
9 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
答案 53 :(得分:0)
(defun c(n)(if (eql n 1)'(1)(cons n(if(oddp n)(c(1+(* 3 n)))(c(/ n 2))))))
或者,写得不错,
(defun collatz (n)
(if (eql n 1)
'(1)
(cons n (if (oddp n)
(collatz (1+ (* 3 n)))
(collatz (/ n 2))))))
答案 54 :(得分:0)
[:n||l|l:=OrderedCollection with:1.[n>1]whileTrue:[l addLast:n.n:=n odd ifTrue:[3*n+1]ifFalse:[n/2]].l]
通过向所需参数发送消息#value:来调用:
[:n||l|l:=OrderedCollection with:1.[n>1]whileTrue:[l addLast:n.n:=n odd ifTrue:[3*n+1]ifFalse:[n/2]].l] value: 123
或者,更加理智:
[:n | | result |
result := OrderedCollection with: 1.
[n > 1] whileTrue: [
result addLast: n.
n := n odd ifTrue: [3*n + 1] ifFalse: [n / 2]].
result] value: 123
(正确的方法是将上面定义为Integer上的方法,所以你要说“123 collatz”,而不是匿名闭包。)
答案 55 :(得分:0)
n=gets.to_i
while(n>1) do n=((n%2)==1)?3*n+1:n/2;p n end
答案 56 :(得分:0)
Perl,59 Chars
$n=shift;for($i=1;$n>1;$i++){$n=$n%2==0?$n/2:$n*3+1;printf"%002s: %s\n",$i,$n;}
但是,我喜欢这个版本的79个字符(不计算空白)更好,因为它打印行号和迭代值:
$n = shift; for($i = 1; $n > 1; $i++){ $n = $n % 2 == 0 ? $n / 2 : $n*3 + 1; printf "%002s: %s\n", $i, $n;}
$n = shift;
for($i = 1; $n > 1; $i++){
$n = $n % 2 == 0 ? $n / 2 : $n*3 + 1;
printf "%002s: %s\n", $i, $n;
}
答案 57 :(得分:0)
read*,n
1 if(n/2*2<n)n=6*n+2
n=n/2
print*,n
if(n>1)goto1
end
答案 58 :(得分:0)
package main
import(."os"
."strconv")
func main(){n,_:=Atoi(Args[1])
println(n)
for n>1{if n%2!=0{n=n*3+1}else{n/=2}
println(n)}}
示例强>
./collatz 3
3
10
5
16
8
4
2
1
答案 59 :(得分:0)
main(x){scanf("%d",&x);while(x>printf("%d ",x=x&1?3*x+1:x/2));}
这是基于KennyTM的回答。 for循环被转换为while循环,代码进入while。
答案 60 :(得分:0)
迭代,精度取决于JS限制
var i=prompt('');while(i>1){console.log(i);i=(i%2)?3*i+1:i/2}
答案 61 :(得分:0)
另一个bash条目。不执行无限精度数学运算,它可能会溢出。
#!/bin/bash
x=$1;echo $x;((x>1))&&$0 $((x%2?x*3+1:x/2))
不应溢出的版本可能是
#!/bin/bash
x=$1;echo $x;((x>1))&&exec $0 $((x%2?x*3+1:x/2))
(编辑)一个迭代版本:
#!/bin/bash
for((x=$1;x>1;x=x%2?x*3+1:x/2));do echo $x;done
答案 62 :(得分:0)
<强>因子强>:
没有打高尔夫球
USE: math
: body ( n -- n ) >integer dup . "->" . dup odd? = [ 3 * 1 + ] [ 2 / ] if ;
: hailstone ( n -- ) dup 1 > [ body hailstone ] [ . ] if ;
21 hailstone
golfed:
21 [ dup 1 > ] [ >integer dup . "->" . dup 2 mod 1 = [ 3 * 1 + ] [ 2 / ] if ] while .
输出:
21
"->"
64
"->"
32
"->"
16
"->"
8
"->"
4
"->"
2
"->"
1
答案 63 :(得分:0)
VBScript:105个字符
显然我是一个受到侮辱的惩罚。
c(InputBox("?")) Public Sub c(i) msgbox(i) If i>1 Then If i mod 2=0 Then c(i/2) Else c(3*i+1) End If End If End Sub
答案 64 :(得分:0)
One-liner:
"Results: $(for($x=read-host Number;1%$x;$x=@($x/2;3*$x+1)[$x%2]){""$x ->""}) 1"
漂亮印刷:
"Results: $( for( $x = read-host Number; 1%$x; $x = @( $x/2; 3*$x+1 )[ $x%2 ] )
{
""$x ->""
}
) 1"
for($x=read-host;1%$x;$x=@($x/2;3*$x+1)[$x%2]){$x}1
答案 65 :(得分:0)
c n=" 1",if n=1
=" "++shownum(n)++c(n*3+1),if n mod 2=1
=" "++shownum(n)++c(n div 2),otherwise
(空格在语法上很重要)
答案 66 :(得分:0)
C ++ 113 100 95
#include <iostream>
int main(int i){for(std::cin>>i;i>1;i=i&1?i*3+1:i/2)std::cout<<i<<" -> ";}
答案 67 :(得分:0)
基于ar的代码,这是一个实际符合输出要求的perl版本
perl -E 'print"Number: ";$_=<STDIN>;chomp;print"Results: $_";$_=$_%2?$_*3+1:$_/2,print" -> ",$_ while$_!=1;say""'
长度:114计算perl调用和引号,104 withouit
我相信一些经验丰富的高尔夫球手可以进一步减少这种原油版本。
答案 68 :(得分:0)
void T(int i,string s){Console.Write("{0}{1}",s,i);if(i!=1)T(i%2==0?i/2:(i*3)+ 1,"->");}
加上这个初始调用
T(171, "");
这是一个非递归方法,我认为107个字符
void T2(int i){string s="";while(i>=1){Console.Write("{0}{1}",s,i);i=i==1?-1:i=i%2==0?i/2:(i*3)+1;s="->";}}
答案 69 :(得分:-6)