Гипотеза Коллатца (OEIS A006577)


66

Это гипотеза Коллатца (OEIS A006577 ):

  • Начните с целого числа n > 1.
  • Повторите следующие шаги:
    • Если n четное, разделите его на 2.
    • Если n нечетно, умножьте его на 3 и добавьте 1.

Доказано , что для всех натуральных чисел до 5 * 2 60 , или около 5764000000000000000 , п , в конечном счете станет 1 .

Ваша задача - выяснить, сколько итераций требуется (вдвое или трижды плюс один), чтобы достичь 1 .

Соответствующий xkcd :)

Правила:

  • Самый короткий код выигрывает.
  • Если число <2 введено, или нецелое, или не число, вывод не имеет значения.

Контрольные примеры

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

Ответы:


19

GolfScript, 24 23 21 20 18 символов

~{(}{3*).2%6\?/}/,

Предполагает ввод на стандартный ввод. Онлайн тест


3
1+в специальном корпусе как ).
Питер Тейлор

@PeterTaylor, конечно, забыл об этом;)
Волатильность

1
Хорошо сделано! <! - padding ->
Питер Тейлор

1
@Peter: <! - -> не работает в комментариях. Используйте это вместо этого.
Ильмари Каронен


15

C - 50 47 символов

К сожалению, малоимущий C требует огромного количества кода для базового ввода-вывода, поэтому сокращение всего этого сделало интерфейс немного неинтуитивным.

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--.
Угорен

Хе-хе, вы так сильно
нарушаете

Спасибо, Угорен! Должно быть, я был пьян, когда писал это. :)
Форс

12

Perl 34 (+1) символа

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

Злоупотребление $\для окончательного вывода, как обычно. Запустить с параметром -pкомандной строки, ввод берется из stdin.

Сохранен один байт благодаря Элиасу Ван Оотегему . В частности, наблюдение, что следующие два эквивалентны:

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

Хотя он на один байт длиннее, он сокращает два байта, сокращая $_/2до всего .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/$_отлично работает
Элиас Ван Отегем

@EliasVanOotegem $_*=3+1/$_великолепен, спасибо!
Примо

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 (), если вы сказали, что вывод не имеет значения, если он не является целым числом? Вы можете сохранить два символа, избавившись от ~~.
Resorath

@Resorath Ах, забыл об авто-кастинге JS: P спасибо
дверная ручка

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(int x=Short.valueOf(a[0]),y=0;x>1;x=x%2<1?x/2:x*3+1,System.out.println(++y))

Это чертовски красивый мужчина. Спасибо Патеру Тейлору !!!, и идея использовать цикл for была украдена у угорена

Я заменил Integer на Short.


1
Вы можете довольно легко сохранить длину i(,++y). Вы можете сохранить еще два, используя <вместо ==.
Питер Тейлор

@PeterTaylor вы правы, мои сравнения будут короче с <, но я не понимаю часть предварительного увеличения
jsedano

2
Две стороны вашей второй троичной структуры структурно идентичны, так что вы можете вставить троичный в первый аргумент рекурсивного вызова.
Питер Тейлор


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 Карл Сассенрат сказал мне, что он нашел Rebmu «нечитабельным», он занят, и у него нет времени, чтобы по-настоящему практиковать преобразование в стиле свиньи-латиноамериканца посредством unmushing . Это действительно просто преобразовано в:

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

Rebol, как и Ruby, оценивает блоки до их последнего значения. Цикл UNTIL является любопытной формой цикла, который не требует условий цикла, он просто прекращает цикл, когда его блок оценивает что-либо, отличное от FALSE или NONE. Таким образом, в тот момент, 1 ==когда результат присваивания A (аргумента rebmu) результату условия Коллатца (либо IF-ELSE, который оценивает выбранную ветвь) ... цикл прерывается.

J и K инициализируются целым значением ноль в Rebmu. И, как уже упоминалось, все это оценивается до последнего значения. Так что ссылка J в конце программы означает, что вы получите количество итераций.

Использование:

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

8

Python Repl, 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
Мой мозг болит сейчас.
Даньеро

1
@daniero второе решение только для вас.
Boothby

Ух ты. Я горжусь!
Даниеро

4
(n//2,n*3+1)[n%2]короче
Евпок

1
@Evpok не будет n/2работать так хорошо, как мы знаем, это даже?
Джордж


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&=образует указатель на герунду. буквально, «остаток после деления на два плюс, равняется ли он одному».

  • #verb^:a:выполняет итерации функции до тех пор, пока результат не станет стабильным (здесь принудительно явно), пока собирает шаги, а затем считает их. Украдена у @JB . <:уменьшает число шагов на единицу, чтобы соответствовать требованиям вопроса.


6
Всякий раз, когда я вижу представление J, я считаю смайлики. Это один делает довольно хорошо: <:, #-:, :`(, &*), =), )^:.
Примо

3
@ primo nice; хотите их объяснение? :-) <:означает «уменьшение» или «меньше или равно», #означает «количество» или «n раз», -:означает «вдвое» или «равенство эпсилон», :`(означает, в свою очередь, конец указанного «пополам», связь между два глагола в герунде и левой круглой скобке (используется для группировки). &*)означает «что связано с умножением» (3 связано с умножением создает оператор «умножить на три») и конец группировки. =выполняет проверку на равенство или, в унарном смысле, самостоятельную классификацию. ^:является степенным соединением (итерация глагола). Поскольку многие глаголы J заканчиваются двоеточием, ... :-)
Джон Дворжак

Годы спустя ... Улучшенный блок цикла: '- & 2 # (> & 1 * -: + 2 & | * +: +>: @ -:) ^: a:' -> -1 символ. : P
randomra

Еще годы спустя ... <:#a:2&(<*|+|6&*%~)19 байт (-11)
миль

6

Схема гамбита, 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

Отредактировано, чтобы удалить Python.
Валентин Клемент

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вместо 16 вводится значение «5551». Четные входные данные вели себя хорошо, поскольку в PowerShell нет действия по умолчанию для разделения на строки. Даже четные входные данные, которые проходили бы через нечетные числа, работали нормально, потому что к тому времени, когда PowerShell достигал нечетного числа в цикле, переменная уже в любом случае была переведена в целое число математическими операциями.

Спасибо Danko Durbic за указание на то, что я могу просто инвертировать операцию умножения, и мне не нужно приводитьread-host к int, поскольку PowerShell основывает свои операции на первом объекте.

Совет PowerShell игрока в гольф: Для некоторых сценариев, как этот, switchбьет if/else. Здесь разница составила 2 символа.

Protip любезно предоставлен 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

Тестовые случаи:

Ниже приведены некоторые примеры с включенным аудитом. Я также отредактировал вывод некоторых для ясности, добавив метки к входному и конечному счету и вставив интервал, чтобы отделить значения Коллатца.

---
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]
Данко Дурбич

2
Кроме того, вам не нужно конвертировать read-hostв число - просто измените $i*3на 3*$i.
Данко Дурбич

Массив вместо свитча? Brilliant! И обмениваться $i*3- почему я не подумал об этом уже?
Изи

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

Брахилог , 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

Python 68 58 54 52 символов

f=lambda n:1+(n-2and f((n/2,3*n+1)[n%2]));f(input())

Спасибо Бакуриу и Бутби за советы :)


Вы можете использовать, n%2and 3*n+1or n/2чтобы сохранить 5 символов. Также в python2 вы можете удалить вызов int, уменьшив размер до 58 байт.
Бакуриу

О, ты можешь даже стать короче этого [n/2,3*n+1][n%2].
Boothby

Это изящно!
Валентин Клемент

Это питон 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

Алгоритм представляет собой цикл выполнения шага Коллатца с унарным числом и добавления нового маркера шага xв конце строки, если число не равно 1.

Когда цикл заканчивается на 1, мы конвертируем маркеры в унарное число (удаляя ведущий 1), который является желаемым выходом.


5

Желе неконкурентоспособное

12 байт. Этот ответ не является конкурирующим, поскольку задача предшествует созданию желе.

×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
Четность не черная магия.
Boothby

1
Нет, но это очень изящный трюк! Я на самом деле делал подобные вещи сам, я просто не думал об этом в этом случае. На секунду меня остановило разделение, но я понял: вы делите на шесть, возвращая первую операцию (* = 3, + = 1) со второй, если четность была неправильной, и из-за целочисленного деления происходит сложение прочь, и мы в основном сделали / = 2. Очень умно :)
Даниеро

1
+1. Я думал, что собираюсь раздавить этот вызов с помощью DC, но получил только до 40. Я видел ваш 27 ответ. Ну что ж.
Цифровая травма

Я не видел этой проблемы, но недавно написал в блоге о печати последовательности Коллатца в dc. Мой подход похож на ваш, но проигрывает на байт, поэтому я не вижу причин, чтобы опубликовать его. Однако, когда я смотрел на свой, чтобы увидеть, как легко перейти от печати каждого шага к печати количества шагов, я заметил кое-что, что может отыграть у тебя байт ... Так как последовательность Коллатца всегда будет идти от 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'%<>./>=

Попробуйте онлайн!

Expanded:

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

Обратите внимание , что это не будет работать на 1по гм ... причинам . Честно говоря, я не совсем уверен, как это работает больше. Все, что я знаю, это то, что код для нечетных чисел запускается в обратном направлении для четных чисел? Каким - то образом?

Новая версия намного чище, чем предыдущая, но в сравнении имеет несколько направлений, а также заканчивается ошибкой деления на ноль. Единственный случай, когда он не ошибается, это когда он действительно обрабатывает 1правильно.


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

@ Sok Да, именно поэтому я отправил это вместо того, чтобы сходить с ума, пытаясь это исправить
Джо Кинг,

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

Ruby 1.9, 49 символов

Ответ Rubyfied Valentin CLEMENT на Python , использующий синтаксис stabby lambda. Сложил это в одно утверждение для дополнительной нечитаемости.

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

Некоторые издержки, потому что Ruby, в отличие от Python, не рад смешивать числа с логическими значениями.


3

С ++ ( 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там не улучшило бы счет любой.
Джо З.

Ах, тогда вы могли бы просто заменить его на это: 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 CLEMENT и daniero : 40 символов

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 байта очень умным способом вычисления следующего значения напрямую. Формула, используемая для вычисления следующего значения в последовательности:

е(N)знак равноN5(Nмодификация2)+12+(Nмодификация2)

Фракция отображает четные числа в 0,5, а нечетные числа в 3. Умножение на nи сложение n%2завершает вычисление - нет необходимости выбирать следующее значение!

Редактировать 2: Вот версия до @ Hohmannfan:

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

Хитрость в том, что оба 3n+1и n/2вычисляются на каждом шаге в последовательности, и тот, который должен быть удален из последовательности, выбирается впоследствии. Это означает, что коду не нужно переходить, пока не будет достигнута 1, и вычисление последовательности может выполняться в одной строке кода.

Редактирование: исключение другого символа после того, как он понял, что единственное положительное целое число, которое может привести к 1, равно 2. Поскольку выходные данные программы не имеют значения для ввода <2, генерация последовательности может закончиться при достижении 2, оставляя размер стека точное количество необходимых шагов.

Предыдущая версия:

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

1
Вы можете играть в гольфе его до 23 , если вы unbranch второй линии еще больше:\::2%:@5*1+2,*+:2=?
Hohmannfan
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.