The inverse Collatz Conjecture

13

3

I think the Collatz Conjecture is already well-known. But what if we invert the rules?

Start with an integer n >= 1.

Repeat the following steps:

If n is even, multiply it by 3 and add 1.

If n is odd, subtract 1 and divide it by 2.

Stop when it reaches 0

Print the iterated numbers.

Test cases:

 1        => 1, 0
 2        => 2, 7, 3, 1, 0
 3        => 3, 1, 0
10        => 10, 31, 15, 7, 3...
14        => 14, 43, 21, 10, ...

Rules:

  • This sequence does not work for a lot of numbers because it enters in an infinite loop. You do not need to handle those cases. Only printing the test cases above is enough.

  • I suggested to subtract 1 and divide by two to give a valid integer to continue, but it is not required to be computed that way. You may divide by 2 and cast to integer or whatever other methods that will give the expected output.

  • You need to print the initial input as well.

  • The output does not need to be formatted as the test cases. It was just a suggestion. However, the iterated order must be respected.

  • The smallest code wins.

Eduardo Hoefel

Posted 2018-11-04T20:24:07.870

Reputation: 587

9

As this is your third question in as many hours, I'd recommend that you check out the Sandbox, the place where we usually post question drafts for feedback, and to make sure they aren't duplicates.

– caird coinheringaahing – 2018-11-04T20:38:15.710

Thank you @cairdcoinheringaahing. I didn't know about this page. – Eduardo Hoefel – 2018-11-04T21:38:57.870

Do we have to print the 0 at the end? – flawr – 2018-11-04T23:01:19.637

2You might want to expand the last two test cases, since they're not that long – Jo King – 2018-11-04T23:07:41.840

3@JoKing I compressed it because it repeats the output from the other lines. At the point you reach 3, it has the same output of when you start from it. The same applies for 10 or any other number. – Eduardo Hoefel – 2018-11-05T02:40:54.043

@flawr it's optional. – Eduardo Hoefel – 2018-11-05T02:41:27.663

Does it have to be in the same format as in the test cases? – MilkyWay90 – 2018-12-02T05:24:09.910

@MilkyWay90: not same format, but they must be in decimal format, keep the ordering and have some kind of separator character that distinguishes the values. – Eduardo Hoefel – 2018-12-02T20:03:24.167

Answers

5

Perl 6, 30 bytes

{$_,{$_%2??$_+>1!!$_*3+1}...0}

Try it online!

Anonymous code block that returns a sequence.

Explanation:

{$_,{$_%2??$_+>1!!$_*3+1}...0}
{                            }   # Anonymous code block
   ,                     ...     # Define a sequence
 $_                              # That starts with the given value
    {                   }        # With each element being
     $_%2??     !!               # Is the previous element odd?
           $_+>1                 # Return the previous element bitshifted right by 1
                  $_*3+1         # Else the previous element multiplied by 3 plus 1
                            0    # Until the element is 0

Jo King

Posted 2018-11-04T20:24:07.870

Reputation: 38 234

5

Haskell, 40 39 bytes

f 0=[]
f n=n:f(cycle[3*n+1,div n 2]!!n)

Try it online!

Now without the final 0.

Lynn

Posted 2018-11-04T20:24:07.870

Reputation: 55 648

4

Clean, 53 bytes

import StdEnv
$0=[0]
$n=[n: $if(isOdd n)(n/2)(n*3+1)]

Try it online!

Οurous

Posted 2018-11-04T20:24:07.870

Reputation: 7 916

2

Jelly, 9 bytes

:++‘ƊḂ?Ƭ2

Try it online!

Erik the Outgolfer

Posted 2018-11-04T20:24:07.870

Reputation: 38 134

2

Rust, 65 64 bytes

|mut n|{while n>0{print!("{} ",n);n=if n&1>0{n>>1}else{n*3+1};}}

Try it online!

Herman L

Posted 2018-11-04T20:24:07.870

Reputation: 3 611

2

JAEL, 18 bytes

![ؼw>î?èÛ|õÀ

Try it online!

Eduardo Hoefel

Posted 2018-11-04T20:24:07.870

Reputation: 587

1Your permalink doesn't seem to be working. The program just prints the input and halts. – Dennis – 2018-11-09T03:30:44.230

Yes, you're right. I'll ask "them" to pull the latest version :P – Eduardo Hoefel – 2018-11-09T15:37:48.397

I've added JAEL to the list of golfing languages. Please let me know if I got any information wrong :-)

– ETHproductions – 2018-11-09T19:39:05.407

@ETHproductions Thank you very much :D I think I could say that the specialty is the utility package that helps the programmer to compress the code, but that's just me trying to merchandise it. – Eduardo Hoefel – 2018-11-12T00:36:44.017

2

Python 2, 54 52 44 bytes

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

-2 bytes thanks to Mr. Xcoder

There must certainly be a faster way. Oddly, when I tried a lambda it was the same bytecount. I'm probably hallucinating.

Try it online!

Quintec

Posted 2018-11-04T20:24:07.870

Reputation: 2 801

-2 bytes – Mr. Xcoder – 2018-11-04T21:48:36.643

@Mr.Xcoder Ah, thanks. – Quintec – 2018-11-04T21:50:21.183

150 bytes – Jo King – 2018-11-04T23:25:53.310

Though the 0 is now optional, so it's shorter to get rid of the second print – Jo King – 2018-11-05T02:43:33.457

Indeed, now you can do it in 44

– Mr. Xcoder – 2018-11-05T11:16:48.620

@Mr.Xcoder Cool, I was asleep lol – Quintec – 2018-11-05T13:28:18.097

2

Haskell, 76 69 61 56 bytes

I feel like this is way too long. Here l produces an infinite list of the inverse-collatz sequence, and the anonymous function at the first line just cuts it off at the right place.

Thanks for -5 bytes @ØrjanJohansen!

fst.span(>0).l
l r=r:[last$3*k+1:[div k 2|odd k]|k<-l r]

Try it online!

flawr

Posted 2018-11-04T20:24:07.870

Reputation: 40 560

There are no negative numbers, so (>0) should suffice. Also there's an odd function. – Ørjan Johansen – 2018-11-05T18:25:36.837

@ØrjanJohansen Thanks a lot! – flawr – 2018-11-05T20:32:50.220

2

05AB1E, 15 14 bytes

[Ð=_#Èi3*>ë<2÷

-1 byte thanks to @MagicOctopusUrn.

Try it online.

Explanation:

[             # Start an infinite loop
 Ð            #  Duplicate the top value on the stack three times
              #  (Which will be the (implicit) input in the first iteration)
  =           #  Output it with trailing newline (without popping the value)
   _#         #  If it's exactly 0: stop the infinite loop
     Èi       #  If it's even:
       3*     #   Multiply by 3
         >    #   And add 1
      ë       #  Else:
       <      #   Subtract 1
        2÷    #   And integer-divide by 2

Kevin Cruijssen

Posted 2018-11-04T20:24:07.870

Reputation: 67 575

[Ð=_#Èi3*>ë<2÷ with = instead of D,. – Magic Octopus Urn – 2018-11-07T04:20:00.773

@MagicOctopusUrn Ah, that was pretty bad to forgot.. Thanks! :) – Kevin Cruijssen – 2018-11-07T07:37:19.527

1

JavaScript (ES6), 31 bytes

f=n=>n&&n+' '+f(n&1?n>>1:n*3+1)

Try it online!

Or 30 bytes in reverse order.

Arnauld

Posted 2018-11-04T20:24:07.870

Reputation: 111 334

1

Pyth, 12 bytes

.u?%N2/N2h*3

Try it here as a test suite!

Mr. Xcoder

Posted 2018-11-04T20:24:07.870

Reputation: 39 774

1

Wolfram Language (Mathematica), 35 bytes

0<Echo@#&&#0[3#+1-(5#+3)/2#~Mod~2]&

Try it online!

0<Echo@# && ...& is short-circuit evaluation: it prints the input #, checks if it's positive, and if so, evaluates .... In this case, ... is #0[3#+1-(5#+3)/2#~Mod~2]; since #0 (the zeroth slot) is the function itself, this is a recursive call on 3#+1-(5#+3)/2#~Mod~2, which simplifies to 3#+1 when # is even, and (#-1)/2 when # is odd.

Misha Lavrov

Posted 2018-11-04T20:24:07.870

Reputation: 4 846

1

Common Lisp, 79 bytes

(defun x(n)(cons n(if(= n 0)nil(if(=(mod n 2)0)(x(+(* n 3)1))(x(/(- n 1)2))))))

Try it online!

JRowan

Posted 2018-11-04T20:24:07.870

Reputation: 231

1

PowerShell, 53 52 bytes

param($i)for(;$i){$i;$i=(($i*3+1),($i-shr1))[$i%2]}0

Try it Online!

Edit:
-1 byte thanks to @mazzy

J. Bergmann

Posted 2018-11-04T20:24:07.870

Reputation: 221

you can try for(;$i) instead while($i) – mazzy – 2018-11-05T12:19:41.010

1

Emojicode 0.5, 141 bytes

aa 10▶️a 0a 2 1a➗a 2a➕✖️a 3 1a 10

Try it online!


a       input integer variable 'a'
a 10       print input int
▶️a 0       loop while number isn’t 0
a 2 1      if number is odd
a➗a 2        divide number by 2

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

a 10      print iteration

X1M4L

Posted 2018-11-04T20:24:07.870

Reputation: 1 586

1

Stax, 11 bytes

₧↑╔¶┘tÇ╣;↑è

Run and debug it

wastl

Posted 2018-11-04T20:24:07.870

Reputation: 3 089

1

x86 machine code, 39 bytes

00000000: 9150 6800 0000 00e8 fcff ffff 5958 a901  .Ph.........YX..
00000010: 0000 0074 04d1 e8eb 066a 035a f7e2 4009  ...t.....j.Z..@.
00000020: c075 dec3 2564 20                        .u..%d 

Assembly (NASM syntax):

section .text
	global func
	extern printf
func:					;the function uses fastcall conventions
	xchg eax, ecx			;load function arg into eax
	loop:
		push eax
		push fmt
		call printf	;print eax
		pop ecx
		pop eax
		test eax, 1	;if even zf=1
		jz even		;if eax is even jmp to even
		odd:		;eax=eax/2
			shr eax, 1
			jmp skip
		even:		;eax=eax*3+1
			push 3
			pop edx
			mul edx
			inc eax
		skip:
		or eax, eax
		jne loop	;if eax!=0, keep looping
	ret			;return eax
section .data
	fmt db '%d '

Try it online!

Logern

Posted 2018-11-04T20:24:07.870

Reputation: 845

1

MathGolf, 12 bytes

{o_¥¿½É3*)}∟

Try it online!

Explanation

{             Start block of arbitrary length
 o            Output the number
  _           Duplicate
   ¥          Modulo 2
    ¿         If-else with the next two blocks. Implicit blocks consist of 1 operator
     ½        Halve the number to integer (effectively subtracting 1 before)
      É       Start block of 3 bytes
       3*)    Multiply by 3 and add 1
          }∟  End block and make it do-while-true

maxb

Posted 2018-11-04T20:24:07.870

Reputation: 5 754

I've added MathGolf to the list of golfing langs--feel free to correct me if I got anything wrong :-)

– ETHproductions – 2018-11-12T20:28:36.333

Thanks for adding it! Everything looks right to me. – maxb – 2018-11-12T22:31:27.523

1

R, 66 61 bytes

-5 bytes thanks to Robert S. in consolidating ifelse into if and removing brackets, and x!=0 to x>0

print(x<-scan());while(x>0)print(x<-`if`(x%%2,(x-1)/2,x*3+1))

instead of

print(x<-scan());while(x!=0){print(x<-ifelse(x%%2,(x-1)/2,x*3+1))}

Try it online!

Sumner18

Posted 2018-11-04T20:24:07.870

Reputation: 1 334

161 bytes – Robert S. – 2018-12-14T16:05:10.630

0

Add++, 38 35 33 bytes

D,f,@:,d3*1+$2/iA2%D
+?
O
Wx,$f>x

Try it online!

How it works

First, we begin by defining a function \$f(x)\$, that takes a single argument, performs the inverted Collatz operation on \$x\$ then outputs the result. That is,

$$f(x) = \begin{cases} x \: \text{is even}, & 3x+1 \\ x \: \text{is odd}, & \lfloor\frac{x}{2}\rfloor \end{cases}$$

When in function mode, Add++ uses a stack memory model, otherwise variables are used. When calculating \$f(x)\$, the stack initially looks like \$S = [x]\$.

We then duplicate this value (d), to yield \$S = [x, x]\$. We then yield the first possible option, \$3x + 1\$ (3*1+), swap the top two values, then calculate \$\lfloor\frac{x}{2}\rfloor\$, leaving \$S = [3x+1, \lfloor\frac{x}{2}\rfloor]\$.

Next, we push \$x\$ to \$S\$, and calculate the bit of \$x\$ i.e. \$x \: \% \: 2\$, where \$a \: \% \: b\$ denotes the remainder when dividing \$a\$ by \$b\$. This leaves us with \$S = [3x+1, \lfloor\frac{x}{2}\rfloor, (x \: \% \: 2)]\$. Finally, we use D to select the element at the index specified by \$(x \: \% \: 2)\$. If that's \$0\$, we return the first element i.e. \$3x+1\$, otherwise we return the second element, \$\lfloor\frac{x}{2}\rfloor\$.

That completes the definition of \$f(x)\$, however, we haven't yet put it into practice. The next three lines have switched from function mode into vanilla mode, where we operate on variables. To be more precise, in this program, we only operate on one variable, the active variable, represented by the letter x. However, x can be omitted from commands where it is obviously the other argument.

For example, +? is identical to x+?, and assigns the input to x, but as x is the active variable, it can be omitted. Next, we output x, then entire the while loop, which loops for as long as \$x \neq 0\$. The loop is very simple, consisting of a single statement: $f>x. All this does is run \$f(x)\$, then assign that to x, updating x on each iteration of the loop.

caird coinheringaahing

Posted 2018-11-04T20:24:07.870

Reputation: 13 702

Just to understand: Is the break line part of the code? Or is it just for better explanation? I don't really know this language. – Eduardo Hoefel – 2018-11-04T21:38:04.357

@EduardoHoefel Break line? – caird coinheringaahing – 2018-11-04T21:38:47.797

@cairdcoinheringaahing The newline characters, presumably. – Lynn – 2018-11-04T22:13:34.207

0

perl -Minteger -nlE, 39 bytes

{say;$_=$_%2?$_/2:3*$_+1 and redo}say 0

user73921

Posted 2018-11-04T20:24:07.870

Reputation:

0

Retina 0.8.2, 46 bytes

.+
$*
{*M`1
^(..)+$
$&$&$&$&$&$&111
1(.*)\1
$1

Try it online! Explanation:

.+
$*

Convert to unary.

{

Repeat until the value stops changing.

*M`1

Print the value in decimal.

^(..)+$
$&$&$&$&$&$&111

If it is even, multiply by 6 and add 3.

1(.*)\1
$1

Subtract 1 and divide by 2.

The trailing newline can be suppressed by adding a ; before the {.

Neil

Posted 2018-11-04T20:24:07.870

Reputation: 95 035

0

Red, 70 bytes

func[n][print n if n = 0[exit]either odd? n[f n - 1 / 2][f n * 3 + 1]]

Try it online!

Galen Ivanov

Posted 2018-11-04T20:24:07.870

Reputation: 13 815

0

Racket, 75 bytes

(define(f n)(cons n(if(= n 0)'()(if(odd? n)(f(/(- n 1)2))(f(+(* 3 n)1))))))

Try it online!

Equivalent to JRowan's Common Lisp solution.

Galen Ivanov

Posted 2018-11-04T20:24:07.870

Reputation: 13 815

0

C# (.NET Core), 62 bytes

a=>{for(;a>0;a=a%2<1?a*3+1:a/2)Console.Write(a+" ");return a;}

Try it online!

Ungolfed:

a => {
    for(; a > 0;                // until a equals 0
        a = a % 2 < 1 ?             // set a depending on if a is odd or even
                a * 3 + 1 :             // even
                a / 2                   // odd (minus one unnecessary because of int casting)
    )
        Console.Write(a + " "); // writes the current a to the console
    return a;                   // writes a to the console (always 0)
}

Meerkat

Posted 2018-11-04T20:24:07.870

Reputation: 371

0

Dart, 49 bytes

f(n){for(;n>0;n=n%2>0?(n-1)>>1:(n*3)+1)print(n);}

Try it online!

Elcan

Posted 2018-11-04T20:24:07.870

Reputation: 913

0

Gambit Scheme (gsi), 74 bytes

(define(f n)(if(= 0 n)'()(cons n(f(if(even? n)(+ (* 3 n)1)(/(- n 1)2))))))

Try it online!

Comrade SparklePony

Posted 2018-11-04T20:24:07.870

Reputation: 5 784