Collatz-Pfade: Vorwärts und rückwärts entlang der Collatz-Vermutung

8

Die Collatz-Vermutung ist eine sehr bekannte Vermutung. Nehmen Sie eine positive ganze Zahl; Wenn es gerade ist, dividieren Sie durch 2, andernfalls multiplizieren Sie mit 3 und addieren Sie 1. Wiederholen Sie diesen Vorgang, bis Sie erreichen 1oder etwas anderes passiert. Die Vermutung ist, dass dieser Prozess immer erreicht 1.

Sie können den Vorgang auch umkehren. Beginnen Sie mit 1, multiplizieren Sie mit 2 und verzweigen Sie zu multiply by 3 and add 1Zahlen, wenn Sie eine gerade Zahl erreichen 1 (mod 3), dh subtrahieren Sie 1 und dividieren Sie durch 3.

Ein Collatz-Pfad kombiniert die beiden und versucht, mit diesen vier Operationen von einer Zahl zur nächsten zu gelangen.

Zum Beispiel, um zu gelangen 20von 1:

1     *2
2     *2
4     *2
8     *2
16    *2
5     (-1)/3
10    *2
20    *2

Sie können erhalten auch 3von 10um 1 subtrahiert und dividiert durch 3.

Mit diesen Werkzeugen können Sie einen Collatz-Pfad von einer Zahl zur anderen durchlaufen. Zum Beispiel ist der Pfad von 20bis 3(durch 2 teilen) (1 subtrahieren, durch 3 teilen).

Kurz gesagt, die verfügbaren Operationen sind:

n * 2       always
n // 2      if n % 2 == 0
n * 3 + 1   if n % 2 == 1
(n-1) // 3  if n % 6 == 4

Hinweis: Nicht alle Collatz-Pfade sind kurz. a(7,3)könnte funktionieren

7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1, 2, 4, 8, 16, 5, 10, 3

aber ein kürzerer Weg ist

7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 3

Die Herausforderung

Finden Sie die Länge des kürzesten Collatz-Pfades zwischen zwei beliebigen positiven ganzen Zahlen pund q.

  • Die Eingabe ist zwei beliebige positive Ganzzahlen kleiner als 2^20zur Vermeidung eines Ganzzahlüberlaufs. Die Eingabemethode liegt im Ermessen des Golfers. Die ganzen Zahlen können gleich sein. In diesem Fall ist die Länge des Collatz-Pfades gleich 0.
  • Die Ausgabe sollte eine Ganzzahl sein und die Länge des kürzesten Collatz-Pfades zwischen pund angeben q.

Testfälle

a(2,1)
1

a(4,1)
1         # 4 -> 1

a(3,1)
6         # 3 -> 10 -> 5 -> 16 -> 8 -> 4 -> 1

a(11,12)
11        # 11 -> 34 -> 17 -> 52 -> 26 -> 13
          # -> 40 -> 20 -> 10 -> 3 -> 6 -> 12

a(15,9)
20        # 46 -> 23 -> 70 -> 35 -> 106 -> 53 -> 160 -> 80 -> 40 -> 13
          # -> 26 -> 52 -> 17 -> 34 -> 11 -> 22 ->  7 -> 14 -> 28 -> 9

Vielen Dank an orlp für ihre Hilfe bei der Klärung dieser Herausforderung.

Wie immer, wenn das Problem unklar ist, lassen Sie es mich bitte wissen. Viel Glück und gutes Golfen!

Sherlock9
quelle
1
Unsere Computer würden eine Reihe von mindestens 2 ^ 31 Elementen nicht aushalten.
@MatthewRoh Challenge wurde inzwischen bearbeitet.
Sherlock9
Dies ist so ziemlich eine Herausforderung für die graphentheoretische Wegfindung . Und ich bin mir ziemlich sicher, dass wir vorher einen fast identischen hatten.
Fehler
Mögliches Duplikat der kürzesten Pfade in einem Divisor-Diagramm
Fehler
2
@flawr Ich bin mit dem Duplikat nicht einverstanden. Ja, beide Herausforderungen möchten einen Pfad in einem Diagramm finden, aber die Diagramme sind unterschiedlich, und die Codierung der Diagrammstruktur in Ihrer Antwort ist der einzigartige Teil, IMO. Sehen Sie sich zum Beispiel meine Antwort an und vergleichen Sie sie mit den Antworten in Ihrer "doppelten" Frage.
Orlp

Antworten:

3

Haskell, 170 158 157 146 143 137 135 112 109 108 106 100 99 Bytes

a!b=length$fst$break(elem b)$iterate(>>= \n->2*n:cycle[div n 2,n*3+1]!!n:[div(n-1)3|mod n 6==4])[a]

Ich hatte nicht erwartet, dass meine Originalversion so viel golffähiger ist, das ist auch die Arbeit von @nimi @Lynn und @Laikoni!

Danke @Laikoni für ein Byte, @Lynn für 11 14 20 21 Bytes, @nimi für 8 Bytes!

Dies erweitert den Baum der besuchten Nummern (beginnend mit a) Schritt für Schritt und prüft in jedem Schritt, ob wir zu der angegebenen Nummer gekommen sind b.

fehlerhaft
quelle
Sie haben ein Feld verpasst:iterate s [a] -> iterate s[a]
Laikoni
Sweet ~ Inlining sspart drei weitere Bytes! iterate(nub.concat.map f)[a]Brauchen Sie das wirklich nub?
Lynn
Sagen Sie mir, wenn Sie mit dem Golfen fertig sind: D Vielen Dank. Leider habe ich immer noch Probleme, Monaden zu verstehen.
Fehler
@nimi Nochmals vielen Dank, ich hätte nie gedacht, dass es so viel golffähiger ist! Ich wusste nicht breakund spanwirklich nützlich!
Fehler
1
Ersetzen [div n 2,n*3+1]!!mod n 2mit cycle[div n 2,n*3+1]!!nspart ein weiteres Byte :)
Lynn
2

Python 2, 110 Bytes

a=lambda p,q,s={0}:1+a(p,q,s.union(*({p,n*2,[n/2,n*3+1][n%2]}|set([~-n/3]*(n%6==4))for n in s)))if{q}-s else-1
orlp
quelle
1

Pyth, 30 Bytes

|q*FQ2ls-M.pm.u&n2N?%N2h*3N/N2

Probieren Sie es online aus

Wie es funktioniert

Nehmen Sie die Länge der symmetrischen Differenz der beiden Vorwärts-Collatz-Sequenzen, beginnend bei den beiden Eingangsnummern und endend bei 2. Die einzige Ausnahme ist, ob die Eingabe [1, 2]oder ist [2, 1], was wir im Sonderfall tun.

  *FQ                        product of the input
|q   2                       if that equals 2, return 1 (True), else:
            m                  map for d in input:
             .u                  cumulative fixed-point: starting at N=d, iterate N ↦
               &n2N?%N2h*3N/N2     N != 2 and (N*3 + 1 if N % 2 else N/2)
                                 until a duplicate is found, and return the sequence
          .p                   permutations
        -M                     map difference
       s                       concatenate
      l                        length
Anders Kaseorg
quelle
1

Python 2, 156 179 191 209 181 172 177 171 Bytes

Da ein Collatz-Pfad als die erste Zahl vorgestellt a(1,p)und a(1,q)verbunden werden kann, die beiden Sequenzen gemeinsam a(1,n)ist und die ursprüngliche Collatz-Vermutung ist, berechnet diese Funktion die Collatz-Sequenz von pund qund berechnet die Länge von dort. Dies ist kein schönes Golfspiel, daher sind Golfvorschläge sehr willkommen. Die einzige Ausnahme ist wann p or q == 1. Da wir dann im Gegensatz zu einer regulären Collatz-Sequenz direkt von 4nach überspringen können 1, müssen wir einen Schritt vom Ergebnis abziehen.

Bearbeiten: Viele Fehlerbehebungen.

Bearbeiten: Viele, viele Fehlerbehebungen

f=lambda p:[p]if p<3else f([p//2,p*3+1][p%2])+[p]
def a(p,q):
 i=1;c=f(p);d=f(q)
 if sorted((p,q))==(1,2):return 1
 while c[:i]==d[:i]!=d[:i-1]:i+=1
 return len(c+d)-2*i+2

Probieren Sie es online aus!

Sherlock9
quelle
Ihr Ansatz funktioniert nicht, z. B. a(3,1)gibt 7 zurück, während er 6 zurückgeben sollte, da der kürzeste Weg ist3 -> 10 -> 5 -> 16 -> 8 -> 4 -> 1
fehlerhaft
@flawr bearbeitet. Hoffentlich funktioniert es jetzt
Sherlock9
Warum nehmen Sie an, dass der von Ihnen beschriebene Algorithmus funktioniert? Könnte ein kürzester Weg nicht darin bestehen, mehrmals "hin und her" zu gehen?
Fehler
2
Lassen Sie fbezeichnen einen Schritt vorwärts, beinen Schritt zurück in der Collatz - Sequenz. Das Muster b->fkann sich nicht auf einem kürzesten Weg befinden, da es sich um die Identität handelt ( fwird bauf jeden Fall rückgängig gemacht ). Der kürzeste Weg kann also nur aus Mustern bestehen f->f, f->bund b->b. Das bedeutet wieder, dass der kürzeste Weg immer die Form f->f->...->foder b->b->...->boderf->...->f->b->...->b
Fehler
3
PS: Ich habe den Eindruck, dass Ihre Byteanzahl in die falsche Richtung geht. : D
Fehler
0

JavaScript (ES6), 135 Byte

f=(x,y,a=[(s=[],s[0]=s[x]=1,x)],z=a.shift())=>z-y?[z*2,z/2,z%2?z*3+1:~-z/3].map(e=>e%1||s[e]?0:s[a.push(e),e]=-~s[z])&&f(x,y,a):~-s[y]

Führt eine Breitensuche durch. xist die Startnummer, ydas Ziel, aeine Anordnung von Testwerten, seine Anordnung von der Anzahl der Schritte , einschließlich der Kette aus x, zder aktuellen Wertes. Wenn zund ynicht gleich sind , berechnen z*2, z/2und entweder z*3+1oder (z-1)/3, je nachdem , ob zgerade oder ungerade ist, dann Fraktionen herauszufiltern und vorher gesehen Werte und fügen Sie sie in der Suchliste.

Neil
quelle
0

Python 2, 80 Bytes

p=lambda n:n-2and{n}|p([n/2,n*3+1][n%2])or{n}
lambda m,n:m*n==2or len(p(m)^p(n))

Nehmen Sie die Länge der symmetrischen Differenz der beiden Vorwärts-Collatz-Sequenzen, beginnend bei den beiden Eingangsnummern und endend bei 2. Die einzige Ausnahme ist, wenn die Eingabe 1, 2 oder 2, 1 ist, was wir im Sonderfall tun.

Anders Kaseorg
quelle