The Collatz Conjecture terbalik

13

Saya pikir dugaan Collatz sudah terkenal. Tetapi bagaimana jika kita membalikkan aturan?

Mulai dengan bilangan bulat n> = 1.

Ulangi langkah-langkah berikut:

Jika n adalah genap , kalikan dengan 3 dan tambahkan 1.

Jika n ganjil , kurangi 1 dan bagi dengan 2.

Berhenti ketika mencapai 0

Cetak nomor yang diulang.

Kasus uji:

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

Aturan:

  • Urutan ini tidak berfungsi untuk banyak angka karena masuk dalam loop tak terbatas. Anda tidak perlu menangani kasus-kasus itu. Hanya mencetak test case di atas sudah cukup.

  • Saya menyarankan untuk mengurangi 1 dan membaginya dengan dua untuk memberikan integer yang valid untuk melanjutkan, tetapi tidak harus dihitung seperti itu. Anda dapat membaginya dengan 2 dan dilemparkan ke integer atau apa pun metode lain yang akan memberikan hasil yang diharapkan.

  • Anda perlu mencetak input awal juga.

  • Output tidak perlu diformat sebagai kasus uji. Itu hanya saran. Namun, perintah yang diulang harus dihormati.

  • Kode terkecil menang.

Eduardo Hoefel
sumber
9
Karena ini adalah pertanyaan ketiga Anda dalam beberapa jam, saya sarankan Anda memeriksa Sandbox , tempat di mana kami biasanya mengirimkan draft pertanyaan untuk umpan balik, dan untuk memastikan mereka bukan duplikat.
caird coinheringaahing
Terima kasih @cairdcoinheringaahing. Saya tidak tahu tentang halaman ini.
Eduardo Hoefel
Apakah kita harus mencetak 0di bagian akhir?
flawr
2
Anda mungkin ingin memperluas dua kasus uji terakhir, karena tidak terlalu lama
Jo King
3
@ JoKing saya mengompresnya karena mengulangi output dari baris lain. Pada titik Anda mencapai 3 , ia memiliki output yang sama ketika Anda mulai dari itu. Hal yang sama berlaku untuk 10 atau nomor lainnya.
Eduardo Hoefel

Jawaban:

5

Perl 6 , 30 byte

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

Cobalah online!

Blok kode anonim yang mengembalikan urutan.

Penjelasan:

{$_,{$_%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
sumber
5

Haskell , 40 39 byte

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

Cobalah online!

Sekarang tanpa 0 akhir.

Lynn
sumber
2

Python 2, 54 52 44 byte

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

-2 byte terima kasih kepada Tn. Xcoder

Pasti ada cara yang lebih cepat. Anehnya, ketika saya mencoba lambda itu adalah bytecount yang sama. Saya mungkin berhalusinasi.

Cobalah online!

Quintec
sumber
-2 byte
Tn. Xcoder
@ Mr.Xcoder Ah, terima kasih.
Quintec
1
50 byte
Jo King
Meskipun 0sekarang opsional, jadi lebih pendek untuk menyingkirkan yang keduaprint
Jo King
Memang, sekarang Anda bisa melakukannya di 44
Mr. Xcoder
2

Haskell , 76 69 61 56 byte

Saya merasa ini terlalu lama. Di sini lmenghasilkan daftar tak terbatas dari urutan inverse-collatz, dan fungsi anonim di baris pertama hanya memotongnya di tempat yang tepat.

Terima kasih untuk -5 byte @ ØrjanJohansen!

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

Cobalah online!

cacat
sumber
Tidak ada angka negatif, jadi (>0)cukuplah. Juga ada oddfungsi.
Ørjan Johansen
@ ØrjanJohansen Terima kasih banyak!
flawr
2

05AB1E , 15 14 byte

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

-1 byte terima kasih @MagicOctopusUrn .

Cobalah online.

Penjelasan:

[             # 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
sumber
[Ð=_#Èi3*>ë<2÷dengan =bukannya D,.
Magic Octopus Mm
@ MagicOctopusUrn Ah, itu sangat buruk untuk dilupakan .. Terima kasih! :)
Kevin Cruijssen
2

JAEL , 18 byte

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

Cobalah online!

Eduardo Hoefel
sumber
1
Permalink Anda sepertinya tidak berfungsi. Program hanya mencetak input dan berhenti.
Dennis
Ya kau benar. Saya akan meminta "mereka" untuk menarik versi terbaru: P
Eduardo Hoefel
I've added JAEL to the list of golfing languages. Please let me know if I got any information wrong :-)
ETHproductions
@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
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
sumber
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
sumber
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
sumber
you can try for(;$i) instead while($i)
mazzy
1

Emojicode 0.5, 141 bytes

🐖🎅🏿🍇🍮a🐕😀🔡a 10🔁▶️a 0🍇🍊😛🚮a 2 1🍇🍮a➗a 2🍉🍓🍇🍮a➕✖️a 3 1🍉😀🔡a 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
sumber
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
sumber
I've added MathGolf to the list of golfing langs--feel free to correct me if I got anything wrong :-)
ETHproductions
Thanks for adding it! Everything looks right to me.
maxb
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
sumber
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
sumber
1
61 bytes
Robert S.
0

perl -Minteger -nlE, 39 bytes

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

sumber
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)={xis even,3x+1xis odd,x2

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 x2, leaving S=[3x+1,x2].

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,x2,(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, x2.

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 x0. 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
sumber
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
@EduardoHoefel Break line?
caird coinheringaahing
@cairdcoinheringaahing The newline characters, presumably.
Lynn
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
sumber
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
sumber
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
sumber
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
sumber