Collatz Conjecture (OEIS A006577)

66

6

This is the Collatz Conjecture (OEIS A006577):

  • Start with an integer n > 1.
  • Repeat the following steps:
    • If n is even, divide it by 2.
    • If n is odd, multiply it by 3 and add 1.

It is proven that for all positive integers up to 5 * 260, or about 5764000000000000000, n will eventually become 1.

Your task is to find out how many iterations it takes (of halving or tripling-plus-one) to reach 1.

Relevant xkcd :)

Rules:

  • Shortest code wins.
  • If a number < 2 is input, or a non-integer, or a non-number, output does not matter.

Test cases

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

Doorknob

Posted 2013-08-01T11:22:46.980

Reputation: 68 138

Answers

19

GolfScript, 24 23 21 20 18 chars

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

Assumes input on stdin. Online test

Volatility

Posted 2013-08-01T11:22:46.980

Reputation: 3 206

31+ is special-cased as ). – Peter Taylor – 2013-08-01T11:59:31.637

@PeterTaylor of course, forgot about that ;) – Volatility – 2013-08-01T12:01:33.433

There are a couple of replacements which tie for length and might be of interest. One is to replace the loop body with .5*)).1&*+2/; the other is to work with x-1 rather than x which turns the unfold into ({}{.2%!{)6*}*2/}/ – Peter Taylor – 2013-08-01T17:22:07.867

1Nice work! <!-- padding --> – Peter Taylor – 2013-08-02T08:20:14.717

1

@Peter: The <!-- --> don't work in comments. Use this instead.

– Ilmari Karonen – 2013-08-02T10:36:48.733

2Or this. – Timwi – 2013-08-03T08:45:07.930

Well, I doubt anyone can get any shorter than this, so I'm accepting it. Good job! – Doorknob – 2013-08-04T01:42:50.473

15

C - 50 47 characters

Poor little C unfortunately requires an awful amount of code for basic I/O, so shorting all that down has made the UI slightly unintuitive.

b;main(a){return~-a?b++,main(a&1?3*a+1:a/2):b;}

Compile it with for example gcc -o 1 collatz.c. The input is in unary with space-separated digits, and you will find the answer in the exit code. An example with the number 17:

$> ./1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
$> echo $?
12
$>

Fors

Posted 2013-08-01T11:22:46.980

Reputation: 3 020

1return~-a? saves 1. Also moving b++ to the ? case should save b--. – ugoren – 2013-08-30T15:41:48.080

Hehe you're bending the rules so much :P +1 for creativity and using a language not usually used to golf – Doorknob – 2013-08-30T16:56:26.093

Thank you ugoren! I must have been drunk when writing it. :) – Fors – 2013-08-30T17:24:08.430

12

Perl 34 (+1) chars

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

Abusing $\ for final output, as per usual. Run with the -p command line option, input is taken from stdin.

Saved one byte due to Elias Van Ootegem. Specifically, the observeration that the following two are equivalent:

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

Although one byte longer, it saves two bytes by shortening $_/2 to just .5.

Sample usage:

$ echo 176 | perl -p collatz.pl
18

PHP 54 bytes

<?for(;1<$n=&$argv[1];$c++)$n=$n&1?$n*3+1:$n/2;echo$c;

Javascript's archnemesis for the Wooden Spoon Award seems to have fallen a bit short in this challenge. There's not a whole lot of room for creativity with this problem, though. Input is taken as a command line argument.

Sample usage:

$ php collatz.php 176
18

primo

Posted 2013-08-01T11:22:46.980

Reputation: 30 891

1Repeating $_ in the ternary seems wasteful, you can shave off another character by using *= like this: $\++,$_*=$_&1?3+1/$_:.5while$_>1}{. Multiplying by 1/$_ has the same effect as +1, so $_*=3+1/$_ works just fine – Elias Van Ootegem – 2015-12-21T17:31:40.723

@EliasVanOotegem $_*=3+1/$_ is brilliant, thanks! – primo – 2015-12-22T08:54:22.770

1Took me a while to figure out what the unmatched brackets are doing :) – marinus – 2013-08-01T22:21:05.390

11

Mathematica (35)

If[#>1,#0@If[OddQ@#,3#+1,#/2]+1,0]&

Usage:

If[#>1,#0[If[OddQ@#,3#+1,#/2]]+1,0]&@16
>> 4

miles

Posted 2013-08-01T11:22:46.980

Reputation: 15 654

It's not a valid function, 10.3 complains about a rogue @ at the end – CalculatorFeline – 2016-04-18T05:29:07.340

@ is calling the argument, I don't know why it was there, just a quick edit – miles – 2016-04-18T05:32:59.710

Gotta be careful :) – CalculatorFeline – 2016-04-18T16:51:38.853

10

As I usually do, I will start the answers off with my own.

JavaScript, 46 44 chars (run on console)

for(n=prompt(),c=1;n>1;n=n%2?n*3+1:n/2,++c)c

Doorknob

Posted 2013-08-01T11:22:46.980

Reputation: 68 138

What is the point of ~~prompt() if you said the output doesn't matter if it is a non-integer? You can save two characters by getting rid of ~~. – Resorath – 2013-08-01T16:57:16.737

@Resorath Ah, forgot about JS's auto casting :P thanks – Doorknob – 2013-08-01T23:28:31.177

9

Java, 165, 156, 154,134,131,129,128,126 (verbose languages need some love too)

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));}}

All is done inside the for

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

That's freaking beautiful man. Thanks to Pater Taylor!!!, and the idea of using a for loop was stolen from ugoren

I replaced Integer for Short.

jsedano

Posted 2013-08-01T11:22:46.980

Reputation: 1 607

1You can quite easily save the length of i(,++y). You can save two more by using < instead of ==. – Peter Taylor – 2013-08-01T16:24:51.920

@PeterTaylor you're right, my comparisons will be shorter with < , but I don't understand the part of the pre-increment – jsedano – 2013-08-01T16:29:52.353

2The two sides of your second ternary are structurally identical, so you can push the ternary into the first argument of the recursive call. – Peter Taylor – 2013-08-01T16:37:43.037

1OH MY GOD THAT'S BRILLIANT – jsedano – 2013-08-01T16:39:02.033

2I know it has been about 3.5 years, but you can still golf it by 5 bytes: 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;}} Changes made: 1) Replaced Short.valueOf(...) with new Short(...) for -4 bytes and 2) I've put the x=x%2<1?x/2:x*3+1; in the body of the for-loop to get rid of the comma for -1 byte. – Kevin Cruijssen – 2017-04-05T08:42:22.320

In addition to my golfs in the comment above, you can change class a{public static void main to interface a{static void main (Java 8+) (-1 byte), and new Short can be new Byte (-1 byte). – Kevin Cruijssen – 2018-02-21T15:22:00.897

9

Rebmu: 28

u[++jE1 AeEV?a[d2A][a1M3a]]j

On a problem this brief and mathy, GolfScript will likely win by some percent against Rebmu (if it's not required to say, read files from the internet or generate JPG files). Yet I think most would agree the logic of the Golfscript is nowhere near as easy to follow, and the total executable stack running it is bigger.

Although Rebol's own creator Carl Sassenrath told me he found Rebmu "unreadable", he is busy, and hasn't time to really practice the pig-latin-like transformation via unmushing. This really is merely transformed to:

u [
    ++ j
    e1 a: e ev? a [
        d2 a
    ] [
        a1 m3 a
    ]
]
j

Note that the space was required to get an a: instead of an a. This is a "set-word!" and the evaluator notices that symbol type to trigger assignment.

If it were written in unabbreviated (yet awkwardly-written Rebol), you'd get:

until [
    ++ j
    1 == a: either even? a [
        divide a 2
    ] [
        add 1 multiply 3 a
    ]
 ]
 j

Rebol, like Ruby, evaluates blocks to their last value. The UNTIL loop is a curious form of loop that takes no loop condition, it just stops looping when its block evaluates to something not FALSE or NONE. So at the point that 1 == the result of assigning A (the argument to rebmu) to the result of the Collatz conditional (either is an IF-ELSE which evaluates to the branch it chooses)... the loop breaks.

J and K are initialized to integer value zero in Rebmu. And as aforementioned, the whole thing evaluates to the last value. So a J reference at the end of the program means you get the number of iterations.

Usage:

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

HostileFork says dont trust SE

Posted 2013-08-01T11:22:46.980

Reputation: 2 292

8

Python repl, 48

I'm not convinced that there isn't a shorter expression than n=3*n+1;n/=1+n%2*5;. I probably found a dozen different expressions of all the same length...

i=0
n=input()
while~-n:n=3*n+1;n/=1+n%2*5;i+=1
i

edit: I've found another solution that will never contend, but is too fun not to share.

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

boothby

Posted 2013-08-01T11:22:46.980

Reputation: 9 038

The OP didn't specify, but I would put print there, or remove that i at the end—it's basically a no-op. – nyuszika7h – 2015-01-22T15:09:01.163

1My brain hurts now. – daniero – 2013-08-12T17:55:12.927

1@daniero the second solution is just for you. – boothby – 2013-08-13T08:10:28.467

Oh wow. I'm honored! – daniero – 2013-08-15T10:23:28.023

Is this for Python2.7? I get bad operand type for unary -: 'str' in Python 3.5.1 – george – 2016-12-16T16:03:45.920

1@Evpok wouldn't n/2 work as well as we know it is even? – george – 2016-12-16T16:04:22.207

@george It would return a float anyway – Evpok – 2016-12-16T18:43:43.653

5(n//2,n*3+1)[n%2] is shorter. – Evpok – 2014-04-05T20:34:53.023

7

APL (31)

A←0⋄A⊣{2⊤⍵:1+3×⍵⋄⍵÷2}⍣{⍺=A+←1}⎕

marinus

Posted 2013-08-01T11:22:46.980

Reputation: 30 224

1old answer, yet, 27: {1=⍵:0⋄2|⍵:1+∇1+3×⍵⋄1+∇⍵÷2} – Uriel – 2017-12-27T17:33:28.927

2{1=⍵:0⋄1+∇⊃⍵⌽0 1+.5 3×⍵} – ngn – 2018-01-16T05:39:29.817

7

J, 30 characters

<:#-:`(1+3&*)`]@.(2&|+1&=)^:a:

Turned out quite a bit longer than desired

usage:

   <:#-:`(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&*)`] is a gerund composed of three verbs, used on three occasions. -: means "halve", (1+3&*) or (1+3*]) encodes the multiplication step and ] (identity) aids termination.

  • 2&|+1&= forms an index to the gerund. literally, "the remainder after division by two plus whether it equals one".

  • #verb^:a: iterates the function until the result is stable (here, forced explicitly), while collecting the steps, then counts them. Stolen from @JB. <: decrements the step count by one to align with the question requirements.

John Dvorak

Posted 2013-08-01T11:22:46.980

Reputation: 9 048

Years later... Improved loop block: '-&2#(>&1-:+2&|+:+>:@-:)^:a:' -> -1 char. :P – randomra – 2015-01-26T13:44:09.277

6Whenever I see a J submission, I count the smilies. This one does pretty well: <:, #-:, :\(,&*),=),)^:`. – primo – 2013-08-01T14:58:43.863

3@primo nice; want their explanation? :-) <: means "decrement" or "less or equal", # means "count of" or "n times", -: means "halve" or "epsilon-equality", :`( mean in turn the end of said "halve", the tie between two verbs in a gerund and a left parenthesis (used for grouping). &*) means "sth. bonded to the multiplication" (3 bonded with multiplication creates the "times three" operator) and the end of grouping. = performs equality checking or, in the unary sense, self-classification. ^: is the power conjunction (verb iteration). Since a lot of J verbs end with a colon, ... :-) – John Dvorak – 2013-08-01T15:10:30.773

More years later... <:#a:2&(<*|+|6&*%~) 19 bytes (-11) – miles – 2018-01-10T14:29:10.010

6

80386 assembly, 16 bytes

This example uses AT&T syntax and the fastcall calling convention, the argument goes into 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);

Here are the resulting 16 bytes of machine code:

83 c8 ff 40 8d 54 49 01 d1 e9 0f 42 ca 75 f4 c3

FUZxxl

Posted 2013-08-01T11:22:46.980

Reputation: 9 656

6

Gambit scheme, 106 98 characters, 40 parentheses

(let((f(lambda(x)(cond((= x 1) 0)((odd? x)(+ 1(f(+ 1(* 3 x)))))(else(+ 1(f(/ x 2))))))))(f(read)))

91 89 chars with define directly

(define(f x)(cond((= x 1)0)((odd? x)(+ 1(f(+ 1(* 3 x)))))(else(+ 1(f(/ x 2))))))(f(read))

Valentin CLEMENT

Posted 2013-08-01T11:22:46.980

Reputation: 321

I haven't been around for a long time, but I have notice that usually people post 1 answer per programming language. – jsedano – 2013-08-01T18:03:49.127

Sorry, I wasn't aware of that :) – Valentin CLEMENT – 2013-08-01T18:05:21.337

Edited to remove the Python one. – Valentin CLEMENT – 2013-08-01T18:06:33.190

1Not true! People tend to post one answer per programming language, but that's because they're trying not to directly compete with someone else with a shorter answer. But nobody's going to complain if you post a different answer in the same language. – breadbox – 2013-08-01T19:05:28.647

@breadbox not true. I post one answer per language if each solution is interesting by itself compared to the other. If both solutions are each as interesting as them both together (the same algorithm, no interesting language tricks), I post them as one. Normally I don't post multiple solutions because I choose a language first, then solve the problem in that language - then I'm usually too lazy to write the same in a different language - or I embark on a journey to learn yet another programming language. – John Dvorak – 2013-08-02T14:20:51.280

Interesting, but it doesn't contradict my point, which is that there's no reason to not post a solution just because someone else already has one in that language. – breadbox – 2013-08-02T15:23:53.280

6

PowerShell: 77 74 71 70 61

Golfed code:

for($i=(read-host);$i-ne1;$x++){$i=(($i/2),(3*$i+1))[$i%2]}$x

Notes:

I originally tried taking the user input without forcing it to an integer, but that broke in an interesting way. Any odd inputs would process inaccurately, but even inputs would work fine. It took me a minute to realize what was going on.

When performing multiplication or addition, PowerShell treats un-typed input as a string first. So, '5'*3+1 becomes '5551' instead of 16. The even inputs behaved fine because PowerShell doesn't have a default action for division against strings. Even the even inputs which would progress through odd numbers worked fine because, by the time PowerShell got to an odd number in the loop, the variable was already forced to an integer by the math operations anyway.

Thanks to Danko Durbic for pointing out I could just invert the multiplication operation, and not have to cast read-host to int since PowerShell bases its operations on the first object.

PowerShell Golfer's Tip: For some scenarios, like this one, switch beats if/else. Here, the difference was 2 characters.

Protip courtesy of Danko Durbic: For this particular scenario, an array can be used instead of switch, to save 8 more characters!

There's no error checking for non-integer values, or integers less than two.

If you'd like to audit the script, put ;$i just before the last close brace in the script.

I'm not sure exactly how well PowerShell handles numbers that progress into very large values, but I expect accuracy is lost at some point. Unfortunately, I also expect there's not much that can be done about that without seriously bloating the script.


Ungolfed code, with comments:

# 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

Test cases:

Below are some samples with auditing enabled. I've also edited the output some for clarity, by adding labels to the input and final count and putting in spacing to set apart the Collatz values.

---
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
---

Interesting bits about the input numbers which are not from the question's test cases:

Iszi

Posted 2013-08-01T11:22:46.980

Reputation: 2 369

2Nice! You can still shorten it somewhat, by replacing switch with $i=(($i/2),($i*3+1))[$i%2] – Danko Durbić – 2013-11-30T09:32:35.237

2Also, you don't have to convert read-host to number - just change $i*3 to 3*$i. – Danko Durbić – 2013-11-30T09:52:10.860

An array instead of switch? Brilliant! And swapping $i*3 around - why didn't I think of that already? – Iszi – 2013-11-30T18:37:32.413

1param($i)for(;$i-ne1;$x++){$i=(($i/2),(3*$i+1))[$i%2]}$x - swap the read-host for a parameter, to get 56 bytes. Try It Online link – TessellatingHeckler – 2017-07-09T20:59:08.803

6

Brachylog, 16 bytes

1b|{/₂ℕ|×₃+₁}↰+₁

Try it online!

Explanation

         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.

An alternative solution at the same byte count:

;.{/₂ℕ|×₃+₁}ⁱ⁾1∧

Try it online!

;.          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.

Martin Ender

Posted 2013-08-01T11:22:46.980

Reputation: 184 808

5

GolfScript (23 chars)

~{.1&{.3*)}*.2/.(}do;],

Online test

Peter Taylor

Posted 2013-08-01T11:22:46.980

Reputation: 41 901

5

Python 68 58 54 52 chars

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

Thanks to Bakuriu and boothby for the tips :)

Valentin CLEMENT

Posted 2013-08-01T11:22:46.980

Reputation: 321

You can use n%2and 3*n+1or n/2 to save 5 characters. Also in python2 you can remove the call to int, reducing the size to 58 bytes. – Bakuriu – 2013-08-03T12:35:54.277

Oh, you can even get shorter than that: [n/2,3*n+1][n%2]. – boothby – 2013-08-06T04:14:15.467

That is nifty ! – Valentin CLEMENT – 2013-08-06T09:12:52.453

Is this python 2.7? I get an error in Python 3.5.1? unsupported operand type(s) for -: 'str' and 'int' – george – 2016-12-16T16:01:01.557

5

F# - 65 chars

let rec c n=function 1->n|i->c(n+1)(if i%2=0 then i/2 else i*3+1)

Daniel

Posted 2013-08-01T11:22:46.980

Reputation: 313

5

Retina, 43 bytes

11
2
(2+)1
$1$1$0$0$0$0
2.*
$0x
)`2
1
1?x
1

Takes input and prints output in unary.

Each line should go to its own file. 1 byte per extra file added to byte-count.

You can run the code as one file with the -s flag. E.g.:

> echo -n 1111111|retina -s collatz
1111111111111111

The algorithm is a loop of doing a Collatz step with the unary number and adding a new step-marker x at the end of the string if the number isn't 1.

When the loop ends with 1, we convert the markers to a unary number (removing the leading 1) which is the desired output.

randomra

Posted 2013-08-01T11:22:46.980

Reputation: 19 909

5

Jelly, non-competing

12 bytes This answer is non-competing, since the challenge predates the creation of Jelly.

×3‘$HḂ?ß0’?‘

Try it online!

How it works

×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.

Dennis

Posted 2013-08-01T11:22:46.980

Reputation: 196 637

4

dc, 27 characters

Applying boothby's black magic:

?[d3*1+d2%5*1+/d1<x]dsxxkzp

I'm not really sure if I understand how - or that - it works.

Usage:
$ dc collatz.dc <<< 7
16

dc, 36 characters

My own creation; a somewhat more traditional approach, even tho I had to wrangle with the language a fair bit to overcome the lack of an else part to if statements:

?[2/2Q]se[dd2%[0=e3*1+]xd1<x]dsxxkzp

Internally it produces all numbers of the sequence and stores them on the stack, then pops the final 1 and displays the stack height.

daniero

Posted 2013-08-01T11:22:46.980

Reputation: 17 193

1Parity is not black magic. – boothby – 2013-08-12T23:09:46.403

1No, but it's a very neat trick there! I have actually done similar stuff myself, I just didn't think about it in this case. What stumbled me for a second was the division, but I get it: You divide by six, reverting the first operation (*=3,+=1) with the second if the parity was wrong, and because of integer division the addition goes away too, and we've basically done /=2. Very clever :) – daniero – 2013-08-13T00:11:15.810

I hadn't seen this challenge, but blogged a while back about printing the Collatz sequence in dc. My approach is similar to yours but loses by a byte so I don't really see a reason to post it. However, when I was looking at mine to see how to easily go from printing each step to printing the number of steps, I spotted something that can golf a byte from yours...

Since the Collatz sequence will always go from 2 to 1, you can change your conditional to 2<x and get rid of the k. Just in case you want a byte back after four years. :D – brhfl – 2017-08-25T20:13:23.250

1+1. I thought I was going to crush this challenge with dc, but only got as far as 40. The I saw your 27 answer. Oh well. – Digital Trauma – 2014-05-02T00:46:01.797

4

brainfuck, 59 56 bytes

,-[<->[[>]+<[-<]>>]>[-<<[++>+<]>->]<<[+>+++<]<<+>>>]<<<.

Try it online! (Slightly modified for ease of use)

Input and output as character codes. This is more useful with arbitrarily sized cells, but can still work with small values in limited cell sizes.

How It Works

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

Jo King

Posted 2013-08-01T11:22:46.980

Reputation: 38 234

4

Hexagony, 48 44 bytes

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

Try it online!

Expanded:

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

Note that this fails on 1 for uhh... reasons. Honestly, I'm not really sure how this works anymore. All I know is that the code for odd numbers is run backwards for even numbers? Somehow?

The new version is much cleaner than the previous, but has a few more directionals in comparison and also ends in a divide-by-zero error. The only case it doesn't error is when it actually handles 1 correctly.

Jo King

Posted 2013-08-01T11:22:46.980

Reputation: 38 234

If a number < 2 is input ... output does not matter. :o) – Sok – 2018-03-27T12:47:45.770

@Sok Yep, that's why I posted it instead of going insane trying to fix that – Jo King – 2018-03-27T12:49:23.167

3

Q,46

{i::0;{x>1}{i+:1;$[x mod 2;1+3*x;(_)x%2]}\x;i}

tmartin

Posted 2013-08-01T11:22:46.980

Reputation: 3 917

32 bytes with (#)1_(1<){(1+3*x;x%2)0=x mod 2}\ – streetster – 2017-10-26T22:17:02.947

3

C, 70 69 chars

Quite simple, no tricks.
Reads input from stdin.

a;
main(b){
    for(scanf("%d",&b);b-1;b=b%2?b*3+1:b/2)a++;
    printf("%d",a);
}

ugoren

Posted 2013-08-01T11:22:46.980

Reputation: 16 527

3

C++ (51 48)

This is a recursive function that does this; input reading comes separately.

int c(n){return n==1?0:1+(n%2?c(n*3+1):c(n/2));}

I'm sure I can do some sort of "and/or" trick with the == 0 stuff, but I have no idea how.

Joe Z.

Posted 2013-08-01T11:22:46.980

Reputation: 30 589

.n==1==n<2. – CalculatorFeline – 2016-04-18T16:53:11.390

You could remove the ==0 and swap the sides of the conditional – Doorknob – 2013-11-30T15:30:27.157

Also, no need to handle n==1 because I specified in the question that the number is always greater than 1 – Doorknob – 2013-11-30T15:31:56.980

The problem is that n==1 is the base recursion case. Putting n==2 there wouldn't improve the score any. – Joe Z. – 2013-11-30T17:57:11.963

Ah, then you could just replace it with this: return~-n? and swap the conditional sides – Doorknob – 2013-11-30T23:20:48.403

3

Ruby 1.9, 49 characters

Rubyfied Valentin CLEMENT's Python answer, using the stabby lambda syntax. Sqeezed it into one statement for added unreadability.

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

Some overhead because Ruby, unlike Python, is not happy about mixing numbers with booleans.

daniero

Posted 2013-08-01T11:22:46.980

Reputation: 17 193

3

~-~! (No Comment) - 71 53

This language is obviously not the best for golfing since it lacks a large amount of native functionality, but that's the beauty of it.

'=|*;~~[*,~~~-~]*/~~|:''=|'''==~[*]'''='&''':''&*+~|:

First, set ''' to your input. The function '' can then be called with % as it's input and will return the answer, like so:

'''=~~~~~:''&%:

This will return ~~~~~. It actually works for n==1 (it loops forever with n==0).

As always with this language, untested.

cjfaure

Posted 2013-08-01T11:22:46.980

Reputation: 4 213

3

Perl 6, 40 bytes

Recursive function method, as per Valentin CLEMENT and daniero: 40 characters

sub f(\n){n>1&&1+f n%2??3*n+1!!n/2}(get)

Lazy list method: 32 characters

+(get,{$_%2??$_*3+1!!$_/2}...^1)

Mouq

Posted 2013-08-01T11:22:46.980

Reputation: 906

3

JavaScript (ES6) - 29 Characters

f=x=>x>1?f(x%2?x*3+1:x/2)+1:0

Creates a function f which accepts a single argument and returns the number of iterations.

JavaScript - 31 Characters

for(c=0;n>1;n=n%2?n*3+1:n/2)++c

Assumes that the input is in the variable n and creates a variable c which contains the number of iterations (and will also output c to the console as its the last command).

MT0

Posted 2013-08-01T11:22:46.980

Reputation: 3 373

128 bytes – Shaggy – 2019-01-24T12:23:04.887

3

><>, 27 26 23 bytes

\ln;
\::2%:@5*1+2,*+:2=?

Like the other ><> answers, this builds the sequence on the stack. Once the sequence reaches 2, the size of the stack is the number of steps taken.

Thanks to @Hohmannfan, saved 3 bytes by a very clever method of computing the next value directly. The formula used to calculate the next value in the sequence is:

$$f(n)=n\cdot\frac{5(n\bmod2)+1}{2}+(n\bmod2)$$

The fraction maps even numbers to 0.5, and odd numbers to 3. Multiplying by n and adding n%2 completes the calculation - no need to choose the next value at all!

Edit 2: Here's the pre-@Hohmannfan version:

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

The trick here is that both 3n+1 and n/2 are computed at each step in the sequence, and the one to be dropped from the sequence is chosen afterwards. This means that the code doesn't need to branch until 1 is reached, and the calculation of the sequence can live on one line of code.

Edit: Golfed off another character after realising that the only positive integer that can lead to 1 is 2. As the output of the program doesn't matter for input < 2, the sequence generation can end when 2 is reached, leaving the stack size being the exact number of steps required.

Previouser version:

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

Sok

Posted 2013-08-01T11:22:46.980

Reputation: 5 592

1You can golf it to 23 if you unbranch the second line even more: \::2%:@5*1+2,*+:2=? – SE - stop firing the good guys – 2016-12-14T01:04:21.943

2

Clojure, 60 bytes

(fn c[n](if(= n 1)0(inc(c(if(even? n)(/ n 2)(+(* n 3)1))))))

Pretty standard. Recursive function that recurses when n isn't equal to one. Each iteration, one is added to the accumulator via inc.

While this uses unoptimized recursion, I'm currently testing to see when it fails. It's at 1711000000, and is still going. The highest number of steps I've seen so far is 1008, so I don't expect it to fail anytime soon.

Pregolfed:

(defn collatz-conj [n]
  (if (= n 1)
    0 ; Base case
    (inc ; Add one to step
      (collatz-conj ; Recurse
        (if (even? n) ; The rest should be be self-explanatory
          (/ n 2)
          (+ (* n 3) 1))))))

Carcigenicate

Posted 2013-08-01T11:22:46.980

Reputation: 3 295

You can save 1 byte by using odd? instead of even?. You can save another byte by replacing (inc(...)) with (+(...)1) – user84207 – 2018-01-09T03:55:37.200

2

Alice, 26 bytes, non-competing

/2:k@
.i#o3*hk
^d/.2%.j.t$

Try it online!

Explanation

This makes use of Alice's "jump and return" commands which allow you to implement subroutines. They're not at all separately scoped or otherwise encapsulated and nothing is stopping you from leaving the "subroutine", but if you want you can basically use them to jump to a different place in the code to do whatever you need and then continue where you left off. I'm using this to choose between two different "subroutines" depending on the parity of the current value to either halve it or triple and increment it.

To count the number of steps, we simply make a copy of the value at each step and check the stack depth at the end.

/     Reflect to SE. Switch to Ordinal.
i     Read the input as a string.
/     Reflect to E. Switch to Cardinal.
.     Duplicate the input.
2%    Take the current value modulo 2 to get its parity.
.     Duplicate it. So for even inputs we've got (0, 0) on top of the stack
      and for odd inputs we've got (1,1).
j     Use the top two values to jump to the specified point on the grid. That's
      either the top left corner, or the cell containing the i.
      Using j also pushes the original position of the IP (the cell containing j
      in this case) to a separate return address stack, so we can return here
      later.
      Note that the IP will move before executing the first command.

      Subroutine for even values:

  2:    Divide by 2.
  k     Pop an address from the return stack and jump back there (i.e. to the j).

      Subroutine for odd values:

  #     Skip the next command (the 'o' is there for a later part of the code).
  3*    Multiply by 3.
  h     Increment.
  k     Pop an address from the return stack and jump back there (i.e. to the j).

      Either way, we continue after the j:

.     Duplicate the new value.
t     Decrement it, to get a 0 if we've reached 1.
$     Skip the next value if the result was 0.

      This part is run if the current value wasn't 1 yet:

  ^     Send the IP north.
  .     Duplicate the current value to increase the stack depth.
  /     Reflect to SW. Switch to Ordinal.
        Immediately reflect off the left boundary and move SE.
  i     Try to read more input, but this just pushes an empty string.
        However, the next command will be the duplication . which tries to
        duplicate an integer, so this empty string is immediately discarded.
        After that we start the next iteration of the loop.

     This part is run once the value reaches 1:

  d     Push the stack depth.
  /     Reflect to SE. Switch to Ordinal.
        Immediately reflect off the bottom boundary and move NE.
  o     Implicitly convert the stack depth to a string and print it.
  @     Terminate the program.

Martin Ender

Posted 2013-08-01T11:22:46.980

Reputation: 184 808

2

Aceto, 33 bytes

&)
(I2/(I)&
+3_!
1*2%
i@d|(
rd1=p

Explanation:

Read an integer:

i
r

Set a catch point, duplicate the number and check if it's 1, if so, we mirror horizontally (meaning we end up on the ( next to the |):

 @ |
 d1=

Duplicate the value again, check if it's divisible by 2, if so, we mirror vertically (ending up on the 2 above):

  _!
  2%

Otherwise, multiply by 3, add 1, go one stack to the left, increment the number there (initially zero), go back to the original stack, and raise (jumping back to the catch point):

&)
(I
+3
1*

If it was divisible, we divide the number by two, and again increment the stack to the left and jump to the catch point:

  2/(I)&

When the number is 1 after jumping to the catch point, we go to the left stack and print that number (and exit):

    (
    p

L3viathan

Posted 2013-08-01T11:22:46.980

Reputation: 3 151

2

newLISP - 94 chars

Strangely similar to Valentin's Scheme answer... :) I'm let down here by verbosity of the language but there's a bitshift division which appears to work...

(let(f(fn(x)(cond((= x 1)0)((odd? x)(++(f(++(* 3 x)))))(1(++(f(>> x)))))))(f(int(read-line))))

cormullion

Posted 2013-08-01T11:22:46.980

Reputation: 569

2

TCL 8.5 (71 70 68) (67)

TCL has no real chance of ever winning, but it is a fun way to oil the machine:

proc c x {while \$x>1 {set x [expr $x%2?3*$x+1:$x/2];incr k};set k}

formatted for readability:

proc c x {
    while {$x>1} {
    set x [expr $x%2 ? 3*$x+1 : $x/2]
    incr k
    }
    set k
}

Edits: many suggestions (inspired) by sergiol. I guess the answer is more theirs than mine, by now :-)

Rolazaro Azeveires

Posted 2013-08-01T11:22:46.980

Reputation: 141

1Didactic post to make me now that applying incr to an undefined variable interprets it as 0 and then does the increment! – sergiol – 2017-01-19T01:44:04.003

is all the whitespace really neccessary? – John Dvorak – 2013-11-09T20:06:09.437

1@JanDvorak I think it is, in TCL. – Doorknob – 2013-11-09T20:08:17.613

You can shave one character off if you replace while {$x>1} by while \$x>1 – sergiol – 2017-04-04T09:18:32.090

@JanDvorak Yes, as far as I know. Say, trying 'while{$x>1}' results in the error 'invalid command name "while{7>1}"' (executing 'tclsh collatz-conjecture.tcl 7'). That is, the interpreter substitutes $x, and then assumes the resulting string to be a command, and it is quite liberal to what may be a command name. – Rolazaro Azeveires – 2013-11-09T20:17:18.053

@sergiol done, tks :-) – Rolazaro Azeveires – 2017-04-04T21:32:31.620

1

@RolazaroAzeveires: You are loosing to answers which implement it as a function. I purpose sthg like: proc c x {while \$x>1 {set x [expr $x%2?3*$x+1:$x/2];incr k};set k} — 67. demo: http://rextester.com/LLUS24241

– sergiol – 2017-04-05T09:36:40.717

@sergiol Right. I also note that set k could have been used in the "full program" version, which would bring it down to 68. I'll use both (somehow a function instead of a full program feels like cheating :-) as a function needs to be called from somewhere) – Rolazaro Azeveires – 2017-04-05T21:47:49.313

2

Emacs/Common Lisp, 61 bytes

(defun f(n)(if(= 1 n)0(1+(f(if(oddp n)(1+(* 3 n))(/ n 2))))))

alternatively:

(defun f(n)(if(= 1 n)0(1+(f(if(oddp n)(+ n n n 1)(/ n 2))))))

user84207

Posted 2013-08-01T11:22:46.980

Reputation: 171

2

Game Maker Language, 63 61 60 bytes

Make script/function c with this code and compile with uninitialized variables as 0:

a=argument0while(a>1){i++if i mod 2a=a*3+1else a/=2}return i

Call it with c(any number) and it will return how many times it took to become 1.

Timtech

Posted 2013-08-01T11:22:46.980

Reputation: 12 038

2

Befunge-93, 29 bytes

&<\+1\/2+*%2:+2*5:_$#-.#1@#:$

Try it online!

A nice and concise one-liner. This uses the formula (n+(n*5+2)*(n*5%2))/2 to calculate the next number in the series.

Jo King

Posted 2013-08-01T11:22:46.980

Reputation: 38 234

2

Ruby, 35 bytes

f=->n{n<2?0:1+f[n*3/(6-5*w=n%2)+w]}

Try it online!

How it works

Instead of getting the 2 values and choosing one, multiply by 3, divide by 1 if odd, or 6 if even, and then add n modulo 2.

G B

Posted 2013-08-01T11:22:46.980

Reputation: 11 099

2

Emojicode, 157 bytes

➡️ac 0▶️a 1a 2 0a➗a 2a➕✖️a 3 1c➕c 1c 10

Try it online!

Explanation:

    
➡️
a       input integer variable 'a'
c 0          counter variable
▶️a 1       loop while number isn’t 1
a 2 0      if number is even
a➗a 2        divide number by 2

       else
a➕✖️a 3 1    multiply by 3 and add 1

c➕c 1      increment counter

c 10    return final count as string



  16

X1M4L

Posted 2013-08-01T11:22:46.980

Reputation: 1 586

2

MATL, 21 16 bytes

Saved 5 bytes thanks to Luis Mendo! I didn't know while had a finally statement that could be used to get the iteration index. Keeping track of the number of iterations took a lot of bytes in my original submission.

`to?3*Q}2/]tq}x@

Try it online!

Explanation:

`t                % grab input implicitly and duplicate it.
                  % while ...
 o?                % the parity is `1` (i.e. the number is odd
   3*Q              % multiply it by 3 and increment it
  }                % else
   2/               % divide it by 2
  ]                % end if
 tq               % Duplicate the current value and decrement it
}                 % Continue loop if this value is not zero (i.e. the current value is >1
x                 % Else, delete the current value (the 0)
@                 % And output the "while index" (i.e. the number of iterations)

Stewie Griffin

Posted 2013-08-01T11:22:46.980

Reputation: 43 471

2

Jelly, 10 bytes

×3‘ƊHḂ?Ƭi2

Try it online!

How it works

×3‘ƊHḂ?Ƭi2    Main link (monad). Input: integer >= 2
      ?       Create a "ternary-if" function:
     Ḃ          If the input is odd,
×3‘Ɗ            compute 3*n+1;
    H           otherwise, halve it.
       Ƭ      Repeat until results are not unique; collect all results
        i2    Find one-based index of 2

Example: The result of ...Ƭ for input 5 is [5, 16, 8, 4, 2, 1]. The one-based index of 1 is 6, which is 1 higher than expected. So we choose the index of 2 (which is guaranteed to come right before 1) instead.

Bubbler

Posted 2013-08-01T11:22:46.980

Reputation: 16 616

2

05AB1E, 16 15 bytes

-1 byte thanks to Kevin Cruijssen

[Éi3*>ë2÷}¼Ð#]¾

Try it online!

Explanation

                  # Implicit input: integer n
[              ]  # Infinite loop
   i       }      # if:
  É               # n is odd
    3*>           # compute 3n+1
       ë          # else:
         2÷       # compute n//2
            ¼     # increment counter variable
             Ð    # Triplicate
              #   # Break loop if n = 1
                ¾ # output counter variable

Wisław

Posted 2013-08-01T11:22:46.980

Reputation: 554

wait. why does halve not work? floating point errors, i guess? – ASCII-only – 2019-01-19T01:19:09.350

yup, it turns integers into floats and I dont see a way to implicitly turn it into an integer again after halving – Wisław – 2019-01-19T01:30:53.433

You can save a byte removing the first D and changing the second D to Ð (in the first iteration it will implicitly use the input twice). (And you might want to change n/2 to n//2 or n integer-divided by 2 in your explanation to make it clear you're integer-dividing.) – Kevin Cruijssen – 2019-01-28T14:32:12.497

Thanks @KevinCruijssen! I am still bad at taking advantage of implicit input :-) – Wisław – 2019-01-28T15:00:51.280

14 bytes – Zylviij – 2019-04-30T19:10:01.177

2

Haskell 73 Bytes 73 Chars

r n |even n=n`quot`2
    |otherwise=3*n+1
c=length.takeWhile(/=1).iterate r

PyRulez

Posted 2013-08-01T11:22:46.980

Reputation: 6 547

3otherwise in golf??? Use 1>0 – John Dvorak – 2014-05-10T07:32:16.253

1You can save another 2 chars with takeWhile(>1) and \div``. – sjy – 2014-09-22T02:51:58.010

2

Fish (33 chars including whitespace, 26 without)

:2%?v:2,  >:1=?v
    >:3*1+^;nl~<

The whitespace is necessary for it to function, as ><> is a 2D language. Example run:

$ python3 fish.py collatz.fish -v 176
18

TalkTakesTime

Posted 2013-08-01T11:22:46.980

Reputation: 51

2

Befunge, 42 40 bytes

Surprisingly short to be an esolang! I thank @Sok for showing how to avoid one extra branching in his answer. Saved 2 bytes after a complete rewriting of the code.

0&>\1+\:2/\:3v
.$<v_v#%2\+1*<@
`!|>\>$:1

Original answer:

1&>:2%v>2v
^\+1*3_^ /
>+v  v`1:<
^1\#\_$.@

Shold be compatible with both Befunge 93 and Befunge 98. Interpretor available here.

There is no need for a trailing white space after @, so I count it as 42. However, 2D languages are often counted by their bounding box.

SE - stop firing the good guys

Posted 2013-08-01T11:22:46.980

Reputation: 529

We count all answers by their length in bytes. If you don't need the trailing space, leave it off and save yourself a byte. Bounding box doesn't matter here. – Mego – 2016-04-18T05:53:57.403

Glad to have helped :o) – Sok – 2016-05-05T14:40:54.063

1If you try to pop a value from the stack, and there aren't any values on the stack, a 0 is popped. Therefore, the stack is filled with an infinite amount of 0s for practical purposes. Because of this, you don't need the 0 at the beginning of your program, letting you shift over each line to save a byte. I can suggest an edit to show you what I mean, if you want. – MildlyMilquetoast – 2016-12-05T17:58:11.860

2

Julia, 29 27 bytes

!n=n>1&&1+!(n%2>0?3n+1:n/2)

I can't seem to compile Julia 0.1 on my machine, so there's a chance this is non-competing.

Try it online!

Dennis

Posted 2013-08-01T11:22:46.980

Reputation: 196 637

2

Python 2, 38 37 bytes

f=lambda n:n<3or-~f([n/2,n*3+1][n%2])

Thanks to @user84207 for a suggestion that saved 1 byte!

Note that this returns True instead of 1.

Try it online!

Dennis

Posted 2013-08-01T11:22:46.980

Reputation: 196 637

you could save one byte by using n<1or instead of n>1and – user84207 – 2018-01-09T04:13:55.177

@user84207 n<1or doesn't work (n is never less than 1) and n<2or would be off by one, but n<3or works just fine. Since 0 == False and 1 == True in Python, returning Booleans is allowed by default.

– Dennis – 2018-01-09T14:01:10.337

1

QBIC, 34 33 bytes

:{~-a|_Xb\b=b+1~a%2|a=a*3+1\a=a/2

Pretty straightforward:

:           Name the Command Line Parameter 'a'
{           Start an infinite loop
~-a|_Xb     If 'a' = 1 (or -a = -1, QB's TRUE value), quit printing 'b'
\           ELSE (a > 1)
b=b+1       Increment step counter
~a%2        In QBasic, 8 mod 2 yields 0, and 0 is considered false
|a=a*3+1    Collatz Odd branch
\a=a/2      Collatz Even branch

steenbergh

Posted 2013-08-01T11:22:46.980

Reputation: 7 772

1

Befunge 93, 37 bytes

Try it Online!

&>:1-|
\@#-1<+2_.#
v#%2:<+1*3:_
<v/2:

Explanation:

&         Take integer input
 >:1-|    If the top of the stack is 1, go to the 2nd line.
          Else, go the third.

----------------------------------------------

\  -1<+2_      The top of the stack is 1, which becomes the counter for
               the stack size. If the second-to-the-top of the stack is
               non-zero, consume that value and increment the counter by 1.

 @       .     If the second-to-the-top of the stack is 0, i.e. there are
               no elements besides the counter, output the counter and
               terminate the program.

----------------------------------------------

v#%2:<     _    The top of the stack is non-zero. Check if the top of
                the stack is divisible by 2, and execute 1 of the
                following accordingly:

      +1*3:     The top of the stack (a) is odd, so push 3a + 1,
                and check the top mod 2 again.

<v/2:           The top of the stack (a) is even, so push a / 2,
                and check if the top is 1 again.

Like other programs, this pushes each iteration onto the stack until the top is 1, and outputs the stack size - 1.

I was able to make this program shorter by not testing if the top was 1, if the previous iteration was odd. Also, in counting the stack size, I used the fact that the top of the stack will always be 1.

MildlyMilquetoast

Posted 2013-08-01T11:22:46.980

Reputation: 2 907

1

Clojure, 77 bytes

#(loop[x % a 0](if(= x 1)a(recur(if(=(mod x 2)0)(/ x 2)(+(* x 3)1))(inc a))))

Defines an anonymous function. Usage is like so:

(#(...) {num})

Ungolfed:

(defn collatz [n]
  (loop [x n
         a 0]
    (if (= x 1) a
      (recur (if (= (mod x 2) 0) (/ x 2) (+ (* x 3) 1)) (inc a)))))

clismique

Posted 2013-08-01T11:22:46.980

Reputation: 6 600

1

C (gcc), 43 33 bytes

f(x){x=~-x?f(x&1?3*x+1:x/2)+1:0;}

Try it online!

Bijan

Posted 2013-08-01T11:22:46.980

Reputation: 781

1

C, 38 bytes

g(v){return v^1?1+g(v&1?v*3+1:v/2):0;}

2501

Posted 2013-08-01T11:22:46.980

Reputation: 748

1

Casio-Basic, 83 72 bytes

71 bytes for code, +1 for n as parameter.

0⇒z
While n≠1
piecewise(mod(n,2),3n+1,n/2)⇒n
z+1⇒z
WhileEnd
Print z

numbermaniac

Posted 2013-08-01T11:22:46.980

Reputation: 639

1

PARI/GP, 38 bytes

a(n)=if(n==1,0,a(if(n%2,3*n+1,n/2))+1)

Try it online!

Equivalent to this readable C code:

int b(n)
{
    if (n % 2)
        return 3 * n + 1;
    else
        return n / 2;
}

int a(n)
{
    if (n == 1)
        return 0;
    else
        return a(b(n)) + 1;
}

MD XF

Posted 2013-08-01T11:22:46.980

Reputation: 11 605

1

tinylisp repl, 68 bytes

(load library)(d f(q((n)(i(e n 1)0(inc(f(i(even? n)(/ n 2)(inc(* 3 n

Try it online! (Note that the repl auto-closes parentheses; on TIO, they have to be explicitly closed, which I've done in the footer.)

This is the same recursive solution as, e.g., Carcigenicate's Clojure answer. Because tinylisp has only addition and subtraction built in, I load the standard library to get even?, /, and * (and inc, which is the same length as a 1 but looks nicer). Other library functions would make the code longer; for instance, I'm defining the function manually with (q((n)(...))) rather than using (lambda(n)(...)). Here's how it would look ungolfed and indented:

(load library)
(def collatz
  (lambda (n)
    (if (equal? n 1)
      0
      (inc
        (collatz
          (if (even? n)
            (/ n 2)
            (inc (* 3 n))))))))

Going the other direction, here's a 101-byte solution that doesn't use the library. The E function returns n/2 if n is even and the empty list (falsey) if n is odd, so it can be used both to test evenness and to divide by 2.*

(d E(q((n _)(i(l n 2)(i n()_)(E(s n 2)(a _ 1
(d f(q((n)(i(e n 1)0(a 1(f(i(E n 0)(E n 0)(a(a(a n n)n)1

* Only works for strictly positive integers, but that's exactly what we're dealing with in this challenge.

DLosc

Posted 2013-08-01T11:22:46.980

Reputation: 21 213

1

Acc!!, 127 75 bytes

Count u while N/49 {
_+1
}
Count i while _-1 {
_/2+_%2*(5*_/2+2)
Write 49
}

The program takes input and produces output in unary. Try it online!

(Here's a decimal I/O version in 209 bytes.)

With comments

# Read input in unary
Count u while N/49 {   # Increment u from 0 while input character is >= "1"
  _+1                  # Add one to accumulator
}

# Main loop
Count i while _-1 {    # Increment i from 0 while accumulator is not equal to 1
  _/2+_%2*(5*_/2+2)    # Apply one step of Collatz function to accumulator
  Write 49             # Write "1" to output
}

The expression _/2+_%2*(5*_/2+2) boils down to

_/2,               if _%2 is 0
_/2 + (5*_)/2 + 2, if _%2 is 1

This is integer division, so the latter case comes out to

_/2 + 2*_ + _/2 + 2
 = 2*_ + (_/2)*2 + 2
 = 2*_ + _ + 1
 = 3*_ + 1

DLosc

Posted 2013-08-01T11:22:46.980

Reputation: 21 213

1

Attache, 11 bytes

CollatzSize

Try it online!

Not much to say...

Conor O'Brien

Posted 2013-08-01T11:22:46.980

Reputation: 36 228

1

Java (136)

public class C {public static void main(String[] a) {int i=27,c=0;while(i!=1;{c++;if(i%2==0)i/=2;else i=3*i+1;}System.out.println(c);}}

Just change the value of i to the input. For 27, it prints 111 to the console.

Whitespace view:

public class C {
    public static void main(String[] a) {
        int i=27,c=0;
        while(i!=1) {
            c++;
            if(i%2==0)
                i/=2;
            else
                i=3*i+1;
        }
        System.out.println(c);
    }
}

I know it isn't the shortest, but I figured I'd give it a whirl. Any suggestions would be appreciated. ;)

I have to say I'm a little envious of all those who know the short languages. I'd love to see this done in Brainf**k.

Andrew Gies

Posted 2013-08-01T11:22:46.980

Reputation: 111

Wish granted – Jo King – 2017-12-27T14:27:37.257

1

Wumpus, 22 bytes

I]=2:~3*)=&~~!0~.
l(O@

Try it online!

Explanation

The first line is the main loop which iterates the Collatz function until we get 1. We keep track of the number of steps by growing the stack by one element on each iteration.

I   Read a decimal integer N from STDIN. At EOF (i.e. on subsequent 
    iterations) this pushes 0 instead.
]   Rotate the stack right. On the first iteration, this does nothing, but
    afterwards this moves the 0 to the bottom of the stack.
=   Duplicate N.
2:  Compute N/2.
~   Swap with the other copy of N.
3*) Compute 3N+1.
=   Duplicate.
&~  3N+1 times: swap N/2 and 3N+1. If N is odd, 3N+1 is even and vice versa.
    We end up with the value that we want on top and the incorrect one
    underneath.
~   Swap them once more.
!   Logical NOT. 3N+1 is always positive and N/2 gives 0 iff N = 1 (in which 
    case N/2 will also be on top of the stack). So this essentially gives us
    1 iff N = 1 (and 0 otherwise). Call this value y.
0~. Jump to (0, y), i.e. to the beginning of the second line once we reach N = 1
    and to the beginning of the first line otherwise.

Once we reach 1:

l   Push the stack depth. The stack holds one zero for each iteration as well
    as the final result. But note that we won't terminate until the iteration
    that process 1 itself (because we check the condition at the end of
    the loop, but based on its initial N). So the stack depth is one
    greater than the number of steps to reach 1.
(   Decrement.
O   Print as decimal integer.
@   Terminate the program.

I've got an alternative 22 byte solution, but unfortunately I haven't found anything shorter yet:

I]3*)=2%5*):=(!0~.
lO@

Martin Ender

Posted 2013-08-01T11:22:46.980

Reputation: 184 808

1

Japt, 18 15 bytes

É©Òß[U*3ÄUz]gUv

Try it

Shaggy

Posted 2013-08-01T11:22:46.980

Reputation: 24 623

1

Java (OpenJDK 8), 54 bytes

a->{int c=0;for(;a!=1;c++)a=a%2>0?a*3+1:a/2;return c;}

Try it online!

This answer is a little to simple to justify an explanation, it’s just a while loop and a ternary expression.

X1M4L

Posted 2013-08-01T11:22:46.980

Reputation: 1 586

1

PHP, 80 73 Bytes

Tried a recursive function Try it here! (80 Bytes)

Try it online (73 Bytes)

Code (recursive function)

function f($n,$c=0){echo($n!=1)?(($n%2)?f($n*3+1,$c+1):f($n/2,$c+1)):$c;}

Output

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

Explanation

function f($n,$c=0){ //$c counts the iterations, $n the input
echo($n!=1)?    
(($n%2)?
    f($n*3+1,$c+1): //$n is odd
    f($n/2,$c+1))   //$n is even
:$c;                 //echo $c (counter) when n ==1
}

Francisco Hahn

Posted 2013-08-01T11:22:46.980

Reputation: 591

No, the test cases aren't part of the byte count. Your submission looks fine as it is. – Martin Ender – 2018-03-26T13:42:55.253

1

Octave, 65 bytes

@(x)eval 'k=0;do++k;if mod(x,2)x=3*x+1;else x/=2;end,until x<2,k'

Try it online!

It's time we have an Octave answer here. It's a straight forward implementation of the algorithm, but there are several small golfs.

Using do ... until instead of while ... end saves some bytes. Instead of having while x>1,k++;...end, we could have do++k;...until x<2, saving two bytes. Using eval in an anonymous function saves a few bytes, compared to having input(''). Also, skipping the parentheses in the eval call saves some bytes.

Stewie Griffin

Posted 2013-08-01T11:22:46.980

Reputation: 43 471

1

Ruby, 48 bytes

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

Same as other Ruby, but using n%2?a:b syntax instead of [a,b][n%2]. Saves one char.

Joey

Posted 2013-08-01T11:22:46.980

Reputation: 11

You mention that you save one byte off of the other Ruby answer yet your answer is 13 bytes longer because of (...)[gets.to_i]. Even if I remove that (which doesn't break your answer) you still have the same length as the other answer. This is ok, I just thought maybe you might have made a mistake. – Post Rock Garf Hunter – 2018-06-19T14:11:14.620

1

MathGolf, 7 bytes

kÅ■┐▲î 

Don't get fooled, there's a non-breaking space at the end of the program.

Try it online!

Explanation

k        Read input as integer
 Å       Start a block of length 2
  ■      Map TOS to the next item in the collatz sequence
   ┐     Push TOS-1 without popping
    ▲    Do block while TOS is true
     î   Push the length of the last loop
         Discard everything but top of stack

MathGolf, 14 bytes (no built-ins, provided by JoKing)

{_¥¿É3*)½┐}▲;î

Explanation

{               Start block of arbitrary length
 _              Duplicate TOS
  ¥             Modulo 2
   ¿            If-else (works with TOS which is 0 or 1 based on evenness)
    É3*)        If true, multiply TOS by 3 and increment
        ½       Otherwise halve TOS
         ┐      Push TOS-1 (making the loop end when TOS == 1)
          }▲    End block, making it a do-while-true with pop
            ;   Discard TOS
             î  Print the loop counter of the previous loop (1-based)

Ideally, this solution could become 13 bytes, since it's not neccessary to have the ending of the block be explicit when the loop type instruction comes right after. I'll see when I get around to coding implicit block ending when loop type is present.

Try it online!

maxb

Posted 2013-08-01T11:22:46.980

Reputation: 5 754

This is 12 bytes if you don't use the collatz operator

– Jo King – 2018-10-06T08:39:29.460

Nice solution! I'll have to analyze a bit before I understand it completely. I wrote this solution when the language was still really new, there are a bunch of new features now – maxb – 2018-10-06T09:25:33.413

@JoKing I've looked your solution over, and I might have to clarify the documentation, (documented as "triplicate TOS") does not push TOS*3, but instead pushes TOS 3 times. Your solution gives the correct input for powers of 2, but fails for e.g. input 7. – maxb – 2018-11-15T08:15:19.550

Lol, my bad. In that case, it would be 14 bytes

– Jo King – 2018-11-15T09:14:17.343

1

Keg -rR, 23 bytes (SBCS)

I really need to remember those new instructions.

0&{:1>|:2%[3*⑨|½]⑹

Try it online!

user85052

Posted 2013-08-01T11:22:46.980

Reputation:

-5 bytes with -rR and new register commands – Lyxal – 2019-12-13T20:24:15.160

1

Python (73):

Can probably be golfed a heck of a lot more.

i=0
while 1:
 i+=1;j=i;k=0
 while j!=1:j=(j/2,j*3+1)[j%2];k+=1
 print i,k

ɐɔıʇǝɥʇuʎs

Posted 2013-08-01T11:22:46.980

Reputation: 4 449

1

Python 2, 59 57 55 54 bytes

i=0;n=input()
while~-n:n=[n/2,n*3+1][n%2];i+=1
print i

nyuszika7h

Posted 2013-08-01T11:22:46.980

Reputation: 1 624

You can remove the indentation and newline for the while loop, while n>1:n=.... works the same. – Rɪᴋᴇʀ – 2016-05-04T14:27:12.357

@EᴀsᴛᴇʀʟʏIʀᴋ Thanks, I thought that didn't work when there are multiple statements inside. – nyuszika7h – 2016-05-04T18:45:20.747

It does work, as long as you don't have any other "indent required" statements such as another loop. Semicolons work fine for plain statements though. – Rɪᴋᴇʀ – 2016-05-04T20:03:47.447

1Can't you remove greater than 0, as it can only be 1 or 0? – Destructible Lemon – 2016-12-06T00:29:05.933

@DestructibleWatermelon You're right, thanks. – nyuszika7h – 2016-12-06T23:13:36.230

1Since n can't be 0, can you do while~-n: to save a byte? – Destructible Lemon – 2016-12-07T05:34:22.100

@DestructibleWatermelon Yeah, that works, thanks. I don't use bitwise operators too much, didn't think of that. – nyuszika7h – 2016-12-08T10:54:17.663

1

This Programming Language, 59

v>v>_1=?v_2%?v2/  v
}0"     >~"i;>3*1+v
>^>^          "+1"<

Not the shortest, but an interesting program nonetheless.

BobTheAwesome

Posted 2013-08-01T11:22:46.980

Reputation: 509

If this is anything like ><>, that's a lot of whitespace that could be golfed out... – Sp3000 – 2015-03-15T01:46:50.667

I wrote this program with a headache and I'm not really in the mood to golf it right now. – BobTheAwesome – 2015-03-15T02:04:17.147

1

K, 24 bytes

#1_(1<){(x%2;1+3*x)x!2}\

With test cases:

  (#1_(1<){(x%2;1+3*x)x!2}\)'2 16 5 7
1 4 5 16

This uses a bit of a cute trick to avoid conditionals- (x%2;1+3*x) builds a list of the potential next term and then the parity calculated by x!2 indexes into that list. Otherwise it's a straightforward application of the "do while" form of \, given the tacit predicate (1<) (while greater than 1) as a stopping condition:

  (1<){(x%2;1+3*x)x!2}\5
5 16 8 4 2 1

The example output indicates that we need to drop the first (1_) of this sequence before taking the count (#). This is slightly shorter than taking the count and then subtracting one.

JohnE

Posted 2013-08-01T11:22:46.980

Reputation: 4 632

1

Pyth 27 23 22 chars

W>Q1=hZ=Q?h*Q3%Q2/Q2)Z

online

Pyth is much newer than the challenge and therefore won't count as a winning candidate

gcq

Posted 2013-08-01T11:22:46.980

Reputation: 251

Btw. W>Q1 is the same thing as WtQ – Jakube – 2015-05-29T09:05:48.900

I didn't even look at the date ;) And thanks. – gcq – 2015-05-29T09:06:36.577

If your interested in a 18 bytes solution: fq1=Q?h*Q3%Q2/Q2 1 gives 18 bytes. And I'm sure you can golf this even further. – Jakube – 2015-05-29T09:07:11.370

The usage of f...1 not really documented (at least not good). It basically means: "find the first number >= 1, that satisfies ..." – Jakube – 2015-05-29T09:12:44.030

That's good to know, tried to find that on the docs but no luck – gcq – 2015-05-30T20:03:24.410

1

><>, 28 bytes

:1=?v::2%?v2,
+c0.\l1-n;\3*1

This takes input from the stack, computes the different steps on the stack, then returns its size when 1 is reached.

Aaron

Posted 2013-08-01T11:22:46.980

Reputation: 3 689

That is one of the most beautiful snippets of ><> I have ever seen. – SE - stop firing the good guys – 2016-04-14T15:29:23.567

Hu, is it? Thanks ! You might like my FizzBuzz one then, it's got a few control-flow tricks I was proud of.

– Aaron – 2016-04-14T15:56:59.843

1

Oracle SQL 11.2, 122 bytes

WITH v(n,i)AS(SELECT:1,0 FROM DUAL UNION ALL SELECT DECODE(MOD(n,2),0,n/2,n*3+1),i+1 FROM v WHERE n>1)SELECT MAX(i)FROM v;

Un-golfed :

WITH v(n,i)AS   -- Recursive view, n=>current value, i=>iterations count
(
  SELECT :1,0 FROM DUAL -- Initialize with parameter and 0 iteration count 
  UNION ALL
  SELECT DECODE(MOD(n,2),0,n/2,n*3+1),i+1 -- Compute the next value
  FROM   v WHERE n>1 -- End when it reaches 1  
)
SELECT MAX(i)FROM v -- Return only the last iteration count

Jeto

Posted 2013-08-01T11:22:46.980

Reputation: 1 601

1

Mathcad, 36 "bytes"

enter image description here

From user perspective, Mathcad is effectively a 2D whiteboard, with expressions evaluated from left-to-right,top-to-bottom. Mathcad does not support a conventional "text" input, but instead makes use of a combination of text and special keys / toolbar / menu items to insert an expression, text, plot or component. For example, type ":" to enter the definition operator (shown on screen as ":=") or "ctl-]" to enter the while loop operator (inclusive of placeholders for the controlling condition and one body expression). What you see in the image above is exactly what appears on the user interface and as "typed" in.

For golfing purposes, the "byte" count is the equivalent number of keyboard operations required to enter an expression.

Stuart Bruff

Posted 2013-08-01T11:22:46.980

Reputation: 501

Keyboard operations required to enter an expression please? – CalculatorFeline – 2016-04-18T17:00:22.460

Answer Part 1: Tricky. Becomes somewhat of a habit after a short time and I have to look at what I'm doing to answer this one ... ":" to enter the definition operator (:=), "]" for a programming line (black vertical bar after the :=), "ctl-#" for the while loop operator (see text), "3n" for implicit multiplication of n by 3, "shft-[" for local definition operator, "ctl-/" for in-line division operator, single-quote for balanced parentheses (context dependent). After a while, a user develops their own method of keyboard and mouse editing, which means the entry sequence can be different. – Stuart Bruff – 2016-04-18T17:53:49.393

Answer Part 2: Download Mathcad Express (http://www.ptc.com/engineering-math-software/mathcad/free-download - cutdown version of Mathcad Prime 3.1) and then Mathcad 15 (http://www.ptc.com/engineering-math-software/mathcad/free-trial). This will allow you to play with them (M15 for 30 days, at least); Mathcad Express will give you full Prime 3.1 functionality for 30 days (including programming and symbolics).

– Stuart Bruff – 2016-04-18T17:57:41.163

0

Axiom, 74 bytes

g(a)==(c:=0;repeat(a<=1=>break;c:=c+1;a rem 2=0=>(a:=a quo 2);a:=3*a+1);c)

ungolfed

gg(a)==
   c:=0
   repeat
      a<=1     =>break
      c:=c+1 
      a rem 2=0=>(a:=a quo 2)
      a:=3*a+1
   c

results

(3) -> [i,g(i)] for i in [2,16,5,7,1232456,123245677777777777777777777777777]
   Compiling function g with type PositiveInteger -> NonNegativeInteger
   (3)
   [[2,1], [16,4], [5,5], [7,16], [1232456,191],
    [123245677777777777777777777777777,572]]
                                      Type: Tuple List NonNegativeInteger

RosLuP

Posted 2013-08-01T11:22:46.980

Reputation: 3 036

0

R, 57 55 bytes

x=scan();n=0;while(x-1){x='if'(x%%2,3*x+1,x/2);n=n+1};n

Not much to say, uses a nice statement within the while loop, which should become 0 -> False only when x=1, similar to the check whether x is odd or even. This also uses the implicit conversion of 0->False and nonzero -> True.

Saved 2 bytes thanks to a trick by @Billywob used in this answer.

JAD

Posted 2013-08-01T11:22:46.980

Reputation: 2 898

Abusing a built-in (F) saves 4 bytes - the other change is just a different way of doing the if, not golfier.

– JayCe – 2018-06-14T19:35:49.437

0

C#, 71 bytes

Assuming output is required as opposed to just a return

n=>{int i=0;while(n>1){n=n%2<1?n/2:n*3+1;i++;}System.Console.Write(i);}

Alfie Goodacre

Posted 2013-08-01T11:22:46.980

Reputation: 321

0

Java (OpenJDK), 53 bytes

n->{int i=0;for(;n>1;i++)n=n%2<1?n/2:n*3+1;return i;}

Try it online!

Pavel

Posted 2013-08-01T11:22:46.980

Reputation: 8 585

0

Java 8, 53 bytes

i->{for(;i>1;)System.out.print(i=i&1>0?i=3*i+1:i/2);}

Another solution(Java 9)

i->IntStream.iterate(i,j->j&1>0?j*3+1:j/2).takeWhile(n->true);

Roman Gräf

Posted 2013-08-01T11:22:46.980

Reputation: 2 915

0

SmileBASIC, 54 bytes

INPUT N
WHILE N-1D=1AND N
C=C+1N=N*3*D+D+N/2*!D
WEND?C

12Me21

Posted 2013-08-01T11:22:46.980

Reputation: 6 110

0

TI-Basic, 47 bytes

Prompt A
0→B
While A-1
Aremainder(A+1,2_/2+(3A+1)remainder(A,2→A
B+1→B
End
B

pizzapants184

Posted 2013-08-01T11:22:46.980

Reputation: 3 174

0

S.I.L.O.S, 76 bytes

readIO
lbla
I=1-(i%2)
if I x
i=i*6+2
lblx
i/2
x+1
I=1-i
I|
if I a
printInt x

Try it online!

Somewhat naively implements the spec. It avoids a couple extra lines at the cost of performance by multiplying i by 6 and adding 2, then dividing by two when the number is odd.

Rohan Jhunjhunwala

Posted 2013-08-01T11:22:46.980

Reputation: 2 569

0

Emojicode, 139 bytes

➡️ai 0❎1a1a 2a➕1✖3aa➗a 2i➕1ii

Try it online!

betseg

Posted 2013-08-01T11:22:46.980

Reputation: 8 493

0

Clean, 82 bytes

import StdEnv
?n=snd(until(\(e,_)=e<2)(\(e,i)=(if(isOdd e)(3*e+1)(e/2),i+1))(n,0))

Try it online!

Οurous

Posted 2013-08-01T11:22:46.980

Reputation: 7 916

0

Stax, 12 bytesCP437

ÄFl,rBoU¡£&╦

14 bytes when unpacked,

1{h_3*^\_@gt%v

Run and debug online!

Adaptation of https://github.com/tomtheisen/stax/blob/master/testspecs/golf/CollatzTest.staxtest .

Weijun Zhou

Posted 2013-08-01T11:22:46.980

Reputation: 3 396

0

SNOBOL4 (CSNOBOL4), 96 bytes

	N =INPUT
T	X =X + 1
	N =GT(REMDR(N,2)) 3 * N + 1	:S(O)
	N =N / 2
O	OUTPUT =EQ(N,1) X	:F(T)
END	

Try it online!

Giuseppe

Posted 2013-08-01T11:22:46.980

Reputation: 21 077

0

Add++, 50 bytes

D,f,@,dd2/i@3*1+$2%D
+?
-1
W,+1,$f>x,},+1,},-1
}
O

Try it online!

-5 bytes thanks to rubber duck golfing!

How it works

D,f,@,		; Define a function 'f' that takes one argument
		; Example argument:	[10]
	dd	; Triplicate;	STACK = [10 10 10]
	2/i	; Halve;	STACK = [10 10 5]
	@	; Reverse;	STACK = [5 10 10]
	3*1+	; (n*3)+1;	STACK = [5 10 31]
	$	; Swap;		STACK = [5 31 10]
	2%	; Parity;	STACK = [5 31 0]
	D	; Select;	STACK = [5]

+?		; Take input; 	x = 10;	y = 0;
-1		; Decrement;	x = 9;	y = 0;

W,		; While x != 0:
	+1,	;  Increment;	x = 10;	y = 0;
	$f>x,	;  Call 'f';	x = 5;	y = 0;
	},+1,	;  Increment y;	x = 5;	y = 1;
	},-1	;  Decrement x;	x = 4;	y = 1;

}		; Swap to y;	x = 0;	y = 6;
O		; Output y;

caird coinheringaahing

Posted 2013-08-01T11:22:46.980

Reputation: 13 702

0

dc, 30 28 bytes

?[d5*2+d2%*+2/d1<f1+]dsfx1-p

This uses the formula from Jo King's answer, slightly adapted so we dup after adding 2.

Explanation

?                             # read input
 [            d1<f  ]dsfx     # repeat until we reach 1 
  d5*2+d2%*+2/                # n → (n + (5n+2)%2 * (5n+2)) / 2
                  1+          # count iterations
                         1-p  # decrement and print result

Previous answer: 30 bytes

?[6*4+]sm[d2~1=md1!=f]dsfxz1-p

We keep all the intermediate results on the stack, then count the size of the stack. We save bytes by always doing the division by two, but if the remainder is 1, then we multiply by 6 and add 4 (3 for the remainders and 1 for the Collatz constant). The final stack count contains all the numbers we've seen; the number of operations is one less than that.

Explanation

?                               # input

[6*4+]sm                        # helper function

[d2~1=md1!=f]dsfx               # recursion

z1-p                            # print result

Toby Speight

Posted 2013-08-01T11:22:46.980

Reputation: 5 058

0

Julia 0.6, 43 bytes

c(n,l=0)=n<2?l:n%2>0?c(3n+1,l+1):c(n/2,l+1)

Try it online!

sundar - Reinstate Monica

Posted 2013-08-01T11:22:46.980

Reputation: 5 296

0

Ahead, 38 bytes

Il&+1t~j+1*3\~/2<~<
>:1)k~tO@~:k\:  nl

Try it online!

snail_

Posted 2013-08-01T11:22:46.980

Reputation: 1 982

0

Python 2, 48 bytes

f=lambda n,s=0:s*(n<2)or f((n/2,3*n+1)[n%2],s+1)

Try it online!

Aaah, recursion.

# s*0 or s*1.
s*(n<2)

# while n>1, this will evaluate to 0 or f(n,s+1).
# Since positive integers are Truthy, this will return f().
# when n<2, this will return s without evaluating f().
s*(n<2)or f(...)

Triggernometry

Posted 2013-08-01T11:22:46.980

Reputation: 765

0

Pushy, 24 bytes

Zvt$h2C3*h}2/}2%zFhFt;F#

Try it online!

FlipTack

Posted 2013-08-01T11:22:46.980

Reputation: 13 242

0

JavaScript, 35 bytes

f=(n,c)=>n<2?c:f(n%2?n*3+1:n/2,-~c)

Try it online!

Oliver

Posted 2013-08-01T11:22:46.980

Reputation: 7 160

0

Ruby, 77 72 bytes

b=0;a=gets.to_i;loop{if a==1;p b;exit;end;a.odd?? (a*=3;a+=1):a/=2;b+=1}

Definitely not the shortest, but not the most unreadable or hard to follow either. Try it online!

a.odd?? (a*=3;a+=1): uses the ternary operator, which is a short form of if/then/else. It looks like boolean ? instruction : instruction, with the first instruction being if the boolean is true, and the second being if it isn't. Therefore trailing question mark and colon.

*= and /= are the multiplication and division versions of += in Ruby.

Ungolfed version:

counter = 0
input = gets.to_i
loop do
  if input = 1
    print counter
    exit
  end
  if input.odd?
    input *= 3
    input += 1
  else
    input /= 2
  end
  counter += 1
end

CG One Handed

Posted 2013-08-01T11:22:46.980

Reputation: 133

0

Here is the one line code in python (a long one though)

num = int(input()); while num > 0 : print(num); num = int(num / 2) if num % 2 == 0 else 3 * num + 1 if num > 1 else 0

KARTHIK O

Posted 2013-08-01T11:22:46.980

Reputation: 1

1Wecome to the site! Answers are scored in number of characters rather than number of lines. This leaves you a few ways of optimization. You can use a shorter variable name, you can remove unnecessary spaces. – Post Rock Garf Hunter – 2019-12-12T14:08:01.300

0

Wren, 68 bytes

Fn.new{|n|
var c=0
while(n>1){
n=n%2==0?n/2:n*3+1
c=c+1
}
return c
}

Try it online!

Explanation

Fn.new{|n| // New anonymous function with param n
var c=0    // Declare a variable c as 0
while(n>1){ // While n is larger than 1:
n=n%2==0?          // If n is divisible by 2:
         n/2:      // Halve n
             n*3+1 // Otherwise, triple n & increment.
c=c+1              // Increment the counter
}                  // This is here due to Wrens bad brace-handling system
return c           // Return the value of the counter
}

user85052

Posted 2013-08-01T11:22:46.980

Reputation:

0

Haskell, 43 Bytes

c 1=0
c x|odd x=1+c(3*x+1)|1<2=1+c(x`div`2)

Usage: c 7-> 16

nimi

Posted 2013-08-01T11:22:46.980

Reputation: 34 639

What's "Haskell 2"? – nyuszika7h – 2016-12-06T23:14:02.267

2@nyuszika7h: a typo – nimi – 2016-12-06T23:14:49.867