Collatz-Vermutung (OEIS A006577)


66

Dies ist die Collatz-Vermutung (OEIS A006577 ):

  • Beginnen Sie mit einer ganzen Zahl n > 1.
  • Wiederholen Sie die folgenden Schritte:
    • Wenn n gerade ist, dividiere es durch 2.
    • Wenn n ungerade ist, multiplizieren Sie es mit 3 und addieren Sie 1.

Es ist erwiesen , dass für alle positiven ganzen Zahlen bis zu 5 * 2 60 , oder etwa 5764000000000000000 , n schließlich werden wird 1 .

Sie müssen herausfinden, wie viele Iterationen (Halbierung oder Verdreifachung plus Eins) erforderlich sind, um 1 zu erreichen .

Relevante xkcd :)

Regeln:

  • Kürzester Code gewinnt.
  • Wenn eine Zahl <2 eingegeben wird oder eine Nicht-Ganzzahl oder eine Nicht-Zahl, spielt die Ausgabe keine Rolle.

Testfälle

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

Antworten:



15

C - 50 47 Zeichen

Schlechtes kleines C erfordert leider eine schreckliche Menge an Code für grundlegende E / A, so dass das Kurzschließen all dessen die Benutzeroberfläche etwas unintuitiv gemacht hat.

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

Kompiliere es zum Beispiel mit gcc -o 1 collatz.c. Die Eingabe ist unär mit durch Leerzeichen getrennten Ziffern, und Sie finden die Antwort im Exit-Code. Ein Beispiel mit der Nummer 17:

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

1
return~-a?speichert 1. Auch das Verschieben b++in den ?Fall sollte speichern b--.
Ugoren

Hehe Sie die Regeln so sehr verbiegen : P +1 für Kreativität und mit einer Sprache, die normalerweise nicht zum Golfen verwendet wird
Türklinke

Vielen Dank, dass Sie ugoren! Ich muss betrunken gewesen sein, als ich es geschrieben habe. :)
Fors

12

Perl 34 (+1) Zeichen

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

Wie üblich $\für die endgültige Ausgabe missbrauchen . Mit der -pBefehlszeilenoption ausführen, die Eingabe wird von übernommen stdin.

1 Byte aufgrund von Elias Van Ootegem gespeichert . Insbesondere die Beobachtung, dass die folgenden beiden gleichwertig sind:

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

Obwohl ein Byte länger, werden zwei Byte eingespart, indem $_/2auf "nur" gekürzt wird .5.

Beispielnutzung:

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

Javascripts Archnemesis für den Wooden Spoon Award scheint in dieser Herausforderung ein bisschen zu kurz gekommen zu sein. Es gibt jedoch nicht viel Raum für Kreativität bei diesem Problem. Die Eingabe wird als Befehlszeilenargument verwendet.

Beispielnutzung:

$ php collatz.php 176
18

1
Ich habe eine Weile gebraucht, um herauszufinden, was die unvergleichlichen Klammern tun :)
Marinus

1
Die Wiederholung $_im ternären verschwenderisch scheint, können Sie einen anderen Charakter , indem Sie abrasieren *=wie folgt aus : $\++,$_*=$_&1?3+1/$_:.5while$_>1}{. Das Multiplizieren mit 1/$_hat den gleichen Effekt wie +1, $_*=3+1/$_funktioniert also
prima

@EliasVanOotegem $_*=3+1/$_ist brillant, danke!
Primo

11

Mathematica (35)

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

Verwendungszweck:

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

Es ist keine gültige Funktion, 10.3 beschwert sich über einen Schurken @ am Ende
CalculatorFeline

@ ruft das Argument auf, ich weiß nicht, warum es dort war, nur eine kurze Bearbeitung
Meilen


10

Wie üblich beginne ich die Antworten mit meinen eigenen.

JavaScript, 46 44 Zeichen (auf Konsole ausgeführt)

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

Was ist der Sinn von ~~ prompt (), wenn Sie sagten, dass die Ausgabe keine Rolle spielt, wenn es sich um eine Nicht-Ganzzahl handelt? Sie können zwei Zeichen speichern, indem Sie ~~ entfernen.
Resorath

@Resorath Ah, ich habe das automatische Casting von JS vergessen: P danke
Türklinke

9

Java, 165, 156, 154, 134, 131, 129, 128 , 126 (auch ausführliche Sprachen brauchen etwas Liebe)

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

Alles ist in der für getan

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

Das ist verdammt schöner Mann. Vielen Dank an Pater Taylor !!! und die Idee, eine for-Schleife zu verwenden, wurde ugoren gestohlen

Ich habe Integer für Short ersetzt.


1
Sie können die Länge von ganz einfach speichern i(,++y). Sie können zwei weitere speichern, indem Sie <anstelle von verwenden ==.
Peter Taylor

@ Peter Taylor Sie haben Recht, meine Vergleiche werden kürzer mit <sein, aber ich verstehe den Teil des Pre-Inkrements nicht
jsedano

2
Die beiden Seiten Ihres zweiten Ternärs sind strukturell identisch, sodass Sie den Ternär in das erste Argument des rekursiven Aufrufs verschieben können.
Peter Taylor

1
Oh mein Gott, das ist brillant
jsedano

2
Ich weiß, dass es ungefähr 3,5 Jahre her ist, aber Sie können es immer noch mit 5 Bytes Golf spielen : Durchgeführte 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;}}Änderungen: 1) Ersetzt Short.valueOf(...)durch new Short(...)für -4 Bytes und 2) Ich habe das x=x%2<1?x/2:x*3+1;in den Körper der forSchleife gesteckt, um das loszuwerden Komma für -1 Byte .
Kevin Cruijssen

9

Rebmu : 28

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

Bei einem so knappen und mathematischen Problem wird GolfScript wahrscheinlich um einige Prozent gegen Rebmu gewinnen (wenn es nicht erforderlich ist, Dateien aus dem Internet zu lesen oder JPG-Dateien zu generieren). Ich denke jedoch, die meisten würden zustimmen, dass die Logik des Golfscript bei weitem nicht so einfach zu befolgen ist und dass der gesamte ausführbare Stapel, auf dem es ausgeführt wird, größer ist.

Obwohl Rebols eigener Schöpfer Carl Sassenrath mir erzählte, dass er Rebmu "unleserlich" fand, ist er beschäftigt und hat keine Zeit, die schweinelateinähnliche Transformation durch Unmushing wirklich zu üben . Dies ist wirklich nur umgewandelt in:

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

Beachten Sie, dass das Leerzeichen erforderlich war, um ein a: anstelle eines a zu erhalten . Dies ist ein "Setzwort"! und der Bewerter bemerkt diesen Symboltyp, um die Zuordnung auszulösen.

Wenn es in ungekürztem (aber unbeholfen geschriebenem) Rebol geschrieben wäre, bekäme man:

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

Rebol wertet Blöcke wie Ruby auf ihren letzten Wert aus. Die UNTIL-Schleife ist eine kuriose Form der Schleife, die keine Schleifenbedingung annimmt. Sie stoppt nur die Schleife, wenn ihr Block etwas ergibt, das nicht FALSE oder NONE ist. An dem Punkt, an dem 1 ==das Ergebnis der Zuweisung von A (das Argument für rebmu) zu dem Ergebnis der Collatz-Bedingung (entweder ist es ein IF-ELSE, das den von ihm gewählten Zweig ergibt), wird die Schleife unterbrochen.

J und K werden in Rebmu auf den ganzzahligen Wert Null initialisiert. Und wie bereits erwähnt, wird das Ganze bis zum letzten Wert bewertet. Eine J-Referenz am Ende des Programms bedeutet also, dass Sie die Anzahl der Iterationen erhalten.

Verwendungszweck:

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

8

Python Repl, 48

Ich bin nicht überzeugt, dass es keinen kürzeren Ausdruck gibt als n=3*n+1;n/=1+n%2*5;. Ich habe wahrscheinlich ein Dutzend verschiedene Ausdrücke mit der gleichen Länge gefunden ...

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

edit: ich habe eine andere lösung gefunden, die sich nie streiten wird, aber zu spaßig ist, nicht zu teilen.

s='s'
i=s
n=i*input()
while 1:
 while n==n[::2]+n[::2]:i+=s;n=n[::2]
 if n==s:i.rindex(s);break
 n=3*n+s
 i+=s

1
Mein Gehirn tut jetzt weh.
Daniero

1
@daniero die zweite lösung ist nur für dich.
Stand

Oh wow. Ich fühle mich geehrt!
Daniero

4
(n//2,n*3+1)[n%2]ist kürzer.
Evpok

1
@Evpok würde nicht n/2so gut funktionieren, wie wir es selbst wissen?
george

7

APL (31)

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

alte Antwort, noch 27:{1=⍵:0⋄2|⍵:1+∇1+3×⍵⋄1+∇⍵÷2}
Uriel

1
{1=⍵:0⋄1+∇⊃⍵⌽0 1+.5 3×⍵}
ngn

7

J, 30 Zeichen

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

Es stellte sich heraus, ziemlich viel länger als gewünscht

Verwendungszweck:

   <:#-:`(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&*)`]ist ein Gerundium, das aus drei Verben besteht und dreimal verwendet wird. -:bedeutet "halbieren" (1+3&*)oder (1+3*])codiert den Multiplikationsschritt und ](Identität) unterstützt die Beendigung.

  • 2&|+1&=bildet einen Index zum Gerundium. wörtlich "der Rest nach Division durch zwei plus ob er gleich eins ist".

  • #verb^:a:iteriert die Funktion, bis das Ergebnis stabil ist (hier explizit erzwungen), sammelt die Schritte und zählt sie dann. Von @JB gestohlen . <:Verringert die Schrittzahl um eins, um die Anforderungen der Frage zu erfüllen.


6
Immer wenn ich eine J-Einsendung sehe, zähle ich die Smilies. Dies tut man ziemlich gut: <:, #-:, :`(, &*), =), )^:.
Primo

3
@primo nett; Willst du ihre Erklärung? :-) <:bedeutet "dekrementieren" oder "kleiner oder gleich", #bedeutet "zählen von" oder "n-mal", -:bedeutet "halbieren" oder "epsilon-gleich", :`(bedeutet wiederum das Ende der "halbieren", die Verbindung zwischen zwei Verben in einem Gerundium und einer linken Klammer (zur Gruppierung verwendet). &*)bedeutet "etw. an die Multiplikation gebunden" (3 an die Multiplikation gebunden ergibt den Operator "mal drei") und das Ende der Gruppierung. =führt eine Gleichheitsprüfung oder im unären Sinne eine Selbsteinstufung durch. ^:ist die Potenz Konjunktion (Verb Iteration). Da viele J-Verben mit einem Doppelpunkt enden, ... :-)
John Dvorak

Jahre später ... Verbesserter Schleifenblock: '- & 2 # (> & 1 * -: + 2 & | * +: +>: @ -:) ^: a:' -> -1 char. : P
Randomra

Mehr Jahre später ... <:#a:2&(<*|+|6&*%~)19 Bytes (-11)
Meilen

6

Gambit-Schema, 106 98 Zeichen, 40 Klammern

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

91 89 Zeichen mit direkt definieren

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


Ich bin schon lange nicht mehr da, aber ich habe bemerkt, dass die Leute normalerweise 1 Antwort pro Programmiersprache posten.
jsedano

Sorry, das wusste ich nicht :)
Valentin CLEMENT

Bearbeitet, um die Python-Version zu entfernen.
Valentin CLEMENT

1
Nicht wahr! Die Leute neigen dazu , eine Antwort pro Programmiersprache zu posten, aber das liegt daran, dass sie nicht direkt mit jemand anderem mit einer kürzeren Antwort konkurrieren wollen. Aber niemand wird sich beschweren, wenn Sie eine andere Antwort in derselben Sprache verfassen.
Brotkasten

@ Breadbox nicht wahr. Ich poste eine Antwort pro Sprache, wenn jede Lösung für sich im Vergleich zur anderen interessant ist. Wenn beide Lösungen jeweils so interessant sind wie beide zusammen (derselbe Algorithmus, keine interessanten Sprachtricks), poste ich sie als eine. Normalerweise poste ich nicht mehrere Lösungen, weil ich zuerst eine Sprache auswähle, dann das Problem in dieser Sprache löse - dann bin ich normalerweise zu faul, um dasselbe in einer anderen Sprache zu schreiben - oder ich mache mich auf eine Reise, um noch eine andere Programmierung zu lernen Sprache.
John Dvorak

6

PowerShell: 77 74 71 70 61

Golf Code:

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

Anmerkungen:

Ich habe ursprünglich versucht, die Benutzereingabe zu übernehmen, ohne sie in eine Ganzzahl umzuwandeln, aber das hat auf interessante Weise funktioniert. Alle ungeraden Eingaben würden ungenau verarbeitet, aber gerade Eingaben würden gut funktionieren. Ich brauchte eine Minute, um zu begreifen, was los war.

Bei der Multiplikation oder Addition behandelt PowerShell nicht eingegebene Zeichen zuerst als Zeichenfolge. So '5'*3+1wird ‚5551‘ statt 16. Die geraden Eingänge verhielt sich gut , weil Powershell keine Standardaktion für die Division gegen Strings haben. Selbst die geraden Eingaben, die durch ungerade Zahlen verlaufen würden, funktionierten einwandfrei, da die Variable zu dem Zeitpunkt, an dem PowerShell eine ungerade Zahl in der Schleife erreichte, von den mathematischen Operationen ohnehin bereits auf eine Ganzzahl gezwungen wurde.

Dank Danko Durbic für den Hinweis auf , ich könnte nur die Multiplikationsoperation umkehren und nicht werfen müssen read-hostin int da Powershell seine Operationen auf dem ersten Objekt basiert.

PowerShell Golfer-Tipp: In einigen Szenarien wie diesem switchschlägt if/else. Hier betrug der Unterschied 2 Zeichen.

Mit freundlicher Genehmigung von Danko Durbic : In diesem speziellen Szenario kann ein Array anstelle von verwendet werden switch, um 8 weitere Zeichen zu speichern!

Es wird kein Fehler bei der Suche nach nicht ganzzahligen Werten oder Ganzzahlen unter zwei festgestellt.

Wenn Sie das Skript überwachen möchten, setzen Sie es ;$ikurz vor die letzte Klammer im Skript.

Ich bin nicht sicher, wie gut PowerShell mit Zahlen umgeht, die sehr große Werte annehmen, aber ich gehe davon aus, dass die Genauigkeit irgendwann verloren geht. Leider gehe ich auch davon aus, dass nicht viel getan werden kann, ohne das Skript ernsthaft aufzublähen.


Ungolfed Code, mit Kommentaren:

# 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

Testfälle:

Unten finden Sie einige Beispiele mit aktivierter Überwachung. Der Klarheit halber habe ich auch die Ausgabe bearbeitet, indem ich der Eingabe und der Endzählung Beschriftungen hinzufügte und Abstände einfügte, um die Collatz-Werte voneinander zu trennen.

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

Interessante Bits zu den Eingangsnummern, die nicht aus den Testfällen der Frage stammen:


2
Nett! Sie können es immer noch etwas verkürzen, durch den Austausch switchmit$i=(($i/2),($i*3+1))[$i%2]
Danko Durbić

2
Auch Sie müssen nicht konvertieren read-hostzu Nummer - nur ändern $i*3zu 3*$i.
Danko Durbić

Ein Array statt Switch? Brillant! Und tauschen $i*3- warum habe ich das nicht schon gedacht?
Iszi

1
param($i)for(;$i-ne1;$x++){$i=(($i/2),(3*$i+1))[$i%2]}$x- Tauschen Sie den Lesehost gegen einen Parameter aus, um 56 Bytes zu erhalten . Versuchen Sie es online Link
TessellatingHeckler

6

80386 Assembly, 16 Bytes

In diesem Beispiel wird die AT & T-Syntax und die Fastcall-Aufrufkonvention verwendet. Das Argument lautet 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);

Hier sind die resultierenden 16 Byte Maschinencode:

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

6

Brachylog , 16 Bytes

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

Probieren Sie es online!

Erläuterung

         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.

Eine alternative Lösung bei gleicher Byteanzahl:

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

Probieren Sie es 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.


5

F # - 65 Zeichen

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

5

Python 68 58 54 52 Zeichen

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

Danke an Bakuriu und boothby für die Tipps :)


Sie können n%2and 3*n+1or n/2damit 5 Zeichen speichern. Außerdem können Sie in python2 den Aufruf von entfernen intund die Größe auf 58 Byte reduzieren.
Bakuriu

Oh, man kann sogar kürzer als das: [n/2,3*n+1][n%2].
Stand

Das ist schick!
Valentin CLEMENT

Ist das Python 2.7? Ich erhalte einen Fehler in Python 3.5.1? unsupported operand type(s) for -: 'str' and 'int'
George

5

Retina , 43 Bytes

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

Übernimmt die Eingabe und druckt die Ausgabe in unary.

Jede Zeile sollte in eine eigene Datei gehen. 1 Byte pro zusätzlicher Datei zur Byteanzahl hinzugefügt.

Sie können den Code als eine Datei mit dem -sFlag ausführen . Z.B:

> echo -n 1111111|retina -s collatz
1111111111111111

Der Algorithmus ist eine Schleife, in der ein Collatz-Schritt mit der unären Nummer ausgeführt wird und xam Ende der Zeichenfolge ein neuer Schrittmarker hinzugefügt wird, wenn die Nummer nicht 1 ist.

Wenn die Schleife endet 1, wandeln wir die Marker in eine unäre Zahl um (wobei die führende Zahl entfernt wird 1). Dies ist die gewünschte Ausgabe.


5

Gelee , nicht konkurrierend

12 bytes Diese Antwort ist nicht konkurrierend, da die Herausforderung vor der Erstellung von Jelly liegt.

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

Probieren Sie es online!

Wie es funktioniert

×3‘$HḂ?ß0’?‘  Main link. Argument: n (integer)

     Ḃ?       Yield the last bit of n is 1:
   $            Evaluate the three links to the left as a monadic chain:
×3                Multiply n by 3.
  ‘               Increment the product by 1.
    H           Else, halve n.
         ’?   If n-1 is non-zero:
       ß        Recursively call the main link.
        0     Else, yield 0.
           ‘  Increment the result by 1.

4

dc, 27 zeichen

Anwenden von Boothby schwarzer Magie :

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

Ich bin mir nicht sicher, ob ich verstehe, wie - oder wie - es funktioniert.

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

dc, 36 zeichen

Meine eigene Schöpfung; Ein etwas traditionellerer Ansatz, obwohl ich mich ein wenig mit der Sprache auseinandersetzen musste, um das Fehlen eines elseTeils der ifAussagen zu überwinden :

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

Intern werden alle Nummern der Sequenz erzeugt und auf dem Stapel gespeichert. Anschließend wird das Finale eingefügt 1und die Stapelhöhe angezeigt.


1
Parität ist keine schwarze Magie.
Stand

1
Nein, aber es ist ein sehr guter Trick! Ich habe selbst ähnliche Sachen gemacht, ich habe nur in diesem Fall nicht darüber nachgedacht. Was mich für eine Sekunde gestolpert hat, war die Division, aber ich verstehe: Sie teilen durch sechs und machen die erste Operation (* = 3, + = 1) mit der zweiten rückgängig, wenn die Parität falsch war, und wegen der Ganzzahldivision erfolgt die Addition weg auch, und wir haben im Grunde getan / = 2. Sehr klug :)
Daniero

1
+1. Ich dachte, ich würde diese Herausforderung mit dc zerschlagen, kam aber nur bis zu 40. Ich habe Ihre Antwort 27 gesehen. Naja.
Digitales Trauma

Ich hatte diese Herausforderung nicht gesehen, aber vor einiger Zeit über das Drucken der Collatz-Sequenz in dc gebloggt. Mein Ansatz ähnelt Ihrem, verliert aber byteweise, sodass ich keinen Grund sehe, ihn zu posten. Als ich mir jedoch meine ansah, um zu sehen, wie einfach es ist, von jedem Schritt zum Drucken der Anzahl der Schritte zu gelangen, entdeckte ich etwas, das ein Byte von Ihnen spielen kann ... Da die Collatz-Sequenz immer von 2 zu 1 geht, Sie können Ihre Bedingung auf ändern 2<xund die entfernen k. Nur für den Fall, dass Sie nach vier Jahren ein Byte zurück haben möchten. : D
brhfl

4

Brainfuck , 59 56 Bytes

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

Probieren Sie es online! (Leicht modifiziert für einfache Bedienung)

Eingabe und Ausgabe als Zeichencodes. Dies ist bei Zellen beliebiger Größe nützlicher, kann jedoch auch bei kleinen Werten mit begrenzten Zellengrößen verwendet werden.

Wie es funktioniert

Tape Format:
Counter 0 Copy Number Binary...
^End           ^Start

,-[ Get input, decrement by 1 and start loop
  <->                  Initialises the copy of the value at -1
  [[>]+<[-<]>>]        Converts the input to binary while preserving a negative copy
  <+>>[-<<[++>+<]>->] If the last digit of the binary is 1 (n-1 is odd), divide by 2 and decrement
  <<[+>+++<]            If the last digit of the binary is 0 (n-1 is even), multiply by 3
  <<+>>>               Increment counter and end on n-1
]<<<.                 End loop and print counter

4

Hexagony , 48 44 Bytes

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

Probieren Sie es online!

Erweitert:

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

Beachten Sie, dass dies aus 1ähm ... Gründen fehlschlägt . Ehrlich gesagt bin ich mir nicht mehr sicher, wie das funktioniert. Ich weiß nur, dass der Code für ungerade Zahlen für gerade Zahlen rückwärts läuft. Irgendwie?

Die neue Version ist viel sauberer als die vorherige, weist jedoch im Vergleich ein paar mehr Richtungsangaben auf und endet ebenfalls mit einem Fehler beim Teilen durch Null. Der einzige Fall, in dem es keinen Fehler macht, ist, wenn es tatsächlich 1richtig behandelt wird.


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

@Sok Ja, deshalb habe ich es gepostet, anstatt verrückt zu werden und zu versuchen, das zu beheben
Jo King

3

C, 70 69 Zeichen

Ganz einfach, keine Tricks.
Liest die Eingabe von stdin.

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

3

Q, 46

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

32 Bytes mit(#)1_(1<){(1+3*x;x%2)0=x mod 2}\
Streetster

3

Ruby 1.9, 49 Zeichen

Die Python-Antwort von Rubyfied Valentin CLEMENT mit der Stabby-Lambda-Syntax. Sqeezed es in eine Anweisung für zusätzliche Unlesbarkeit.

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

Ein wenig Overhead, weil Ruby im Gegensatz zu Python nicht gerne Zahlen mit Booleschen Werten mischt.


3

C ++ ( 51 48)

Dies ist eine rekursive Funktion, die dies ausführt. Eingangsablesung erfolgt separat.

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

Ich bin mir sicher, dass ich mit dem == 0Zeug irgendeinen "und / oder" Trick machen kann , aber ich habe keine Ahnung, wie.


Sie können das entfernen ==0und die Seiten des Bedingten
austauschen

Auch keine Notwendigkeit zu behandeln, n==1weil ich in der Frage angegeben, dass die Zahl immer größer als 1 ist
Türklinke

Das Problem ist, dass dies n==1der Basisrekursionsfall ist. Putting n==2es würde die Punktzahl jeder nicht verbessern.
Joe Z.

Ah, dann könnten Sie es einfach durch dieses ersetzen: return~-n?und die bedingten Seiten tauschen
Türklinke

. n==1== n<2.
CalculatorFeline

3

~ - ~! (Kein Kommentar) - 71 53

Diese Sprache ist offensichtlich nicht die beste für das Golfen, da es an einer großen Anzahl von nativen Funktionen mangelt, aber das ist das Schöne daran.

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

Stellen Sie '''zunächst Ihre Eingabe ein. Die Funktion ''kann dann %als Eingabe mit aufgerufen werden und gibt die Antwort wie folgt zurück:

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

Dies wird zurückkehren ~~~~~. Es funktioniert tatsächlich für n==1(es schleift für immer mit n==0).

Wie immer mit dieser Sprache, ungetestet.


3

JavaScript (ES6) - 29 Zeichen

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

Erstellt eine Funktion, fdie ein einzelnes Argument akzeptiert und die Anzahl der Iterationen zurückgibt.

JavaScript - 31 Zeichen

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

Angenommen, die Eingabe befindet sich in der Variablen nund erstellt eine Variable cmit der Anzahl der Iterationen (und wird auch cals letzter Befehl an die Konsole ausgegeben ).



3

Perl 6, 40 Bytes

Rekursive Funktionsmethode nach Valentin CLEMENT und daniero : 40 Zeichen

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

Lazy-List-Methode: 32 Zeichen

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

3

> <>, 27 26 23 Bytes

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

Wie die anderen> <> Antworten wird auch hierdurch die Reihenfolge auf dem Stapel erstellt. Sobald die Sequenz 2 erreicht, entspricht die Größe des Stapels der Anzahl der durchgeführten Schritte.

Dank @Hohmannfan werden 3 Bytes durch eine sehr clevere Methode zur direkten Berechnung des nächsten Wertes eingespart. Die Formel zur Berechnung des nächsten Werts in der Sequenz lautet:

f(n)=n5(nmod2)+12+(nmod2)

Der Bruch bildet gerade Zahlen auf 0,5 und ungerade Zahlen auf 3 ab. Das Multiplizieren nund Addieren n%2vervollständigt die Berechnung - es ist überhaupt nicht erforderlich, den nächsten Wert zu wählen!

Edit 2: Hier ist die pre- @ Hohmannfan-Version:

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

Der Trick dabei ist, dass beide 3n+1und n/2bei jedem Schritt in der Sequenz berechnet werden und anschließend derjenige ausgewählt wird, der aus der Sequenz entfernt werden soll. Dies bedeutet, dass der Code erst verzweigen muss, wenn 1 erreicht ist, und die Berechnung der Sequenz in einer Codezeile erfolgen kann.

Bearbeiten: Wurde ein anderes Zeichen entfernt, nachdem erkannt wurde, dass die einzige positive Ganzzahl, die zu 1 führen kann, 2 ist. Da die Ausgabe des Programms für die Eingabe <2 keine Rolle spielt, kann die Sequenzgenerierung beendet werden, wenn 2 erreicht ist, und die Stapelgröße verbleibt Dies ist die genaue Anzahl der erforderlichen Schritte.

Vorgängerversion:

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

1
Sie können es bis 23 spielen, wenn Sie die zweite Reihe noch mehr aus der Reihe nehmen:\::2%:@5*1+2,*+:2=?
Hohmannfan
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.