Вдохновленный http://xkcd.com/710/, вот код для этого гольфа.
Соревнование
Дано положительное целое число больше 0, распечатайте последовательность грады для этого числа.
Последовательность Града
См. Википедию для более подробной информации.
- Если число четное, разделите его на два.
- Если число нечетное, утроите его и прибавьте единицу.
Повторите это с полученным числом до тех пор, пока оно не достигнет 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
Кроме того, код гольф должен включать в себя полный пользовательский ввод и вывод.
Ответы:
сборка x86, 1337 символов
источник
int 23h
.Befunge
источник
LOLCODE: 406 CHARAKTERZ
ТЕСТД УНДР Джастин Дж. МЕЗА ПЕРЕВОДЧИК . KTHXBYE!
источник
Python -
95645146 символовОчевидно, не вызывает переполнения стека.
источник
input
не поддерживаетeval
.n=input()*2
Perl
Я решил быть немного антиконкурентным и показать, как вы обычно кодируете такую проблему на Perl.
В конце также есть 46 (всего) кодовая запись для гольфа.
Все эти первые три примера начинаются с этого заголовка.
Простая рекурсивная версия
Простая итеративная версия
Оптимизированная итеративная версия
Теперь я покажу, как бы вы сделали этот последний пример с версией Perl до v5.10.0.
Контрольный показатель
Во-первых, ввод-вывод всегда будет медленной частью. Так что, если вы действительно протестировали их как есть, вы должны получить примерно одинаковую скорость для каждого из них.
Затем, чтобы проверить это, я открыл дескриптор файла для
/dev/null
($null
) и отредактировал каждый,say $n
чтобы вместо этого читатьsay {$null} $n
. Это сделано для уменьшения зависимости от ввода-вывода.После 10 запусков, вот типичный результат:
Наконец, настоящий код-гольф:
46 символов всего
Если вам не нужно печатать начальное значение, вы можете удалить еще 5 символов.
41 символ всего
31 символ для фактической части кода, но код не будет работать без
-n
переключателя. Поэтому я включаю в свой счет весь пример.источник
$i + 1
это всегда дополнение (ответ на запись в блоге). Также используетсяSub::Call::Recur
оптимизация. В противном случае я бы использовал@_=$n;goto &Collatz
. (Это будет на 10-20% медленнее, если вы перейдетеstate @next
наmy @next
Haskell, 62 символа
637683,86,97,137Пользовательский ввод, вывод на печать, использует постоянную память и стек, работает с произвольно большими целыми числами.
Пример выполнения этого кода с 80-значным числом, состоящим из всех единиц (!) В качестве входных данных, довольно интересно посмотреть.
Оригинальная, функциональная версия:
Haskell 51 символ
Кому, вообще говоря, @ & ^ # нужны условные выражения?
(править: я был «умным» и использовал исправление. Без него код упал до 54 символов. edit2: упал до 51 за счет факторинга
f()
)источник
c 1=[1];c n=n:(c$div(n
mod2*(5*n+2)+n)2)
- 41 символ, здесь используется тот факт, что это k * (3n + 1) + (1-k) * n / 2, где k = n mod 2Гольфскрипт: 20 символов
Это эквивалентно
источник
21
с~
заставит программу использовать номер от стандартного ввода(eval):1:in
метод initialize ': undefinedleftparen' for nil:NilClass (NoMethodError)
при замене21
на~
.echo 21 | ruby golfscript.rb collatz.gs
bc 41 символ
Я предполагаю, что такого рода проблемы и
bc
были придуманы:Контрольная работа:
Правильный код:
bc
обрабатывает числа доINT_MAX
цифрИзменить: В статье Википедии упоминается, что эта гипотеза была проверена для всех значений до 20x2 58 (прибл. 5.76e18 ). Эта программа:
тестирует 2 20,000 +1 (прибл. 3,98e6,020 ) за 68 секунд, 144 404 цикла.
источник
cat /dev/urandom | tr -dc '0-9' | head -c 10000 | bc collatz-conjecture.bc
bc
Perl: 31 символ
Отредактировано для удаления 2 ненужных пробелов.
Отредактировано, чтобы удалить 1 ненужный пробел.
источник
MS Excel, 35 символов
Взято прямо из Википедии :
Чтобы получить результат для начального числа 1000, нужно всего 111 раз скопировать / вставить формулу;)
источник
C: 64 символа
С поддержкой большого числа: 431 (необходимый) символ
Примечание . Не удаляйте
#include <stdlib.h>
по крайней мере без создания прототипа malloc / realloc, так как это будет небезопасно на 64-битных платформах (64-битное void * будет преобразовано в 32-битное int).Этот еще не прошел серьезных испытаний. Он также может использовать некоторое сокращение.
Предыдущие версии:
(удалены 12 символов, потому что никто не следует формату вывода ...: |)
источник
Еще одна версия ассемблера. Он не ограничен 32-битными числами, он может обрабатывать числа до 10 65534, хотя формат ".com", используемый MS-DOS, ограничен 80-значными числами. Написан для ассемблера A86 и требует для работы Win-XP DOS. Сборка до 180 байт:
источник
dc - 24 символа
2528dc
хороший инструмент для этой последовательности:Также 24 символа с использованием формулы из записи Golfscript :
57 символов для соответствия спецификациям:
источник
Схема: 72
Здесь используется рекурсия, но вызовы рекурсивны по хвосту, поэтому я думаю, что они будут оптимизированы для итераций. При быстром тестировании мне не удалось найти число, для которого стек все равно переполняется. Например:
(c 9876543219999999999000011234567898888777766665555444433332222 77777777777777777777777777777798797657657657651234143375987342987 53987098123749825298309837432974329870239873749825298309837432974329870239873857398252983098374329743298705230985739209875983
... работает нормально. [это все одно число - я только что разбил его по размеру экрана.]
источник
Математика, 45
50символыисточник
OddQ[#]
на,OddQ@#
чтобы сэкономить 1 символ.c[n_]:=NestWhileList[If[OddQ@#,3#+1,#/2]&,n,#>1&]
Ruby, 50 символов, без переполнения стека
По сути, прямая копия решения makapuf на Python :
Рубин, 45 символов, переполнится
В основном прямой разрыв кода, указанного в вопросе:
источник
n.odd??
не определился. Кроме того, это уязвимо для переполнения стека большими числами.p n=[n/2,n*3+1][n%2]
источник
Python 45 символов
Срезал уголь с ответа Макапуфа.
источник
TI-BASIC
Не самый короткий, но новый подход. Определенно, чтобы значительно замедлить работу с большими последовательностями, но не должно переполняться.
источник
Haskell: 50
источник
c 1=[1];c n=n:(c$[n
div2,3*n+1]!!(n
mod2))
, 44не самое короткое, но элегантное решение для закрытия
источник
C #: 216 символов
в полной форме:
Новая версия, принимает одно число в качестве ввода, предоставляемого через командную строку, без проверки ввода.
173154 символа.в полной форме:
Я могу сбрить несколько символов, отказавшись от идеи в этом ответе использовать цикл for, а не время. 150 знаков.
источник
Рубин, 43 символа
bignum поддерживается, с возможностью переполнения стека:
... и 50 символов, поддерживается bignum, без переполнения стека:
Престижность Иордании. Я не знал о "p" как о замене пут.
источник
nroff 1
Бежать с
nroff -U hail.g
1. версия groff
источник
groff -U hail.g
и получите PostScript! :-)Скала + Скалаз
И в действии:
Scala 2.8
Это также включает в себя конечный 1.
Со следующим неявным
это можно сократить до
Редактировать - 58 символов (включая ввод и вывод, но не включая начальный номер)
Можно уменьшить на 2, если вам не нужны новые строки ...
источник
F #, 90 символов
Или, если вы не используете F # interactive для отображения результата, 102 символа:
источник
Common Lisp, 141 символ:
Тестовый забег:
источник
Программа от Jerry Coffin имеет целочисленное переполнение, попробуйте эту:
протестировано с
Число меньше 100 миллионов с наибольшим общим временем остановки составляет 63 728 127 с 949 шагами.
Число меньше 1 миллиарда с наибольшим общим временем остановки составляет 670 617 279 с 986 шагами.
источник
unsigned long long
.ruby, 43, возможно, отвечающий требованиям ввода-вывода
Бежать с
ruby -n hail
источник
C #: 659 символов с поддержкой BigInteger
Безголовый
источник