Code Golf: гипотеза Collatz
Вдохновленный http://xkcd.com/710/, здесь есть код для гольфа.
Задача
Учитывая положительное целое число больше 0, распечатайте последовательность градиента для этого числа.
Последовательность Hailstone
Подробнее см. 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
Кроме того, гольф-код должен включать полный ввод и вывод пользователя.
Ответы
Ответ 1
сборка x86, 1337 символов
;
; 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 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
Ответ 2
Befunge
&>:.:1-|
>3*^ @
|%2: <
v>2/>+
Ответ 3
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. KспасибоBYE!
Ответ 4
Python - 95 64 51 46 char
Очевидно, не создает переполнение стека.
n=input()
while n>1:n=(n/2,n*3+1)[n%2];print n
Ответ 5
Хаскелл, 62 символа <удаp > 63 76 83, 86, 97, < <удаp > 137забастовкa >
c 1=[1]
c n=n:c(div(n`mod`2*(5*n+2)+n)2)
main=readLn>>=print.c
Пользовательский ввод, вывод на печать, использует постоянную память и стек, работает с произвольно большими целыми числами.
Примерный пробег этого кода, учитывая 80-значное число всех '1 (!) в качестве входных данных, довольно забавно смотреть на.
Оригинальная версия только для функций:
Haskell 51 chars
f n=n:[[],f([n`div`2,3*n+1]!!(n`mod`2))]!!(1`mod`n)
Кому все равно @& ^ # нужны условные обозначения?
(edit: Я был "умным" и использовал исправление. Без него код упал до 54 символов.
edit2: сбрасывается до 51 путем факторизации f()
)
Ответ 6
Perl
Я решил быть немного антиконкурентным и показать, как вы обычно кодируете такую проблему в Perl.
В конце есть также 46 (общий) char код-гольф.
Эти первые три примера начинаются с этого заголовка.
#! /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];
}
Теперь я покажу, как вы могли бы сделать этот последний пример с версией Perl до версии 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];
}
}
Benchmark
Сначала 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
. Поэтому я включаю весь пример в мой счет.
Ответ 7
Golfscript: 20 символов
~{(}{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;
Ответ 8
bc 41 chars
Я предполагаю, что такие проблемы - это то, что 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
цифрами
Изменить: Статья в Википедии упоминает, что эта гипотеза проверена для всех значений до 20x2 58 (пример 5.76e18). Эта программа:
c=0;for(n=2^20000+1;n>1;){if(n%2)n=n*6+2;n/=2;c+=1};n;c
тесты 2 20 000 +1 (приблизительно 3,98e6,020) за 68 секунд, 144,404 цикла.
Ответ 9
Perl: 31 символ
perl -nE 'say$_=$_%2?$_*3+1:$_/2while$_>1'
# 123456789 123456789 123456789 1234567
Отредактировано для удаления 2 ненужных пробелов.
Отредактировано для удаления 1 ненужного пространства.
Ответ 10
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.;)
Ответ 11
C: 64 символа
main(x){for(scanf("%d",&x);x>=printf("%d,",x);x=x&1?3*x+1:x/2);}
С большой целочисленной поддержкой: 431 (необходимо) символов
#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;}}
Примечание. Не удаляйте #include <stdlib.h>
, не создавая прототипов malloc/realloc, так как это не будет безопасно на 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 символов, потому что никто не следует за выходным форматом...: |)
Ответ 12
Другая версия ассемблера. Это не ограничивается 32-разрядными номерами, оно может обрабатывать номера до 10 65534 хотя формат MS-DOS формата ".com" ограничен 80 цифрами. Написан для ассемблера A86 и требуется окно DOS Win-XP для запуска. Снимает до 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
Ответ 13
dc - 24 символа 25 28
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
Ответ 14
Схема: 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)
... работает просто отлично. [что все одно число - я только что сломал его, чтобы поместиться на экране.]
Ответ 15
Mathematica, 45 50 chars
c=NestWhileList[If[[email protected]#,3#+1,#/2]&,#,#>1&]&
Ответ 16
Ruby, 50 символов, переполнение стека
В основном прямой рип makapuf Python solution:
def c(n)while n>1;n=n.odd?? n*3+1: n/2;p n end end
Ruby, 45 символов, переполняется
В принципе, прямая копия кода, содержащегося в вопросе:
def c(n)p n;n.odd?? c(3*n+1):c(n/2)if n>1 end
Ответ 17
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
Python 45 Char
Вычеркнул a char ответ makapuf.
n=input()
while~-n:n=(n/2,n*3+1)[n%2];print n
Ответ 19
TI-BASIC
Не самый короткий, но новый подход. Некоторое замедление значительно с большими последовательностями, но оно не должно переполняться.
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
Ответ 20
Haskell: 50
c 1=[1];c n=n:(c$if odd n then 3*n+1 else n`div`2)
Ответ 21
Ruby, 43 символа
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
Престижность в Иордании. Я не знал о "р" в качестве замены для puts.
Ответ 22
С#: 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);
}
}
}
Я могу сбрить несколько символов, срывая идею в этом ответе, чтобы использовать цикл 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);}}
Ответ 23
не самый короткий, но элегантный clojure решение
(defn collatz [n]
(print n "")
(if (> n 1)
(recur
(if (odd? n)
(inc (* 3 n))
(/ n 2)))))
Ответ 24
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, если вам не нужны символы новой строки...
Ответ 25
Nroff 1
Выполнить с 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
Ответ 26
F #, 90 символов
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"
Ответ 27
Общий 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
Ответ 28
Программа 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";
}
с
Число менее 100 миллионов с самым длинным общим временем остановки составляет 63 728 127, с 949 шагами.
Число менее 1 миллиарда с самым длинным общим временем остановки составляет 670 617 279, с 986 шагами.
Ответ 29
ruby, 43, возможно, соответствует требованию ввода/вывода
Выполнить с ruby -n hail
n=$_.to_i
(n=n%2>0?n*3+1: n/2
p n)while n>1
Ответ 30
С#: 659 символов с поддержкой 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);
}
}
}