Pisano period: Difference between revisions

m (→‎{{header|Sidef}}: added zkl header)
(→‎{{header|zkl}}: added code)
Line 725:
 
=={{header|zkl}}==
{{libheader|GMP}} GNU Multiple Precision Arithmetic Library for prime testing
<lang zkl></lang>
<lang zkl>var [const] BI=Import("zklBigNum"); // libGMP
<lang zkl></lang>
 
fcn pisanoPeriod(p){
if(p<2) return(0);
lastn,n,t := 0,1,0;
foreach i in ([0..p*p]){
t,n,lastn = n, (lastn + n) % p, t;
if(lastn==0 and n==1) return(i + 1);
}
1
}
fcn pisanoPrime(p,k){
_assert_(BI(p).probablyPrime(), "%s is not a prime number".fmt(p));
pisanoPeriod(p.pow(k))
<lang zkl>}</lang>
<lang zkl>println("Pisano period (p, 2) for primes less than 50:");
[1..50].pump(List,BI,"probablyPrime",Void.Filter, pisanoPrime.fp1(2))
.concat(" "," ").println();
 
println("Pisano period (p, 1) for primes less than 180:");
[1..180].pump(List,BI,"probablyPrime",Void.Filter, pisanoPrime.fp1(1))
.pump(Void,T(Void.Read,14,False),fcn{ vm.arglist.apply("%4d".fmt).concat().println() });</lang>
{{out}}
<pre>
Pisano period (p, 2) for primes less than 50:
6 24 100 112 110 364 612 342 1104 406 930 2812 1640 3784 1504
Pisano period (p, 1) for primes less than 180:
3 8 20 16 10 28 36 18 48 14 30 76 40 88 32
108 58 60 136 70 148 78 168 44 196 50 208 72 108 76
256 130 276 46 148 50 316 328 336 348 178
</pre>
<lang zkl></lang>fcn pisano(m){
primeFactors(m).pump(Dictionary().incV) //18 --> (2,3,3) --> ("2":1, "3":2)
.reduce(fcn(z,[(k,v])){ lcm(z,pisanoPrime(k.toInt(),v)) },1)
}
 
fcn lcm(a,b){ a / a.gcd(b) * b }
fcn primeFactors(n){ // Return a list of prime factors of n
acc:=fcn(n,k,acc,maxD){ // k is 2,3,5,7,9,... not optimum
if(n==1 or k>maxD) acc.close();
else{
q,r:=n.divr(k); // divr-->(quotient,remainder)
if(r==0) return(self.fcn(q,k,acc.write(k),q.toFloat().sqrt()));
return(self.fcn(n,k+1+k.isOdd,acc,maxD)) # both are tail recursion
}
}(n,2,Sink(List),n.toFloat().sqrt());
m:=acc.reduce('*,1); // mulitply factors
if(n!=m) acc.append(n/m); // opps, missed last factor
else acc;
}</lang>
<lang zkl>println("Pisano(m) for integers 2 to 180:");
[2..180].pump(List, pisano, "%4d".fmt)
.pump(Void,T(Void.Read,14,False),fcn{ vm.arglist.concat().println() });</lang>
{{out}}
<pre>
Pisano(m) for integers 2 to 180:
3 8 6 20 24 16 12 24 60 10 24 28 48 40 24
36 24 18 60 16 30 48 24 100 84 72 48 14 120 30
48 40 36 80 24 76 18 56 60 40 48 88 30 120 48
32 24 112 300 72 84 108 72 20 48 72 42 58 120 60
30 48 96 140 120 136 36 48 240 70 24 148 228 200 18
80 168 78 120 216 120 168 48 180 264 56 60 44 120 112
48 120 96 180 48 196 336 120 300 50 72 208 84 80 108
72 72 108 60 152 48 76 72 240 42 168 174 144 120 110
60 40 30 500 48 256 192 88 420 130 120 144 408 360 36
276 48 46 240 32 210 140 24 140 444 112 228 148 600 50
36 72 240 60 168 316 78 216 240 48 216 328 120 40 168
336 48 364 180 72 264 348 168 400 120 232 132 178 120
</pre>
Anonymous user