language agnostic - Código Golf: Conjetura de Collatz
language-agnostic code-golf (30)
F #, 90 caracteres
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; ...]
O si no está utilizando F # interactivo para mostrar el resultado, 102 caracteres:
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"
Inspirado por http://xkcd.com/710/ aquí hay un código de golf para él.
El reto
Dado un entero positivo mayor que 0, imprima la secuencia de granizo para ese número.
La secuencia de Hailstone
Ver Wikipedia para más detalles ...
- Si el número es par, divídalo por dos.
- Si el número es impar, triplícalo y agrega uno.
Repita esto con el número producido hasta que llegue a 1. (si continúa después de 1, irá en un bucle infinito de 1 -> 4 -> 2 -> 1...
)
A veces, el código es la mejor manera de explicarlo, así que aquí hay algunos de Wikipedia
function collatz(n)
show n
if n > 1
if n is odd
call collatz(3n + 1)
else
call collatz(n / 2)
Este código funciona, pero estoy agregando un desafío adicional. El programa no debe ser vulnerable a desbordamientos de pila . Por lo tanto, debe usar iteración o recursividad de cola.
Además, puntos de bonificación por si puede calcular números grandes y el idioma aún no lo tiene implementado. (o si vuelve a implementar el soporte de números grandes usando enteros de longitud fija)
Caso de prueba
Number: 21
Results: 21 -> 64 -> 32 -> 16 -> 8 -> 4 -> 2 -> 1
Number: 3
Results: 3 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1
Además, el código de golf debe incluir la entrada y salida completa del usuario.
Perl
Decidí ser un poco anticompetitivo y mostrar cómo normalmente codificaría ese problema en Perl.
También hay un total de 46 (total) entrada de código de golf al final.
Estos primeros tres ejemplos comienzan con este encabezado.
#! /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( $_ );
}
Versión recursiva simple
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 ); } } }
Versión iterativa simple
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; } }
Versión iterativa optimizada
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]; }
Ahora voy a mostrar cómo harías ese último ejemplo con una versión de Perl anterior a v5.10.0
#! /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];
}
}
Punto de referencia
Primero de IO siempre va a ser la parte lenta. Por lo tanto, si realmente los compara como es, debería obtener la misma velocidad de cada uno.
Para probarlos, abrí un identificador de archivo a /dev/null
( $null
) y edité cada say $n
para leer en su lugar say {$null} $n
. Esto es para reducir la dependencia de 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;
...
}
Después de haberlo ejecutado 10 veces, aquí hay una salida de muestra representativa:
Rate Recursive Iterative Optimized Recursive 1715/s -- -27% -46% Iterative 2336/s 36% -- -27% Optimized 3187/s 86% 36% --
Finalmente, una entrada real de código de golf:
perl -nlE''say;say$_=$_%2?3*$_+1:$_/2while$_>1''
46 caracteres en total
Si no necesita imprimir el valor de inicio, puede eliminar 5 caracteres más.
perl -nE''say$_=$_%2?3*$_+1:$_/2while$_>1''
41 caracteres en total
31 caracteres para la parte del código real, pero el código no funcionará sin el -n
. Entonces incluyo todo el ejemplo en mi conteo.
Python - 95 64 51 46 char
Obviamente no produce un desbordamiento de pila.
n=input()
while n>1:n=(n/2,n*3+1)[n%2];print n
bc 41 caracteres
Supongo que este tipo de problemas es para lo que fue inventado bc
:
for(n=read();n>1;){if(n%2)n=n*6+2;n/=2;n}
Prueba:
bc1 -q collatz.bc
21
64
32
16
8
4
2
1
Código correcto:
for(n=read();n>1;){if(n%2)n=n*3+1else n/=2;print n,"/n"}
bc
maneja números con hasta dígitos INT_MAX
Editar: El artículo de Wikipedia menciona esta conjetura se ha comprobado para todos los valores de hasta 20x2 58 (aproximadamente 5.76e18 ). Este programa:
c=0;for(n=2^20000+1;n>1;){if(n%2)n=n*6+2;n/=2;c+=1};n;c
prueba 2 20,000 +1 (aproximadamente 3.98e6,020 ) en 68 segundos, 144,404 ciclos.
dc - 24 caracteres 25 28
dc
es una buena herramienta para esta secuencia:
?[d5*2+d2%*+2/pd1<L]dsLx
dc -f collatz.dc 21 64 32 16 8 4 2 1
También 24 caracteres usando la fórmula de la entrada de Golfscript :
?[3*1+d2%5*1+/pd1<L]dsLx
57 caracteres para cumplir con las especificaciones:
[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
Befunge
&>:.:1-|
>3*^ @
|%2: <
v>2/>+
C #: 659 caracteres con soporte BigInteger
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);
}
}
}
C: 64 caracteres
main(x){for(scanf("%d",&x);x>=printf("%d,",x);x=x&1?3*x+1:x/2);}
Con gran soporte entero: 431 (necesarios) caracteres
#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;}}
Nota : No elimine #include <stdlib.h>
sin al menos prototipos de malloc / realloc, ya que no será seguro en plataformas de 64 bits (el vacío de 64 bits se convertirá a int de 32 bits).
Este no ha sido probado enérgicamente todavía. Podría usar un poco de manteca también.
Versión anterior:
main(x){for(scanf("%d",&x);printf("%d,",x),x-1;x=x&1?3*x+1:x/2);} // 66
(eliminado 12 caracteres porque nadie sigue el formato de salida ...: |)
Golfscript: 20 caracteres
~{(}{3*).1&5*)/}/1+`
#
# Usage: echo 21 | ruby golfscript.rb collatz.gs
Esto es equivalente a
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;
Haskell, 62 caracteres 63 76 83 , 86 , 97 , 137
c 1=[1]
c n=n:c(div(n`mod`2*(5*n+2)+n)2)
main=readLn>>=print.c
La entrada del usuario, salida impresa, usa memoria y pila constantes, funciona con enteros arbitrariamente grandes.
Una muestra de ejecución de este código, dado un número de 80 dígitos de todos los "1" (!) Como entrada, es muy divertido de ver.
Versión original, solo función:
Haskell 51 caracteres
f n=n:[[],f([n`div`2,3*n+1]!!(n`mod`2))]!!(1`mod`n)
¿Quién de los @ y ^ # necesita condicionales, de todos modos?
(Editar: Estaba siendo "inteligente" y usé el parche. Sin él, el código bajó a 54 caracteres. edit2: bajó a 51 al factorizar f()
)
Haskell: 50
c 1=[1];c n=n:(c$if odd n then 3*n+1 else n`div`2)
Mathematica, 45 50 caracteres
c=NestWhileList[If[OddQ@#,3#+1,#/2]&,#,#>1&]&
Perl: 31 caracteres
perl -nE ''say$_=$_%2?$_*3+1:$_/2while$_>1''
# 123456789 123456789 123456789 1234567
Editado para eliminar 2 espacios innecesarios.
Editado para eliminar 1 espacio innecesario.
Ruby, 43 caracteres
bignum compatible, con susceptibilidad de desbordamiento de pila:
def c(n)p n;n%2>0?c(3*n+1):c(n/2)if n>1 end
... y 50 caracteres, bignum compatible, sin desbordamiento de pila:
def d(n)while n>1 do p n;n=n%2>0?3*n+1:n/2 end end
Felicitaciones a Jordan. No sabía acerca de ''p'' como un reemplazo de puts.
Ruby, 50 caracteres, sin desbordamiento de pila
Básicamente una copia directa de la solución Python de makapuf :
def c(n)while n>1;n=n.odd?? n*3+1: n/2;p n end end
Ruby, 45 caracteres, se desbordará
Básicamente una copia directa del código provisto en la pregunta:
def c(n)p n;n.odd?? c(3*n+1):c(n/2)if n>1 end
TI-BASIC
No es el más corto, sino un enfoque novedoso. Cierto disminuir la velocidad considerablemente con secuencias grandes, pero no debería desbordarse.
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
conjunto x86, 1337 caracteres
;
; 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
nroff 1
Ejecutar con 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. versión de groff
ruby, 43, posiblemente cumpliendo el requisito de E / S
Corre con ruby -n hail
n=$_.to_i
(n=n%2>0?n*3+1: n/2
p n)while n>1
Common Lisp, 141 caracteres:
(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~%"))
Prueba de funcionamiento:
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
El programa de Jerry Coffin tiene un número entero de flujo excesivo, prueba este:
#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";
}
probado con
El número de menos de 100 millones con el tiempo de detención total más largo es 63,728,127, con 949 pasos.
El número de menos de mil millones con el tiempo de detención total más largo es de 670,617,279, con 986 pasos.
Otra versión de ensamblador. Éste no está limitado a números de 32 bits, puede manejar números de hasta 10 65534, aunque el formato ".com" que utiliza MS-DOS está limitado a números de 80 dígitos. Escrito para el ensamblador A86 y requiere un cuadro Win-XP DOS para ejecutarse. Se ensambla a 180 bytes:
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
no la más corta, sino una solución clojure elegante
(defn collatz [n]
(print n "")
(if (> n 1)
(recur
(if (odd? n)
(inc (* 3 n))
(/ n 2)))))
C #: 216 caracteres
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);}}}
en forma larga:
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);
}
}
}
Nueva versión, acepta un número como entrada proporcionada a través de la línea de comando, sin validación de entrada. 173 154 caracteres.
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);}}}
en forma larga:
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);
}
}
}
Soy capaz de afeitar algunos personajes al estafar la idea en esta answer para usar un bucle for en lugar de un rato. 150 caracteres.
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);}}
Esquema: 72
(define(c n)(if(= n 1)`(1)(cons n(if(odd? n)(c(+(* n 3)1))(c(/ n 2))))))
Esto utiliza la recursividad, pero las llamadas son recursivas, por lo que creo que se optimizarán para la iteración. En algunas pruebas rápidas, no he podido encontrar un número para el cual la pila se desborde de todos modos. Solo por ejemplo:
(c 9876543219999999999000011234567898888777766665555444433332222 7777777777777777777777777777777798797657657651234143375987342987 5398709812374982529830983743297432985230985739287023987532098579 058095873098753098370938753987)
... corre bien [Eso es todo un número: acabo de romperlo para que quepa en la pantalla.]
LOLCODE: 406 CHARAKTERZ
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
TESTD UNDR JUSTIN J. MEZA INTERPRETR . KTHXBYE!
MS Excel, 35 caracteres
=IF(A1/2=ROUND(A1/2,0),A1/2,A1*3+1)
Tomado directamente de 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
Solo tomó copiar / pegar la fórmula 111 veces para obtener el resultado de un número inicial de 1000.;)
Python 45 Char
Afeitado un char de la respuesta de makapuf.
n=input()
while~-n:n=(n/2,n*3+1)[n%2];print n
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
Y en acción:
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
Esto también incluye el final 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)
Con el siguiente implícito
implicit def intToEven(i:Int) = new {
def ~(even: Int=>Int, odd: Int=>Int) = {
if (i%2==0) { even(i) } else { odd(i) }
}
}
esto se puede acortar a
val collatz = Stream.iterate(_:Int)(_~(_/2,3*_+1)).takeWhile(1<) :+ 1
Editar - 58 caracteres (incluida la entrada y la salida, pero sin incluir el número inicial)
var n=readInt;while(n>1){n=Seq(n/2,n*3+1)(n%2);println(n)}
Podría reducirse en 2 si no necesita nuevas líneas ...
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);
}
}