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 .
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
1+
ist als Spezialgehäuse ausgeführt)
.C -
5047 ZeichenSchlechtes 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.
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:quelle
return~-a?
speichert 1. Auch das Verschiebenb++
in den?
Fall sollte speichernb--
.Perl 34 (+1) Zeichen
Wie üblich
$\
für die endgültige Ausgabe missbrauchen . Mit der-p
Befehlszeilenoption ausführen, die Eingabe wird von übernommenstdin
.1 Byte aufgrund von Elias Van Ootegem gespeichert . Insbesondere die Beobachtung, dass die folgenden beiden gleichwertig sind:
Obwohl ein Byte länger, werden zwei Byte eingespart, indem
$_/2
auf "nur" gekürzt wird.5
.Beispielnutzung:
PHP 54 Bytes
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:
quelle
$_
im ternären verschwenderisch scheint, können Sie einen anderen Charakter , indem Sie abrasieren*=
wie folgt aus :$\++,$_*=$_&1?3+1/$_:.5while$_>1}{
. Das Multiplizieren mit1/$_
hat den gleichen Effekt wie+1
,$_*=3+1/$_
funktioniert also$_*=3+1/$_
ist brillant, danke!Mathematica (35)
Verwendungszweck:
quelle
Wie üblich beginne ich die Antworten mit meinen eigenen.
JavaScript,
4644 Zeichen (auf Konsole ausgeführt)quelle
Java,
165, 156, 154, 134, 131, 129, 128, 126 (auch ausführliche Sprachen brauchen etwas Liebe)Alles ist in der für getan
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.
quelle
i(,++y)
. Sie können zwei weitere speichern, indem Sie<
anstelle von verwenden==
.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) ErsetztShort.valueOf(...)
durchnew Short(...)
für -4 Bytes und 2) Ich habe dasx=x%2<1?x/2:x*3+1;
in den Körper derfor
Schleife gesteckt, um das loszuwerden Komma für -1 Byte .Rebmu : 28
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:
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:
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:
quelle
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 ...edit: ich habe eine andere lösung gefunden, die sich nie streiten wird, aber zu spaßig ist, nicht zu teilen.
quelle
(n//2,n*3+1)[n%2]
ist kürzer.n/2
so gut funktionieren, wie wir es selbst wissen?APL (31)
quelle
{1=⍵:0⋄2|⍵:1+∇1+3×⍵⋄1+∇⍵÷2}
{1=⍵:0⋄1+∇⊃⍵⌽0 1+.5 3×⍵}
J, 30 Zeichen
Es stellte sich heraus, ziemlich viel länger als gewünscht
Verwendungszweck:
-:`(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.quelle
<:
,#-:
,:`(
,&*)
,=)
,)^:
.<:
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, ... :-)<:#a:2&(<*|+|6&*%~)
19 Bytes (-11)Gambit-Schema,
10698 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)))
9189 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))
quelle
PowerShell:
7774717061Golf Code:
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+1
wird ‚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.PowerShell Golfer-Tipp: In einigen Szenarien wie diesem
switch
schlägtif/else
. Hier betrug der Unterschied 2 Zeichen.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
;$i
kurz 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:
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.
Interessante Bits zu den Eingangsnummern, die nicht aus den Testfällen der Frage stammen:
14
und197
sind Keith Numbers31
ist ein Mersenne Prime6174
ist Kaprekars Konstante8008135
. Und natürlich Numberphile .quelle
switch
mit$i=(($i/2),($i*3+1))[$i%2]
read-host
zu Nummer - nur ändern$i*3
zu3*$i
.$i*3
- warum habe ich das nicht schon gedacht?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 Link80386 Assembly, 16 Bytes
In diesem Beispiel wird die AT & T-Syntax und die Fastcall-Aufrufkonvention verwendet. Das Argument lautet
ecx
:Hier sind die resultierenden 16 Byte Maschinencode:
quelle
Brachylog , 16 Bytes
Probieren Sie es online!
Erläuterung
Eine alternative Lösung bei gleicher Byteanzahl:
Probieren Sie es online!
quelle
GolfScript (23 Zeichen)
Online-Test
quelle
F # - 65 Zeichen
quelle
Python
68585452 Zeichenf=lambda n:1+(n-2and f((n/2,3*n+1)[n%2]));f(input())
Danke an Bakuriu und boothby für die Tipps :)
quelle
n%2and 3*n+1or n/2
damit 5 Zeichen speichern. Außerdem können Sie in python2 den Aufruf von entfernenint
und die Größe auf 58 Byte reduzieren.[n/2,3*n+1][n%2]
.unsupported operand type(s) for -: 'str' and 'int'
Retina , 43 Bytes
Ü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
-s
Flag ausführen . Z.B:Der Algorithmus ist eine Schleife, in der ein Collatz-Schritt mit der unären Nummer ausgeführt wird und
x
am 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 wird1
). Dies ist die gewünschte Ausgabe.quelle
Gelee , nicht konkurrierend
12 bytes Diese Antwort ist nicht konkurrierend, da die Herausforderung vor der Erstellung von Jelly liegt.
Probieren Sie es online!
Wie es funktioniert
quelle
dc, 27 zeichen
Anwenden von Boothby schwarzer Magie :
Ich bin mir nicht sicher, ob ich verstehe, wie - oder wie - es funktioniert.
Verwendungszweck: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
else
Teils derif
Aussagen zu überwinden :Intern werden alle Nummern der Sequenz erzeugt und auf dem Stapel gespeichert. Anschließend wird das Finale eingefügt
1
und die Stapelhöhe angezeigt.quelle
2<x
und die entfernenk
. Nur für den Fall, dass Sie nach vier Jahren ein Byte zurück haben möchten. : DBrainfuck ,
5956 BytesProbieren 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
quelle
Hexagony ,
4844 BytesProbieren Sie es online!
Erweitert:
Beachten Sie, dass dies aus1
ä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
1
richtig behandelt wird.quelle
If a number < 2 is input ... output does not matter.
: o)C,
7069 ZeichenGanz einfach, keine Tricks.
Liest die Eingabe von stdin.
quelle
Q, 46
quelle
(#)1_(1<){(1+3*x;x%2)0=x mod 2}\
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.
Ein wenig Overhead, weil Ruby im Gegensatz zu Python nicht gerne Zahlen mit Booleschen Werten mischt.
quelle
C ++ (
5148)Dies ist eine rekursive Funktion, die dies ausführt. Eingangsablesung erfolgt separat.
Ich bin mir sicher, dass ich mit dem
== 0
Zeug irgendeinen "und / oder" Trick machen kann , aber ich habe keine Ahnung, wie.quelle
==0
und die Seiten des Bedingtenn==1
weil ich in der Frage angegeben, dass die Zahl immer größer als 1 istn==1
der Basisrekursionsfall ist. Puttingn==2
es würde die Punktzahl jeder nicht verbessern.return~-n?
und die bedingten Seiten tauschenn==1
==n<2
.~ - ~! (Kein Kommentar) -
7153Diese 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ürn==1
(es schleift für immer mitn==0
).Wie immer mit dieser Sprache, ungetestet.
quelle
JavaScript (ES6) - 29 Zeichen
Erstellt eine Funktion,
f
die ein einzelnes Argument akzeptiert und die Anzahl der Iterationen zurückgibt.JavaScript - 31 Zeichen
Angenommen, die Eingabe befindet sich in der Variablen
n
und erstellt eine Variablec
mit der Anzahl der Iterationen (und wird auchc
als letzter Befehl an die Konsole ausgegeben ).quelle
Perl 6, 40 Bytes
Rekursive Funktionsmethode nach Valentin CLEMENT und daniero : 40 Zeichen
Lazy-List-Methode: 32 Zeichen
quelle
> <>,
27 2623 BytesWie 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:
Der Bruch bildet gerade Zahlen auf 0,5 und ungerade Zahlen auf 3 ab. Das Multiplizieren
n
und Addierenn%2
vervollständigt die Berechnung - es ist überhaupt nicht erforderlich, den nächsten Wert zu wählen!Edit 2: Hier ist die pre- @ Hohmannfan-Version:
Der Trick dabei ist, dass beide
3n+1
undn/2
bei 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:
quelle
\::2%:@5*1+2,*+:2=?