Fibonacci Yörüngeleri Sayma


13

Fibonacci benzeri bir diziyi f k (n) = (f k (n-1) + f k (n-2))% k olarak tanımlarsak , bazı tamsayı k için (burada % modulo operatörüdür), dizi mutlaka döngüsel olacaktır, çünkü (f k (n-1), f k (n-2)) için sadece k 2 farklı değer vardır . Bununla birlikte, bu döngü genellikle tüm olası çift çiftlerini içermez , bu nedenle f k (0) ve f k (1) başlangıç ​​değerlerine bağlı olarak farklı döngüler alabiliriz. Örneğin, k = 2 için, ilk iki değere bağlı olarak aşağıdaki dört seçeneğe sahibiz:

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

Sekansların döngüsel doğası nedeniyle, burada yörüngeler (0) ve (0, 1, 1) olan sadece iki temel olarak farklı sekans vardır . Şimdi k = 3'e bakalım :

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

Yine, sadece iki farklı yörünge vardır: (0) ve (0, 1, 1, 2, 0, 2, 2, 1) .

Daha yüksek k için daha fazla yörünge alabiliriz, ancak yine de nispeten az sayıda sınıfa gireceklerdir. Örneğin k = 4 dört yörünge (0) , (0,1,1,2,3,1) , (0, 2, 2) , (0, 3, 3, 2, 1, 3) ve k verir = 5 üç yörünge (0) , (0, 1, 1, 2, 3, 0, 3, 3, 1, 4, 0, 4, 4, 3, 2, 0, 2, 2, 4, 1) ve (1, 3, 4, 2) .

Bu görevdeki göreviniz, belirli bir k için dizinin kaç yörünge oluşturduğunu hesaplamaktır . Bu OEIS A015134 . İşte ilk 100 değer ( k = 1'den başlayarak ):

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

K yörüngesinden daha fazlasını veren ilk giriş olan k = 11'i kontrol ettiğinizden emin olun .

kurallar

Size pozitif bir tamsayı k verilir ve A015134 (k) çıktısı almanız gerekir .

Bir program veya işlev yazabilir ve girdi alma ve çıktı sağlama gibi standart yöntemlerden herhangi birini kullanabilirsiniz .

Herhangi bir programlama dili kullanabilirsiniz , ancak bu boşlukların varsayılan olarak yasaklandığını unutmayın .

Bu , bu yüzden bayt cinsinden ölçülen en kısa geçerli cevap kazanır.


3
Bu tek taraflı olarak kapatmak olmaz kodgolf.stackexchange.com/q/26578/194 yeterince yakın ama ben dupe olarak kapatmak için 5. oy.
Peter Taylor

Yanıtlar:


3

Kabuk , 17 16 bayt

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

Çevrimiçi deneyin!

açıklama

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 Dili (Mathematica) , 76 70 bayt

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

Çevrimiçi deneyin!

Nasıl çalışır

{{0,0}->{0,0}, {1,0}->{1,1}, ...}Genelleştirilmiş bir Fibonacci dizisinin iki unsuru verildiğinde, bir sonraki modüloyu bulan kurallarla verilen grafiği oluşturuyoruz n. EdgeCycleMatrixBu grafikteki kenarlarına döngülerinden sıklığı matris verir; satırlarını saymak istiyoruz.

(Benzer bir görevi yerine getiren, ancak ConnectedComponentsdaha uzun olan ve FindCycleçalışmasını sağlamak için çok fazla ek girdiye ihtiyaç duyan bir dizi yerleşik vardır . Ayrıca, EdgeCycleMatrixdiğer ikisi gibi komik olmayan, daha sonra yardımcı olan dikdörtgen bir dizi. )

Matrisin satırlarını saymak için, girişlerin faktöriyesini tüm matrislere dönüştürmek için izliyoruz, ardından izi alıyoruz. (Her döngü en az bir kenar içerir ve bu nedenle en az satır kadar sütun vardır - bu nedenle sütunları değil satırları sayar.)


1

MATL , 38 36 bayt

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

Çevrimiçi deneyin! Girdi aşımı için çevrimiçi derleyicide zaman aşımına uğrar7.

açıklama

Kod, yörüngeleri karmaşık sayılarla tanımlar, burada hayali kısım yeni terimdir ve gerçek kısım Fibonacci dizisinde önceki terimdir . Her karmaşık değer dizinin durumunu kodlar . Yani, bir a+jbsonraki değer olarak hesaplanır b+j(a+b).

Olası başlangıç değerleri a+jbile a, biçinde [0, 1, ..., k-1]. Her başlangıç ​​değeri için kod k^2süreleri yineler . Aslında, kodu kısaltmak için, her yineleme şimdiye kadar birikmiş tüm değerlere uygulanır ve sonuçlar tekilleştirilir (yine de sonunda gerekli olacaktır). Son yinelemeden sonra tekilleştirilen karmaşık değerlerin vektörü sıralanır (mutlak değere, sonra açıya göre). Bu, her yörünge için bir "imza" verir.

Programın sonunda imzalar bir hücre dizisine toplanır. Benzersiz imza sayısı istenen çıktıdır.

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

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

Çevrimiçi deneyin!

Bu muhtemelen geliştirilebilir. Özellikle birisi isInfixOfiçe aktarmayı önlemek ve kaldırmak için bir yol bulabilirse .

Temel fikir, ne zaman dönmeye başladığını görmek için bir "durumlar" listesi (önceki iki değeri içeren tuples) oluşturmaktır. Sonra her yörüngenin öncekilerden farklı olup olmadığını kontrol ederiz (gerçekten tersi çalışır, ancak kelimelere dökmek zordur). Yörüngelerin aynı olup olmadığını kontrol etmek için, uzunluğun aynı olup olmadığını ve birinin kendisiyle birleştirilmiş diğerine uyup uymadığını kontrol ederiz. Örneğin [0,2,2], [2,2,0]: Her iki uzunluğu 3 ve [0,2,2,0,2,2]içeren [2,2,0]sürekli bir alt dizisini olarak. Kusursuz olup olmadığından emin değilim ama işe yarıyor gibi görünüyor.

EDIT: Laikoni'ye 5 bayt ayırdığı için teşekkürler! Bu ipuçlarından daha fazlasını okumalıydım.


1
Önlemek için bu ipucunu kullanabileceğiniz anlaşılıyor length. Başka bayt kaydedilebilir !ile |r<-p++[a]=r!b.
Laikoni

0

JavaScript (ES6), 337 335 bayt

Ω (k ^ 3) kaba kuvvet algoritması için özür dileriz.

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

Performans ... A015134 (k = 50'nin ötesinde bir şey) hesaplarken TIO'daki 60'ların sınırını aştı.

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

Açıklama (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 bayt

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

Sonucu döndüren bir işlev döndürür. 3 bayt için sonucu doğrudan geri getirebiliriz:

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)

Hem zaman karmaşıklığı O (n sahip 2 ).


0

Python 2 , 214 bayt

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)

Çevrimiçi deneyin!

Çok verimli değil ama yapabileceğim en golfi.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.