Fibonacci-Bahnen zählen


13

Wenn wir eine Fibonacci-ähnliche Folge als f k (n) = (f k (n-1) + f k (n-2))% k definieren , ist die Folge für eine ganze Zahl k (wobei % der Modulo-Operator ist) wird notwendigerweise zyklisch sein, weil es nur k 2 verschiedene Werte für (f k (n-1), f k (n-2)) gibt . Da dieser Zyklus in der Regel nicht alle möglichen Wertepaare enthält, kann es in Abhängigkeit von den beiden Startwerten f k (0) und f k (1) zu unterschiedlichen Zyklen kommen. Zum Beispiel für k = 2Abhängig von den ersten beiden Werten haben wir die folgenden vier Möglichkeiten:

0, 0, 0, 0, 0, 0, 0, 0, 0, ...
0, 1, 1, 0, 1, 1, 0, 1, 1, ...
1, 0, 1, 1, 0, 1, 1, 0, 1, ...
1, 1, 0, 1, 1, 0, 1, 1, 0, ...

Aufgrund der zyklischen Natur der Sequenzen gibt es hier eigentlich nur zwei grundlegend unterschiedliche Sequenzen mit den Umlaufbahnen (0) und (0, 1, 1) . Schauen wir uns k = 3 an :

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
0, 1, 1, 2, 0, 2, 2, 1, 0, 1, 1, 2, 0, 2, 2, 1, ...
0, 2, 2, 1, 0, 1, 1, 2, 0, 2, 2, 1, 0, 1, 1, 2, ...
1, 0, 1, 1, 2, 0, 2, 2, 1, 0, 1, 1, 2, 0, 2, 2, ...
1, 1, 2, 0, 2, 2, 1, 0, 1, 1, 2, 0, 2, 2, 1, 0, ...
1, 2, 0, 2, 2, 1, 0, 1, 1, 2, 0, 2, 2, 1, 0, 1, ...
2, 0, 2, 2, 1, 0, 1, 1, 2, 0, 2, 2, 1, 0, 1, 1, ...
2, 1, 0, 1, 1, 2, 0, 2, 2, 1, 0, 1, 1, 2, 0, 2, ...
2, 2, 1, 0, 1, 1, 2, 0, 2, 2, 1, 0, 1, 1, 2, 0, ...

Auch hier gibt es nur zwei verschiedene Umlaufbahnen: (0) und (0, 1, 1, 2, 0, 2, 2, 1) .

Für höhere k erhalten wir möglicherweise mehr Umlaufbahnen, aber sie fallen immer noch in eine vergleichsweise kleine Anzahl von Klassen. Zum Beispiel ergibt k = 4 die vier Bahnen (0) , (0,1,1,2,3,1) , (0, 2, 2) , (0, 3, 3, 2, 1, 3) und k = 5 die drei Bahnen (0) , (0, 1, 1, 2, 3, 0, 3, 3, 1, 4, 0, 4, 4, 3, 2, 0, 2, 2, 4, 1) und (1, 3, 4, 2) .

Ihre Aufgabe bei dieser Herausforderung ist es, zu berechnen, wie viele Umlaufbahnen die Sequenz für ein gegebenes k erzeugt . Dies ist OEIS A015134 . Hier sind die ersten 100 Werte (ab k = 1 ):

1, 2, 2, 4, 3, 4, 4, 8, 5, 6, 14, 10, 7, 8, 12, 16, 9, 16, 22, 16,
29, 28, 12, 30, 13, 14, 14, 22, 63, 24, 34, 32, 39, 34, 30, 58, 19,
86, 32, 52, 43, 58, 22, 78, 39, 46, 70, 102, 25, 26, 42, 40, 27, 52,
160, 74, 63, 126, 62, 70, 63, 134, 104, 64, 57, 78, 34, 132, 101, 60,
74, 222, 37, 38, 62, 328, 89, 64, 82, 124, 41, 86, 42, 172, 75, 44,
184, 178, 181, 132, 82, 180, 99, 140, 104, 246, 49, 50, 114, 76

Stellen Sie sicher, dass k = 11 ist. Dies ist die erste Eingabe, die mehr als k Umlaufbahnen liefert .

Regeln

Sie erhalten eine positive Ganzzahl k und sollten A015134 (k) ausgeben .

Sie können ein Programm oder eine Funktion schreiben und eine der Standardmethoden zum Empfangen von Eingaben und zum Bereitstellen von Ausgaben verwenden.

Sie können jede Programmiersprache verwenden , aber beachten Sie, dass diese Lücken standardmäßig verboten sind.

Das ist , also gewinnt die kürzeste gültige Antwort - gemessen in Bytes .


3
Dies ist nahe genug an codegolf.stackexchange.com/q/26578/194, dass ich es nicht einseitig schließen werde, aber ich würde die 5. Stimme abgeben, um es als Betrug zu schließen.
Peter Taylor

Antworten:


3

Schale , 17 16 Bytes

Lüȯ€U¡ȯ↔m%⁰∫π2ŀ⁰

Probieren Sie es online!

Erläuterung

Lüȯ€U¡ȯ↔m%⁰∫π2ŀ⁰  Implicit input, say n=4.
              ŀ⁰  Lowered range: [0,1,2,3]
            π2    Cartesian second power: [[0,0],[0,1],[1,0],[0,2]..
 üȯ                Deduplicate with respect to this function:
   €U¡ȯ↔m%⁰∫       Arguments are two pairs, say a=[0,2], b=[1,1]
     ¡ȯ            Iterate on a:
           ∫       Cumulative sum,
        m%⁰        take modulo n of each,
       ↔           then reverse: [[0,2],[2,0],[2,2],[0,2],[2,0]..
    U              Cut at first repeated element: [[0,2],[2,0],[2,2]]
   €               Is b in this list? No, so they are distinct in ü.
L                 Number of remaining pairs.


1

Wolfram Language (Mathematica) , 76-70 Bytes

Tr[EdgeCycleMatrix[#->{#[[2]],Tr@#~Mod~n}&/@Tuples[Range[n=#]-1,2]]!]&

Probieren Sie es online!

Wie es funktioniert

Wir konstruieren den Graphen nach den Regeln {{0,0}->{0,0}, {1,0}->{1,1}, ...}, die bei zwei Elementen einer verallgemeinerten Fibonacci-Folge das nächste Modulo finden n. DasEdgeCycleMatrix gibt die Inzidenzmatrix von Zyklen zu Kanten in diesem Diagramm an; Wir wollen seine Zeilen zählen.

(Es gibt eine Reihe von integrierten Funktionen, die ähnliche Aufgaben ausführen, jedoch ConnectedComponentslänger sind und FindCycleviele zusätzliche Eingaben benötigen, damit sie funktionieren. Außerdem EdgeCycleMatrixhandelt es sich um ein rechteckiges Array, das nicht wie die anderen beiden Formen witzig ist . Dies hilft später. )

Um die Zeilen der Matrix zu zählen, nehmen wir die Fakultät der Einträge, um sie in eine Matrix aller zu verwandeln, und nehmen dann den Trace. (Jeder Zyklus enthält mindestens eine Kante, und daher gibt es mindestens so viele Spalten wie Zeilen. Dies zählt also die Zeilen und nicht die Spalten.)


1

MATL , 38 36 Bytes

:qt!J*+le"@GU:"t&Zjwy+G\J*+hu]S]Xhun

Probieren Sie es online! Bei Eingabeüberschreitung tritt im Online-Compiler eine Zeitüberschreitung auf7.

Erläuterung

Der Code definiert Umlaufbahnen in Form komplexer Zahlen, wobei der Imaginärteil der neue Term und der Realteil der vorangehende Term in der Fibonacci-Sequenz ist. Jeder komplexe Wert codiert den Status der Sequenz. Bei gegebenem a+jbnächsten Wert wird nämlich berechnet als b+j(a+b).

Die möglichen Startwerte sind a+jbmit a, bin [0, 1, ..., k-1]. Für jeden Startwert iteriert der Code einige k^2Male. Um den Code zu verkürzen, wird jede Iteration auf alle angewendet akkumulierten Werte , und die Ergebnisse werden dedupliziert (was ohnehin am Ende erforderlich wäre). Nach der letzten Iteration wird der Vektor der deduplizierten komplexen Werte sortiert (nach Absolutwert, dann nach Winkel). Dies gibt eine "Signatur" für jede Umlaufbahn.

Am Ende des Programms werden die Signaturen in einem Zellenarray gesammelt. Die Anzahl der eindeutigen Signaturen ist die gewünschte Ausgabe.

:q          % Implicit input: k. Push row vector [0, 1, ..., k-1]
t!          % Duplicate, transpose: gives column vector [0; 1; ...; k-1]
J*+         % Multiply by 1j, add with broadcast. Gives a k × k matrix of
            % values a+jb with a, b in [0, 1, ..., k-1]
le          % Linearize into a row vector
"           % For each c in that vector
  @         %   Push c
  GU:"      %   Do the following k^2 times
    t&Zj    %     Duplicate and split into real and imaginary parts: a, b
    wy+     %     Swap, duplicate, from below, add: transforms a, b into
            %     b, a+b. This is the basic step in the Fibonacci sequence
            %     In subsequent iterations a and b may be vectors instead
            %     of numbers, as they include all values obtained so far
    G\      %     Modulo k, element-wise
    J*+     %     Times 1j, add. Gives the next complex number for each of
            %     the complex numbers so far
    hu      %     Append to values so far and deduplicate. This may extend
            %     the vector of complex numbers
  ]         %   End
  S         %   Sort
]           % End
Xh          % Collect entire stack into a cell array
u           % Deduplicate
n           % Number of entries. Implicit display

1

Haskell , 196.191 Bytes

import Data.List
o(a:b)=1+o[x|x<-b,not$(0<$a)==(0<$x)&&isInfixOf a(x++x)]
o _=0
k#(a,b)=(b,mod(a+b)k)
p!(a:b)|elem a p=fst<$>p|r<-p++[a]=r!b
f k=o[[]!iterate(k#)(a,b)|a<-[0..k-1],b<-[0..k-1]]

Probieren Sie es online!

Dies könnte wahrscheinlich verbessert werden. Insbesondere, wenn jemand einen Weg findet isInfixOf, den Import zu vermeiden und zu entfernen.

Grundlegende Idee ist es, eine Liste von "Zuständen" (Tupel, die die beiden vorherigen Werte enthalten) zu erstellen, um zu sehen, wann der Zyklus beginnt. Dann prüfen wir, ob sich jeder Orbit von seinen Vorgängern unterscheidet (funktioniert genau umgekehrt, ist aber schwer in Worte zu fassen). Um zu überprüfen, ob die Umlaufbahnen gleich sind, prüfen wir, ob die Länge gleich ist und ob eine in die andere passt, die mit sich selbst verkettet ist. Zum Beispiel [0,2,2], [2,2,0]: Länge beider ist 3 und [0,2,2,0,2,2]enthält [2,2,0]als kontinuierliche Subsequenz. Ich bin nicht sicher, ob es narrensicher ist, aber es scheint zu funktionieren.

EDIT: Danke an Laikoni für die 5 Bytes! Ich hätte mehr von diesen Tipps lesen sollen.


1
Anscheinend können Sie diesen Tipp verwenden , um dies zu vermeiden length. Ein weiteres Byte kann mit gespeichert !werden |r<-p++[a]=r!b.
Laikoni

0

JavaScript (ES6), 337-335 Byte

Entschuldigen Sie den Brute-Force-Algorithmus Ω (k ^ 3).

(k,x=o=0,u=[],s=(q,w,v,j=d=0)=>{while(j++<v)d|=q.reduce((a,b,i)=>a&=b==w[(i+j)%v],1);return d})=>{for(;x<k;x++)for(y=0;y<k;y++){l=2;r=[x,y];do{r.push((c=(d=r[(l+=2)-3])+r[l-4])%k,(c+d)%k)}while(!(t=r.slice(0,h=l/2)).reduce((a,b,i)=>a&=b==r[i+h],1));if(!u.reduce((q,z)=>q|=(t.length-(a=z.length)?0:s(t,z,a)),0)){o++;u.push(t)}}return o}

Die Leistung ... Als ich A015134 berechnet habe (etwas jenseits von k = 50), hat es das 60s-Limit für TIO überschritten.

var g=(k,x=o=0,u=[],s=(q,w,v,j=d=0)=>{while(j++<v)d|=q.reduce((a,b,i)=>a&=b==w[(i+j)%v],1);return d})=>{for(;x<k;x++)for(y=0;y<k;y++){l=2;r=[x,y];do{r.push((c=(d=r[(l+=2)-3])+r[l-4])%k,(c+d)%k)}while(!(t=r.slice(0,h=l/2)).reduce((a,b,i)=>a&=b==r[i+h],1));if(!u.reduce((q,z)=>q|=(t.length-(a=z.length)?0:s(t,z,a)),0)){o++;u.push(t)}}return o}

for (var ix = 1; ix <= 15; ix++)
 console.log(`A015134(${ix}) = ${g(ix)}`);

Erklärung (Ungolfed)

function CheckIfSameOrbit(Array_1, Array_2, Length) { // Checks if the orbits are equal
  var d = false, j = 0;                               // Assume both have same length
  while (j < v) {                                     // Checks for different startings
    j++;                                                
    d |= Array_1.reduce(function(Acc, Item, Index) {  // Element-by-element comparison
      Acc &= Item == w[(Index + j) % v], 1);                     
    });                                               // Return true if any starting
  }                                                   // point makes two orbits identical
}

function A015134(k) {                                 // Main Program
  var o = 0, u = [];                                    
  for (var x = 0; x < k; x++) {                       // Checks different pairs of (x, y)
    for (var y = 0; y < k; y++) {
      var l = 2, r = [x, y], h = 1, t;
      do {                                            // Find until a complete orbit is
        l += 2;                                       // found (except for (0, 0) case)
        h = l / 2;
        var d = r[l - 3], c = r[l - 3] + r[l - 4];
        r.push(c % k, (c + d) % k);
        t = r.slice(0, h);
      }                                                 
      while (!t.reduce(function(Acc, Item, Index) {   // Which is, if 2 identical copies
        Acc &= Item == r[Index + h];                  // of the orbit are calculated
      }, 1));

      if (!u.reduce(function(Acc, Item) {             // If the orbit is a new one
        var a = Item.length;
        Acc |= (t.length - a ? 0 : s(t, Item, a));
      }, 0)) {
        o++;                                          // Increment the counter, and
        u.push(t);                                    // record it to the list
      }
    }
  }
  return o;                                           // Ultimately return the counter;
}



0

JavaScript (ES6), 102 Byte

k=>F=(a=0,b=0,C=0,q)=>q?F[q=[a,b%=k]]?0:1|F(b,a+b,C,F[q]=1):b<k?F(a,b+1,C+F(a,b,C,1)):++a<k?F(a,0,C):C

Gibt eine Funktion zurück, die das Ergebnis liefert. Für 3 weitere Bytes können wir das Ergebnis direkt zurückgeben lassen:

k=>(F=(a,b,C,q)=>q?F[q=[a,b%=k]]?0:1|F(b,a+b,C,F[q]=1):b<k?F(a,b+1,C+F(a,b,C,1)):++a<k?F(a,0,C):C)(0,0,0)

Beide haben Zeitkomplexität O (n 2 ).


0

Python 2 , 214 Bytes

def h(k):
 R=[]
 for p in[[i/k,i%k,(i/k+i%k)%k]for i in range(k*k)]:
	while p[:2]!=p[-2:]:
		p.append(sum(p[-2:])%k)
	p=p[:-2]
	if not any([p==x[i:]+x[:i]for i in range(len(p))for x in R]):R.append(p)
 print len(R)

Probieren Sie es online!

Es ist nicht sehr effizient, aber es ist das Golfspiel, das ich machen kann.

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.