Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
5
Task/Pisano-period/00-META.yaml
Normal file
5
Task/Pisano-period/00-META.yaml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
category:
|
||||
- Mathematics
|
||||
from: http://rosettacode.org/wiki/Pisano_period
|
||||
note: Prime Numbers
|
||||
37
Task/Pisano-period/00-TASK.txt
Normal file
37
Task/Pisano-period/00-TASK.txt
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
The [[wp:Fibonacci_Number|Fibonacci sequence]] taken modulo 2 is a periodic sequence of period 3 : 0, 1, 1, 0, 1, 1, ...
|
||||
|
||||
For any integer n, the Fibonacci sequence taken modulo n is periodic and the length of the periodic cycle is referred to as the [[wp:Pisano_period|Pisano period]].
|
||||
|
||||
Prime numbers are straightforward; the Pisano period of a prime number '''p''' is simply: '''pisano(p)'''. The Pisano period of a composite number '''c''' may be found in different ways. It may be calculated directly: '''pisano(c)''', which works, but may be time consuming to find, especially for larger integers, or, it may be calculated by finding the [[wp:Least common multiple|least common multiple]] of the Pisano periods of each composite component.
|
||||
|
||||
|
||||
;E.G.:
|
||||
Given a Pisano period function: pisano(x), and a least common multiple function lcm(x, y):
|
||||
<big>'''pisano(m × n)''' is equivalent to '''lcm(pisano(m), pisano(n))''' where '''m''' and '''n''' are '''[[wp:Coprime|coprime]]'''</big>
|
||||
A formulae to calculate the pisano period for integer powers '''k''' of prime numbers '''p''' is:
|
||||
<big>'''pisano(p<sup>k</sup>) == p<sup>(k-1)</sup>pisano(p)''' </big>
|
||||
The equation is conjectured, no exceptions have been seen.
|
||||
|
||||
If a positive integer '''i''' is split into its prime factors, then the second and first equations above can be applied to generate the pisano period.
|
||||
|
||||
|
||||
;Task
|
||||
Write 2 functions: pisanoPrime(p,k) and pisano(m).
|
||||
|
||||
pisanoPrime(p,k) should return the Pisano period of p<sup>k</sup> where p is prime and k is a positive integer.
|
||||
|
||||
pisano(m) should use pisanoPrime to return the Pisano period of m where m is a positive integer.
|
||||
|
||||
Print pisanoPrime(p,2) for every prime lower than 15.
|
||||
|
||||
Print pisanoPrime(p,1) for every prime lower than 180.
|
||||
|
||||
Print pisano(m) for every integer from 1 to 180.
|
||||
|
||||
|
||||
;Related tasks
|
||||
* [[Fibonacci sequence]]
|
||||
* [[Prime decomposition]]
|
||||
* [[Least common multiple]]
|
||||
<br><br>
|
||||
|
||||
68
Task/Pisano-period/11l/pisano-period.11l
Normal file
68
Task/Pisano-period/11l/pisano-period.11l
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
F lcm(m, n)
|
||||
R m I/ gcd(m, n) * n
|
||||
|
||||
F get_primes(=n)
|
||||
[Int] r
|
||||
L(d) 2 .. n
|
||||
V q = n I/ d
|
||||
V m = n % d
|
||||
L m == 0
|
||||
r.append(d)
|
||||
n = q
|
||||
q = n I/ d
|
||||
m = n % d
|
||||
R r
|
||||
|
||||
F is_prime(a)
|
||||
I a == 2
|
||||
R 1B
|
||||
I a < 2 | a % 2 == 0
|
||||
R 0B
|
||||
L(i) (3 .. Int(sqrt(a))).step(2)
|
||||
I a % i == 0
|
||||
R 0B
|
||||
R 1B
|
||||
|
||||
F pisano_period(m)
|
||||
V p = 0
|
||||
V c = 1
|
||||
L(i) 0 .< m * m
|
||||
p = (p + c) % m
|
||||
swap(&p, &c)
|
||||
I p == 0 & c == 1
|
||||
R i + 1
|
||||
R 1
|
||||
|
||||
F pisano_prime(p, k)
|
||||
R I is_prime(p) {p ^ (k - 1) * pisano_period(p)} E 0
|
||||
|
||||
F pisano(m)
|
||||
V primes = get_primes(m)
|
||||
DefaultDict[Int, Int] prime_powers
|
||||
L(p) primes
|
||||
prime_powers[p]++
|
||||
[Int] pps
|
||||
L(k, v) prime_powers
|
||||
pps.append(pisano_prime(k, v))
|
||||
I pps.empty
|
||||
R 1
|
||||
V result = pps[0]
|
||||
L(i) 1 .< pps.len
|
||||
result = lcm(result, pps[i])
|
||||
R result
|
||||
|
||||
L(p) 2..14
|
||||
V pp = pisano_prime(p, 2)
|
||||
I pp > 0
|
||||
print(‘pisano_prime(#2, 2) = #.’.format(p, pp))
|
||||
|
||||
print()
|
||||
L(p) 2..179
|
||||
V pp = pisano_prime(p, 1)
|
||||
I pp > 0
|
||||
print(‘pisano_prime(#3, 1) = #.’.format(p, pp))
|
||||
|
||||
print()
|
||||
print(‘pisano(n) for integers 'n' from 1 to 180 are:’)
|
||||
L(n) 1..180
|
||||
print(‘#3’.format(pisano(n)), end' I n % 15 == 0 {"\n"} E ‘ ’)
|
||||
26
Task/Pisano-period/Factor/pisano-period.factor
Normal file
26
Task/Pisano-period/Factor/pisano-period.factor
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
USING: formatting fry grouping io kernel math math.functions
|
||||
math.primes math.primes.factors math.ranges sequences ;
|
||||
|
||||
: pisano-period ( m -- n )
|
||||
[ 0 1 ] dip [ sq <iota> ] [ ] bi
|
||||
'[ drop tuck + _ mod 2dup [ zero? ] [ 1 = ] bi* and ]
|
||||
find 3nip [ 1 + ] [ 1 ] if* ;
|
||||
|
||||
: pisano-prime ( p k -- n )
|
||||
over prime? [ "p must be prime." throw ] unless
|
||||
^ pisano-period ;
|
||||
|
||||
: pisano ( m -- n )
|
||||
group-factors [ first2 pisano-prime ] [ lcm ] map-reduce ;
|
||||
|
||||
: show-pisano ( upto m -- )
|
||||
[ primes-upto ] dip
|
||||
[ 2dup pisano-prime "%d %d pisano-prime = %d\n" printf ]
|
||||
curry each nl ;
|
||||
|
||||
15 2 show-pisano
|
||||
180 1 show-pisano
|
||||
|
||||
"n pisano for integers 'n' from 2 to 180:" print
|
||||
2 180 [a,b] [ pisano ] map 15 group
|
||||
[ [ "%3d " printf ] each nl ] each
|
||||
136
Task/Pisano-period/Go/pisano-period.go
Normal file
136
Task/Pisano-period/Go/pisano-period.go
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func gcd(a, b uint) uint {
|
||||
if b == 0 {
|
||||
return a
|
||||
}
|
||||
return gcd(b, a%b)
|
||||
}
|
||||
|
||||
func lcm(a, b uint) uint {
|
||||
return a / gcd(a, b) * b
|
||||
}
|
||||
|
||||
func ipow(x, p uint) uint {
|
||||
prod := uint(1)
|
||||
for p > 0 {
|
||||
if p&1 != 0 {
|
||||
prod *= x
|
||||
}
|
||||
p >>= 1
|
||||
x *= x
|
||||
}
|
||||
return prod
|
||||
}
|
||||
|
||||
// Gets the prime decomposition of n.
|
||||
func getPrimes(n uint) []uint {
|
||||
var primes []uint
|
||||
for i := uint(2); i <= n; i++ {
|
||||
div := n / i
|
||||
mod := n % i
|
||||
for mod == 0 {
|
||||
primes = append(primes, i)
|
||||
n = div
|
||||
div = n / i
|
||||
mod = n % i
|
||||
}
|
||||
}
|
||||
return primes
|
||||
}
|
||||
|
||||
// OK for 'small' numbers.
|
||||
func isPrime(n uint) bool {
|
||||
switch {
|
||||
case n < 2:
|
||||
return false
|
||||
case n%2 == 0:
|
||||
return n == 2
|
||||
case n%3 == 0:
|
||||
return n == 3
|
||||
default:
|
||||
d := uint(5)
|
||||
for d*d <= n {
|
||||
if n%d == 0 {
|
||||
return false
|
||||
}
|
||||
d += 2
|
||||
if n%d == 0 {
|
||||
return false
|
||||
}
|
||||
d += 4
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// Calculates the Pisano period of 'm' from first principles.
|
||||
func pisanoPeriod(m uint) uint {
|
||||
var p, c uint = 0, 1
|
||||
for i := uint(0); i < m*m; i++ {
|
||||
p, c = c, (p+c)%m
|
||||
if p == 0 && c == 1 {
|
||||
return i + 1
|
||||
}
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
// Calculates the Pisano period of p^k where 'p' is prime and 'k' is a positive integer.
|
||||
func pisanoPrime(p uint, k uint) uint {
|
||||
if !isPrime(p) || k == 0 {
|
||||
return 0 // can't do this one
|
||||
}
|
||||
return ipow(p, k-1) * pisanoPeriod(p)
|
||||
}
|
||||
|
||||
// Calculates the Pisano period of 'm' using pisanoPrime.
|
||||
func pisano(m uint) uint {
|
||||
primes := getPrimes(m)
|
||||
primePowers := make(map[uint]uint)
|
||||
for _, p := range primes {
|
||||
primePowers[p]++
|
||||
}
|
||||
var pps []uint
|
||||
for k, v := range primePowers {
|
||||
pps = append(pps, pisanoPrime(k, v))
|
||||
}
|
||||
if len(pps) == 0 {
|
||||
return 1
|
||||
}
|
||||
if len(pps) == 1 {
|
||||
return pps[0]
|
||||
}
|
||||
f := pps[0]
|
||||
for i := 1; i < len(pps); i++ {
|
||||
f = lcm(f, pps[i])
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
func main() {
|
||||
for p := uint(2); p < 15; p++ {
|
||||
pp := pisanoPrime(p, 2)
|
||||
if pp > 0 {
|
||||
fmt.Printf("pisanoPrime(%2d: 2) = %d\n", p, pp)
|
||||
}
|
||||
}
|
||||
fmt.Println()
|
||||
for p := uint(2); p < 180; p++ {
|
||||
pp := pisanoPrime(p, 1)
|
||||
if pp > 0 {
|
||||
fmt.Printf("pisanoPrime(%3d: 1) = %d\n", p, pp)
|
||||
}
|
||||
}
|
||||
fmt.Println()
|
||||
fmt.Println("pisano(n) for integers 'n' from 1 to 180 are:")
|
||||
for n := uint(1); n <= 180; n++ {
|
||||
fmt.Printf("%3d ", pisano(n))
|
||||
if n != 1 && n%15 == 0 {
|
||||
fmt.Println()
|
||||
}
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
155
Task/Pisano-period/Haskell/pisano-period.hs
Normal file
155
Task/Pisano-period/Haskell/pisano-period.hs
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
import qualified Data.Text as T
|
||||
|
||||
main = do
|
||||
putStrLn "PisanoPrime(p,2) for prime p lower than 15"
|
||||
putStrLn . see 15 . map (`pisanoPrime` 2) . filter isPrime $ [1 .. 15]
|
||||
putStrLn "PisanoPrime(p,1) for prime p lower than 180"
|
||||
putStrLn . see 15 . map (`pisanoPrime` 1) . filter isPrime $ [1 .. 180]
|
||||
let ns = [1 .. 180] :: [Int]
|
||||
let xs = map pisanoPeriod ns
|
||||
let ys = map pisano ns
|
||||
let zs = map pisanoConjecture ns
|
||||
putStrLn "Pisano(m) for m from 1 to 180"
|
||||
putStrLn . see 15 $ map pisano [1 .. 180]
|
||||
putStrLn $
|
||||
"map pisanoPeriod [1..180] == map pisano [1..180] = " ++ show (xs == ys)
|
||||
putStrLn $
|
||||
"map pisanoPeriod [1..180] == map pisanoConjecture [1..180] = " ++
|
||||
show (ys == zs)
|
||||
|
||||
bagOf :: Int -> [a] -> [[a]]
|
||||
bagOf _ [] = []
|
||||
bagOf n xs =
|
||||
let (us, vs) = splitAt n xs
|
||||
in us : bagOf n vs
|
||||
|
||||
see
|
||||
:: Show a
|
||||
=> Int -> [a] -> String
|
||||
see n =
|
||||
unlines .
|
||||
map unwords . bagOf n . map (T.unpack . T.justifyRight 3 ' ' . T.pack . show)
|
||||
|
||||
fibMod
|
||||
:: Integral a
|
||||
=> a -> [a]
|
||||
fibMod 1 = repeat 0
|
||||
fibMod n = fib
|
||||
where
|
||||
fib = 0 : 1 : zipWith (\x y -> rem (x + y) n) fib (tail fib)
|
||||
|
||||
pisanoPeriod
|
||||
:: Integral a
|
||||
=> a -> a
|
||||
pisanoPeriod m
|
||||
| m <= 0 = 0
|
||||
pisanoPeriod 1 = 1
|
||||
pisanoPeriod m = go 1 (tail $ fibMod m)
|
||||
where
|
||||
go t (0:1:_) = t
|
||||
go t (_:xs) = go (succ t) xs
|
||||
|
||||
powMod
|
||||
:: Integral a
|
||||
=> a -> a -> a -> a
|
||||
powMod _ _ k
|
||||
| k < 0 = error "negative power"
|
||||
powMod m _ _
|
||||
| 1 == abs m = 0
|
||||
powMod m p k
|
||||
| 1 == abs p = mod v m
|
||||
where
|
||||
v
|
||||
| 1 == p || even k = 1
|
||||
| otherwise = p
|
||||
powMod m p k = go p k
|
||||
where
|
||||
to x y = mod (x * y) m
|
||||
go _ 0 = 1
|
||||
go u 1 = mod u m
|
||||
go u i
|
||||
| even i = to w w
|
||||
| otherwise = to u (to w w)
|
||||
where
|
||||
w = go u (quot i 2)
|
||||
|
||||
-- Fermat primality test
|
||||
probablyPrime
|
||||
:: Integral a
|
||||
=> a -> Bool
|
||||
probablyPrime p
|
||||
| p < 2 || even p = 2 == p
|
||||
| otherwise = 1 == powMod p 2 (p - 1)
|
||||
|
||||
primes
|
||||
:: Integral a
|
||||
=> [a]
|
||||
primes =
|
||||
2 :
|
||||
3 :
|
||||
5 :
|
||||
7 :
|
||||
[ p
|
||||
| p <- [11,13 ..]
|
||||
, isPrime p ]
|
||||
|
||||
limitDivisor
|
||||
:: Integral a
|
||||
=> a -> a
|
||||
limitDivisor = floor . (+ 0.05) . sqrt . fromIntegral
|
||||
|
||||
isPrime
|
||||
:: Integral a
|
||||
=> a -> Bool
|
||||
isPrime p
|
||||
| not $ probablyPrime p = False
|
||||
isPrime p = go primes
|
||||
where
|
||||
stop = limitDivisor p
|
||||
go (n:_)
|
||||
| stop < n = True
|
||||
go (n:ns) = (0 /= rem p n) && go ns
|
||||
go [] = True
|
||||
|
||||
factor
|
||||
:: Integral a
|
||||
=> a -> [(a, a)]
|
||||
factor n
|
||||
| n <= 1 = []
|
||||
factor n = go n primes
|
||||
where
|
||||
fun x d c
|
||||
| 0 /= rem x d = (x, c)
|
||||
| otherwise = fun (quot x d) d (succ c)
|
||||
go 1 _ = []
|
||||
go _ [] = []
|
||||
go x (d:ds)
|
||||
| 0 /= rem x d = go x $ dropWhile ((0 /=) . rem x) ds
|
||||
go x (d:ds) =
|
||||
let (u, c) = fun (quot x d) d 1
|
||||
in (d, c) : go u ds
|
||||
|
||||
pisanoPrime
|
||||
:: Integral a
|
||||
=> a -> a -> a
|
||||
pisanoPrime p k
|
||||
| p <= 0 || k < 0 = 0
|
||||
pisanoPrime p k = pisanoPeriod $ p ^ k
|
||||
|
||||
pisano
|
||||
:: Integral a
|
||||
=> a -> a
|
||||
pisano m
|
||||
| m < 1 = 0
|
||||
pisano 1 = 1
|
||||
pisano m = foldl1 lcm . map (uncurry pisanoPrime) $ factor m
|
||||
|
||||
pisanoConjecture
|
||||
:: Integral a
|
||||
=> a -> a
|
||||
pisanoConjecture m
|
||||
| m < 1 = 0
|
||||
pisanoConjecture 1 = 1
|
||||
pisanoConjecture m = foldl1 lcm . map (uncurry pisanoPrime') $ factor m
|
||||
where
|
||||
pisanoPrime' p k = (p ^ (k - 1)) * pisanoPeriod p
|
||||
263
Task/Pisano-period/Java/pisano-period.java
Normal file
263
Task/Pisano-period/Java/pisano-period.java
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class PisanoPeriod {
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.printf("Print pisano(p^2) for every prime p lower than 15%n");
|
||||
for ( long i = 2 ; i < 15 ; i++ ) {
|
||||
if ( isPrime(i) ) {
|
||||
long n = i*i;
|
||||
System.out.printf("pisano(%d) = %d%n", n, pisano(n));
|
||||
}
|
||||
}
|
||||
|
||||
System.out.printf("%nPrint pisano(p) for every prime p lower than 180%n");
|
||||
for ( long n = 2 ; n < 180 ; n++ ) {
|
||||
if ( isPrime(n) ) {
|
||||
System.out.printf("pisano(%d) = %d%n", n, pisano(n));
|
||||
}
|
||||
}
|
||||
|
||||
System.out.printf("%nPrint pisano(n) for every integer from 1 to 180%n");
|
||||
for ( long n = 1 ; n <= 180 ; n++ ) {
|
||||
System.out.printf("%3d ", pisano(n));
|
||||
if ( n % 10 == 0 ) {
|
||||
System.out.printf("%n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static final boolean isPrime(long test) {
|
||||
if ( test == 2 ) {
|
||||
return true;
|
||||
}
|
||||
if ( test % 2 == 0 ) {
|
||||
return false;
|
||||
}
|
||||
for ( long i = 3 ; i <= Math.sqrt(test) ; i += 2 ) {
|
||||
if ( test % i == 0 ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private static Map<Long,Long> PERIOD_MEMO = new HashMap<>();
|
||||
static {
|
||||
PERIOD_MEMO.put(2L, 3L);
|
||||
PERIOD_MEMO.put(3L, 8L);
|
||||
PERIOD_MEMO.put(5L, 20L);
|
||||
}
|
||||
|
||||
// See http://webspace.ship.edu/msrenault/fibonacci/fib.htm
|
||||
private static long pisano(long n) {
|
||||
if ( PERIOD_MEMO.containsKey(n) ) {
|
||||
return PERIOD_MEMO.get(n);
|
||||
}
|
||||
if ( n == 1 ) {
|
||||
return 1;
|
||||
}
|
||||
Map<Long,Long> factors = getFactors(n);
|
||||
|
||||
// Special cases
|
||||
// pisano(2^k) = 3*n/2
|
||||
if ( factors.size() == 1 & factors.get(2L) != null && factors.get(2L) > 0 ) {
|
||||
long result = 3 * n / 2;
|
||||
PERIOD_MEMO.put(n, result);
|
||||
return result;
|
||||
}
|
||||
// pisano(5^k) = 4*n
|
||||
if ( factors.size() == 1 & factors.get(5L) != null && factors.get(5L) > 0 ) {
|
||||
long result = 4*n;
|
||||
PERIOD_MEMO.put(n, result);
|
||||
return result;
|
||||
}
|
||||
// pisano(2*5^k) = 6*n
|
||||
if ( factors.size() == 2 & factors.get(2L) != null && factors.get(2L) == 1 && factors.get(5L) != null && factors.get(5L) > 0 ) {
|
||||
long result = 6*n;
|
||||
PERIOD_MEMO.put(n, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
List<Long> primes = new ArrayList<>(factors.keySet());
|
||||
long prime = primes.get(0);
|
||||
if ( factors.size() == 1 && factors.get(prime) == 1 ) {
|
||||
List<Long> divisors = new ArrayList<>();
|
||||
if ( n % 10 == 1 || n % 10 == 9 ) {
|
||||
for ( long divisor : getDivisors(prime-1) ) {
|
||||
if ( divisor % 2 == 0 ) {
|
||||
divisors.add(divisor);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
List<Long> pPlus1Divisors = getDivisors(prime+1);
|
||||
for ( long divisor : getDivisors(2*prime+2) ) {
|
||||
if ( ! pPlus1Divisors.contains(divisor) ) {
|
||||
divisors.add(divisor);
|
||||
}
|
||||
}
|
||||
}
|
||||
Collections.sort(divisors);
|
||||
for ( long divisor : divisors ) {
|
||||
if ( fibModIdentity(divisor, prime) ) {
|
||||
PERIOD_MEMO.put(prime, divisor);
|
||||
return divisor;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("ERROR 144: Divisor not found.");
|
||||
}
|
||||
long period = (long) Math.pow(prime, factors.get(prime)-1) * pisano(prime);
|
||||
for ( int i = 1 ; i < primes.size() ; i++ ) {
|
||||
prime = primes.get(i);
|
||||
period = lcm(period, (long) Math.pow(prime, factors.get(prime)-1) * pisano(prime));
|
||||
}
|
||||
PERIOD_MEMO.put(n, period);
|
||||
return period;
|
||||
}
|
||||
|
||||
// Use Matrix multiplication to compute Fibonacci numbers.
|
||||
private static boolean fibModIdentity(long n, long mod) {
|
||||
long aRes = 0;
|
||||
long bRes = 1;
|
||||
long cRes = 1;
|
||||
long aBase = 0;
|
||||
long bBase = 1;
|
||||
long cBase = 1;
|
||||
while ( n > 0 ) {
|
||||
if ( n % 2 == 1 ) {
|
||||
long temp1 = 0, temp2 = 0, temp3 = 0;
|
||||
if ( aRes > SQRT || aBase > SQRT || bRes > SQRT || bBase > SQRT || cBase > SQRT || cRes > SQRT ) {
|
||||
temp1 = (multiply(aRes, aBase, mod) + multiply(bRes, bBase, mod)) % mod;
|
||||
temp2 = (multiply(aBase, bRes, mod) + multiply(bBase, cRes, mod)) % mod;
|
||||
temp3 = (multiply(bBase, bRes, mod) + multiply(cBase, cRes, mod)) % mod;
|
||||
}
|
||||
else {
|
||||
temp1 = ((aRes*aBase % mod) + (bRes*bBase % mod)) % mod;
|
||||
temp2 = ((aBase*bRes % mod) + (bBase*cRes % mod)) % mod;
|
||||
temp3 = ((bBase*bRes % mod) + (cBase*cRes % mod)) % mod;
|
||||
}
|
||||
aRes = temp1;
|
||||
bRes = temp2;
|
||||
cRes = temp3;
|
||||
}
|
||||
n >>= 1L;
|
||||
long temp1 = 0, temp2 = 0, temp3 = 0;
|
||||
if ( aBase > SQRT || bBase > SQRT || cBase > SQRT ) {
|
||||
temp1 = (multiply(aBase, aBase, mod) + multiply(bBase, bBase, mod)) % mod;
|
||||
temp2 = (multiply(aBase, bBase, mod) + multiply(bBase, cBase, mod)) % mod;
|
||||
temp3 = (multiply(bBase, bBase, mod) + multiply(cBase, cBase, mod)) % mod;
|
||||
}
|
||||
else {
|
||||
temp1 = ((aBase*aBase % mod) + (bBase*bBase % mod)) % mod;
|
||||
temp2 = ((aBase*bBase % mod) + (bBase*cBase % mod)) % mod;
|
||||
temp3 = ((bBase*bBase % mod) + (cBase*cBase % mod)) % mod;
|
||||
}
|
||||
aBase = temp1;
|
||||
bBase = temp2;
|
||||
cBase = temp3;
|
||||
}
|
||||
return aRes % mod == 0 && bRes % mod == 1 && cRes % mod == 1;
|
||||
}
|
||||
|
||||
private static final long SQRT = (long) Math.sqrt(Long.MAX_VALUE);
|
||||
|
||||
// Result is a*b % mod, without overflow.
|
||||
public static final long multiply(long a, long b, long modulus) {
|
||||
//System.out.println(" multiply : a = " + a + ", b = " + b + ", mod = " + modulus);
|
||||
long x = 0;
|
||||
long y = a % modulus;
|
||||
long t;
|
||||
while ( b > 0 ) {
|
||||
if ( b % 2 == 1 ) {
|
||||
t = x + y;
|
||||
x = (t > modulus ? t-modulus : t);
|
||||
}
|
||||
t = y << 1;
|
||||
y = (t > modulus ? t-modulus : t);
|
||||
b >>= 1;
|
||||
}
|
||||
//System.out.println(" multiply : answer = " + (x % modulus));
|
||||
return x % modulus;
|
||||
}
|
||||
|
||||
private static final List<Long> getDivisors(long number) {
|
||||
List<Long> divisors = new ArrayList<>();
|
||||
long sqrt = (long) Math.sqrt(number);
|
||||
for ( long i = 1 ; i <= sqrt ; i++ ) {
|
||||
if ( number % i == 0 ) {
|
||||
divisors.add(i);
|
||||
long div = number / i;
|
||||
if ( div != i ) {
|
||||
divisors.add(div);
|
||||
}
|
||||
}
|
||||
}
|
||||
return divisors;
|
||||
}
|
||||
|
||||
public static long lcm(long a, long b) {
|
||||
return a*b/gcd(a,b);
|
||||
}
|
||||
|
||||
public static long gcd(long a, long b) {
|
||||
if ( b == 0 ) {
|
||||
return a;
|
||||
}
|
||||
return gcd(b, a%b);
|
||||
}
|
||||
|
||||
private static final Map<Long,Map<Long,Long>> allFactors = new TreeMap<Long,Map<Long,Long>>();
|
||||
static {
|
||||
Map<Long,Long> factors = new TreeMap<Long,Long>();
|
||||
factors.put(2L, 1L);
|
||||
allFactors.put(2L, factors);
|
||||
}
|
||||
|
||||
public static Long MAX_ALL_FACTORS = 100000L;
|
||||
|
||||
public static final Map<Long,Long> getFactors(Long number) {
|
||||
if ( allFactors.containsKey(number) ) {
|
||||
return allFactors.get(number);
|
||||
}
|
||||
Map<Long,Long> factors = new TreeMap<Long,Long>();
|
||||
if ( number % 2 == 0 ) {
|
||||
Map<Long,Long> factorsdDivTwo = getFactors(number/2);
|
||||
factors.putAll(factorsdDivTwo);
|
||||
factors.merge(2L, 1L, (v1, v2) -> v1 + v2);
|
||||
if ( number < MAX_ALL_FACTORS ) {
|
||||
allFactors.put(number, factors);
|
||||
}
|
||||
return factors;
|
||||
}
|
||||
boolean prime = true;
|
||||
long sqrt = (long) Math.sqrt(number);
|
||||
for ( long i = 3 ; i <= sqrt ; i += 2 ) {
|
||||
if ( number % i == 0 ) {
|
||||
prime = false;
|
||||
factors.putAll(getFactors(number/i));
|
||||
factors.merge(i, 1L, (v1, v2) -> v1 + v2);
|
||||
if ( number < MAX_ALL_FACTORS ) {
|
||||
allFactors.put(number, factors);
|
||||
}
|
||||
return factors;
|
||||
}
|
||||
}
|
||||
if ( prime ) {
|
||||
factors.put(number, 1L);
|
||||
if ( number < MAX_ALL_FACTORS ) {
|
||||
allFactors.put(number, factors);
|
||||
}
|
||||
}
|
||||
return factors;
|
||||
}
|
||||
|
||||
}
|
||||
34
Task/Pisano-period/Julia/pisano-period.julia
Normal file
34
Task/Pisano-period/Julia/pisano-period.julia
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
using Primes
|
||||
|
||||
const pisanos = Dict{Int, Int}()
|
||||
function pisano(p)
|
||||
p < 2 && return 1
|
||||
(i = get(pisanos, p, 0)) > 0 && return i
|
||||
lastn, n = 0, 1
|
||||
for i in 1:p^2
|
||||
lastn, n = n, (lastn + n) % p
|
||||
if lastn == 0 && n == 1
|
||||
pisanos[p] = i
|
||||
return i
|
||||
end
|
||||
end
|
||||
return 1
|
||||
end
|
||||
|
||||
pisanoprime(p, k) = (@assert(isprime(p)); p^(k-1) * pisano(p))
|
||||
pisanotask(n) = mapreduce(p -> pisanoprime(p[1], p[2]), lcm, collect(factor(n)), init=1)
|
||||
|
||||
for i in 1:15
|
||||
if isprime(i)
|
||||
println("pisanoPrime($i, 2) = ", pisanoprime(i, 2))
|
||||
end
|
||||
end
|
||||
|
||||
for i in 1:180
|
||||
if isprime(i)
|
||||
println("pisanoPrime($i, 1) = ", pisanoprime(i, 1))
|
||||
end
|
||||
end
|
||||
|
||||
println("\nPisano(n) for n from 2 to 180:\n", [pisano(i) for i in 2:180])
|
||||
println("\nPisano(n) using pisanoPrime for n from 2 to 180:\n", [pisanotask(i) for i in 2:180])
|
||||
71
Task/Pisano-period/Nim/pisano-period.nim
Normal file
71
Task/Pisano-period/Nim/pisano-period.nim
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
import math, strformat, tables
|
||||
|
||||
func primes(n: Positive): seq[int] =
|
||||
## Return the list of prime divisors of "n".
|
||||
var n = n.int
|
||||
for d in 2..n:
|
||||
var q = n div d
|
||||
var m = n mod d
|
||||
while m == 0:
|
||||
result.add d
|
||||
n = q
|
||||
q = n div d
|
||||
m = n mod d
|
||||
|
||||
func isPrime(n: Positive): bool =
|
||||
## Return true if "n" is prime.
|
||||
if n < 2: return false
|
||||
if n mod 2 == 0: return n == 2
|
||||
if n mod 3 == 0: return n == 3
|
||||
var d = 5
|
||||
while d <= sqrt(n.toFloat).int:
|
||||
if n mod d == 0: return false
|
||||
inc d, 2
|
||||
if n mod d == 0: return false
|
||||
inc d, 4
|
||||
result = true
|
||||
|
||||
func pisanoPeriod(m: Positive): int =
|
||||
## Calculate the Pisano period of 'm' from first principles.
|
||||
var p = 0
|
||||
var c = 1
|
||||
for i in 0..<m*m:
|
||||
p = (p + c) mod m
|
||||
swap p, c
|
||||
if p == 0 and c == 1: return i + 1
|
||||
result = 1
|
||||
|
||||
func pisanoPrime(p, k: Positive): int =
|
||||
## Calculate the Pisano period of p^k where 'p' is prime and 'k' is a positive integer.
|
||||
if p.isPrime: p^(k-1) * p.pisanoPeriod() else: 0
|
||||
|
||||
func pisano(m: Positive): int =
|
||||
## Calculate the Pisano period of 'm' using pisanoPrime.
|
||||
let primes = m.primes
|
||||
var primePowers = primes.toCountTable
|
||||
var pps: seq[int]
|
||||
for k, v in primePowers.pairs:
|
||||
pps.add pisanoPrime(k, v)
|
||||
if pps.len == 0: return 1
|
||||
result = pps[0]
|
||||
for i in 1..pps.high:
|
||||
result = lcm(result, pps[i])
|
||||
|
||||
|
||||
when isMainModule:
|
||||
|
||||
for p in 2..14:
|
||||
let pp = pisanoPrime(p, 2)
|
||||
if pp > 0:
|
||||
echo &"pisanoPrime({p:2}, 2) = {pp}"
|
||||
|
||||
echo()
|
||||
for p in 2..179:
|
||||
let pp = pisanoPrime(p, 1)
|
||||
if pp > 0:
|
||||
echo &"pisanoPrime({p:3}, 1) = {pp}"
|
||||
|
||||
echo()
|
||||
echo "pisano(n) for integers 'n' from 1 to 180 are:"
|
||||
for n in 1..180:
|
||||
stdout.write &"{pisano(n):3}", if n mod 15 == 0: '\n' else: ' '
|
||||
22
Task/Pisano-period/Perl/pisano-period.pl
Normal file
22
Task/Pisano-period/Perl/pisano-period.pl
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
use strict;
|
||||
use warnings;
|
||||
use feature 'say';
|
||||
use ntheory qw(primes factor_exp lcm);
|
||||
|
||||
sub pisano_period_pp {
|
||||
my($a, $b, $n, $k) = (0, 1, $_[0]**$_[1]);
|
||||
while (++$k) {
|
||||
($a, $b) = ($b, ($a+$b) % $n);
|
||||
return $k if $a == 0 and $b == 1;
|
||||
}
|
||||
}
|
||||
|
||||
sub pisano_period {
|
||||
(lcm map { pisano_period_pp($$_[0],$$_[1]) } factor_exp($_[0])) or 1;
|
||||
}
|
||||
|
||||
sub display { (sprintf "@{['%5d' x @_]}", @_) =~ s/(.{75})/$1\n/gr }
|
||||
|
||||
say "Pisano periods for squares of primes p <= 50:\n", display( map { pisano_period_pp($_, 2) } @{primes(1, 50)} ),
|
||||
"\nPisano periods for primes p <= 180:\n", display( map { pisano_period_pp($_, 1) } @{primes(1, 180)} ),
|
||||
"\n\nPisano periods for integers n from 1 to 180:\n", display( map { pisano_period ($_ ) } 1..180 );
|
||||
60
Task/Pisano-period/Phix/pisano-period.phix
Normal file
60
Task/Pisano-period/Phix/pisano-period.phix
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">pisano_period</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000080;font-style:italic;">-- Calculates the Pisano period of 'm' from first principles. (copied from Go)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">*</span><span style="color: #000000;">m</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">+</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">m</span><span style="color: #0000FF;">)}</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">p</span> <span style="color: #0000FF;">==</span> <span style="color: #000000;">0</span> <span style="color: #008080;">and</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">==</span> <span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">i</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">pisanoPrime</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">is_prime</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">or</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span><span style="color: #000000;">k</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">pisano_period</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">pisano</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000080;font-style:italic;">-- Calculates the Pisano period of 'm' using pisanoPrime.</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">1</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">prime_factors</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">true</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">get_maxprime</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">))&</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">pps</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">p</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">pps</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pps</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pisanoPrime</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span><span style="color: #000000;">k</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">k</span><span style="color: #0000FF;">,</span><span style="color: #000000;">p</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #000000;">k</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #7060A8;">lcm</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pps</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">lim</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000080;font-style:italic;">-- test harness</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"pisanoPrimes"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">pdx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
|
||||
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">get_prime</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pdx</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">lim</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #000000;">c</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #000000;">7</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n "</span><span style="color: #0000FF;">)</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">elsif</span> <span style="color: #000000;">pdx</span><span style="color: #0000FF;">></span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">", "</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"(%3d,%d)=%3d"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span><span style="color: #000000;">k</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pisanoPrime</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span><span style="color: #000000;">k</span><span style="color: #0000FF;">)})</span>
|
||||
<span style="color: #000000;">pdx</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
<span style="color: #000000;">p</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">15</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">p</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">180</span><span style="color: #0000FF;">)</span>
|
||||
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">p180</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">180</span> <span style="color: #008080;">do</span> <span style="color: #000000;">p180</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">pisano</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"pisano(1..180):\n"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p180</span><span style="color: #0000FF;">,{</span><span style="color: #004600;">pp_IntFmt</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%4d"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">pp_IntCh</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">})</span>
|
||||
<!--
|
||||
40
Task/Pisano-period/Python/pisano-period.py
Normal file
40
Task/Pisano-period/Python/pisano-period.py
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
from sympy import isprime, lcm, factorint, primerange
|
||||
from functools import reduce
|
||||
|
||||
|
||||
def pisano1(m):
|
||||
"Simple definition"
|
||||
if m < 2:
|
||||
return 1
|
||||
lastn, n = 0, 1
|
||||
for i in range(m ** 2):
|
||||
lastn, n = n, (lastn + n) % m
|
||||
if lastn == 0 and n == 1:
|
||||
return i + 1
|
||||
return 1
|
||||
|
||||
def pisanoprime(p, k):
|
||||
"Use conjecture π(p ** k) == p ** (k − 1) * π(p) for prime p and int k > 1"
|
||||
assert isprime(p) and k > 0
|
||||
return p ** (k - 1) * pisano1(p)
|
||||
|
||||
def pisano_mult(m, n):
|
||||
"pisano(m*n) where m and n assumed coprime integers"
|
||||
return lcm(pisano1(m), pisano1(n))
|
||||
|
||||
def pisano2(m):
|
||||
"Uses prime factorization of m"
|
||||
return reduce(lcm, (pisanoprime(prime, mult)
|
||||
for prime, mult in factorint(m).items()), 1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
for n in range(1, 181):
|
||||
assert pisano1(n) == pisano2(n), "Wall-Sun-Sun prime exists??!!"
|
||||
print("\nPisano period (p, 2) for primes less than 50\n ",
|
||||
[pisanoprime(prime, 2) for prime in primerange(1, 50)])
|
||||
print("\nPisano period (p, 1) for primes less than 180\n ",
|
||||
[pisanoprime(prime, 1) for prime in primerange(1, 180)])
|
||||
print("\nPisano period (p) for integers 1 to 180")
|
||||
for i in range(1, 181):
|
||||
print(" %3d" % pisano2(i), end="" if i % 10 else "\n")
|
||||
68
Task/Pisano-period/Quackery/pisano-period.quackery
Normal file
68
Task/Pisano-period/Quackery/pisano-period.quackery
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
[ dip number$
|
||||
over size -
|
||||
space swap of
|
||||
swap join echo$ ] is recho ( n n --> )
|
||||
|
||||
[ witheach
|
||||
[ 4 recho
|
||||
i^ 1+ 10 mod
|
||||
0 = if cr ] ] is prettyecho ( [ --> )
|
||||
|
||||
[ primefactors size 1 = ] is isprime ( n --> b )
|
||||
|
||||
[ dup [] = if done
|
||||
[] [] rot
|
||||
witheach
|
||||
[ over [] = iff
|
||||
join done
|
||||
over 0 peek over = iff
|
||||
join done
|
||||
dip [ nested join ]
|
||||
nested ]
|
||||
nested join ] is runs ( [ --> [ )
|
||||
|
||||
[ stack ] is modulus ( --> s )
|
||||
|
||||
[ dip dup 1 - **
|
||||
swap dup 2 < iff
|
||||
[ 2drop 1 ] done
|
||||
modulus put
|
||||
0 temp put
|
||||
0 1
|
||||
[ 1 temp tally
|
||||
tuck +
|
||||
modulus share mod
|
||||
dup 1 = until
|
||||
over 0 = until ]
|
||||
2drop
|
||||
modulus release
|
||||
temp take * ] is pisanoprime ( n n --> n )
|
||||
|
||||
[ dup 2 < iff
|
||||
[ drop 1 ] done
|
||||
primefactors
|
||||
runs
|
||||
[] swap
|
||||
witheach
|
||||
[ dup 0 peek
|
||||
swap size
|
||||
pisanoprime
|
||||
join ]
|
||||
behead swap
|
||||
witheach lcm ] is pisano ( n --> n )
|
||||
|
||||
[] 15 times
|
||||
[ i^ isprime if
|
||||
[ i^ 2 pisanoprime
|
||||
join ] ]
|
||||
prettyecho
|
||||
cr cr
|
||||
[] 180 times
|
||||
[ i^ isprime if
|
||||
[ i^ 1 pisanoprime
|
||||
join ] ]
|
||||
prettyecho
|
||||
cr cr
|
||||
[] 180 times
|
||||
[ i^ 1+ pisano join ]
|
||||
prettyecho
|
||||
37
Task/Pisano-period/REXX/pisano-period.rexx
Normal file
37
Task/Pisano-period/REXX/pisano-period.rexx
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*REXX pgm calculates pisano period for a range of N, and pisanoPrime(N,m) [for primes]*/
|
||||
numeric digits 500 /*ensure enough decimal digits for Fib.*/
|
||||
parse arg lim.1 lim.2 lim.3 . /*obtain optional arguments from the CL*/
|
||||
if lim.1=='' | lim.1=="," then lim.1= 15 - 1 /*Not specified? Then use the default.*/
|
||||
if lim.2=='' | lim.2=="," then lim.2= 180 - 1 /* " " " " " " */
|
||||
if lim.3=='' | lim.3=="," then lim.3= 180 /* " " " " " " */
|
||||
call Fib /* " " Fibonacci numbers. */
|
||||
do i=1 for max(lim.1, lim.2, lim.3); call pisano(i) /*find pisano periods.*/
|
||||
end /*i*/; w= length(i)
|
||||
|
||||
do j=1 for 2; #= word(2 1, j)
|
||||
do p=1 for lim.j; if \isPrime(p) then iterate /*Not prime? Skip this number.*/
|
||||
say ' pisanoPrime('right(p, w)", "#') = 'right( pisanoPrime(p, #), 5)
|
||||
end /*p*/; say
|
||||
end /*j*/
|
||||
|
||||
say center(' pisano numbers for 1──►'lim.3" ", 20*4 - 1, "═") /*display a title.*/
|
||||
$=
|
||||
do j=1 for lim.3; $= $ right(@.j, w) /*append pisano number to the $ list.*/
|
||||
if j//20==0 then do; say substr($, 2); $=; end /*display 20 numbers to a line*/
|
||||
end /*j*/
|
||||
say substr($, 2) /*possible display any residuals──►term*/
|
||||
exit 0 /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
fib: procedure expose fib.; parse arg x; fib.=.; if x=='' then x= 1000
|
||||
fib.0= 0; fib.1= 1; if fib.x\==. then return fib.x
|
||||
do k=2 for x-1; a= k-1; b= k-2; fib.k= fib.a + fib.b
|
||||
end /*k*/; return fib.k
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
isPrime: parse arg n; if n<11 then return pos(n, '2 3 5 7')>0; if n//2==0 then return 0
|
||||
do k=3 by 2 while k*k<=n; if n//k==0 then return 0; end /*k*/; return 1
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
pisano: procedure expose @. fib.; parse arg m; if m==1 then do; @.m=1; return 1; end
|
||||
do k=1; _= k+1; if fib.k//m==0 & fib._//m==1 then leave
|
||||
end /*k*/; @.m= k; return k
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
pisanoPrime: procedure expose @. fib.; parse arg m,n; return m**(n-1) * pisano(m)
|
||||
25
Task/Pisano-period/Raku/pisano-period.raku
Normal file
25
Task/Pisano-period/Raku/pisano-period.raku
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
use Prime::Factor;
|
||||
|
||||
constant @fib := 1,1,*+*…*;
|
||||
|
||||
my %cache;
|
||||
|
||||
multi pisano-period (Int $p where *.is-prime, Int $k where * > 0 = 1) {
|
||||
return %cache{"$p|$k"} if %cache{"$p|$k"};
|
||||
my $fibmod = @fib.map: * % $p**$k;
|
||||
%cache{"$p|$k"} = (1..*).first: { !$fibmod[$_-1] and ($fibmod[$_] == 1) }
|
||||
}
|
||||
|
||||
multi pisano-period (Int $p where * > 0 ) {
|
||||
[lcm] prime-factors($p).Bag.map: { samewith .key, .value }
|
||||
}
|
||||
|
||||
|
||||
put "Pisano period (p, 2) for primes less than 50";
|
||||
put (map { pisano-period($_, 2) }, ^50 .grep: *.is-prime )».fmt('%4d');
|
||||
|
||||
put "\nPisano period (p, 1) for primes less than 180";
|
||||
.put for (map { pisano-period($_, 1) }, ^180 .grep: *.is-prime )».fmt('%4d').batch(15);
|
||||
|
||||
put "\nPisano period (p, 1) for integers 1 to 180";
|
||||
.put for (1..180).map( { pisano-period($_) } )».fmt('%4d').batch(15);
|
||||
25
Task/Pisano-period/Sidef/pisano-period-1.sidef
Normal file
25
Task/Pisano-period/Sidef/pisano-period-1.sidef
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
func pisano_period_pp(p,k) is cached {
|
||||
|
||||
assert(k.is_pos, "k = #{k} must be positive")
|
||||
assert(p.is_prime, "p = #{p} must be prime")
|
||||
|
||||
var (a, b, n) = (0, 1, p**k)
|
||||
|
||||
1..Inf -> first_by {
|
||||
(a, b) = (b, (a+b) % n)
|
||||
(a == 0) && (b == 1)
|
||||
}
|
||||
}
|
||||
|
||||
func pisano_period(n) {
|
||||
n.factor_map {|p,k| pisano_period_pp(p, k) }.lcm
|
||||
}
|
||||
|
||||
say "Pisano periods for squares of primes p <= 15:"
|
||||
say 15.primes.map {|p| pisano_period_pp(p, 2) }
|
||||
|
||||
say "\nPisano periods for primes p <= 180:"
|
||||
say 180.primes.map {|p| pisano_period_pp(p, 1) }
|
||||
|
||||
say "\nPisano periods for integers n from 1 to 180:"
|
||||
say pisano_period.map(1..180)
|
||||
22
Task/Pisano-period/Sidef/pisano-period-2.sidef
Normal file
22
Task/Pisano-period/Sidef/pisano-period-2.sidef
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
func pisano_period_pp(p, k=1) {
|
||||
(p - kronecker(5, p)).divisors.first_by {|d| fibmod(d, p) == 0 } * p**(k-1)
|
||||
}
|
||||
|
||||
func pisano_period(n) {
|
||||
|
||||
return 0 if (n <= 0)
|
||||
return 1 if (n == 1)
|
||||
|
||||
var d = n.factor_map {|p,k| pisano_period_pp(p, k) }.lcm
|
||||
|
||||
3.times {|k|
|
||||
var t = d<<k
|
||||
if ((fibmod(t, n) == 0) && (fibmod(t+1, n) == 1)) {
|
||||
return t
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for k in (1..8) {
|
||||
say ("Pisano(F_#{k}) = ", pisano_period(2**(2**k) + 1))
|
||||
}
|
||||
58
Task/Pisano-period/Wren/pisano-period.wren
Normal file
58
Task/Pisano-period/Wren/pisano-period.wren
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
import "/math" for Int
|
||||
import "/fmt" for Fmt
|
||||
|
||||
// Calculates the Pisano period of 'm' from first principles.
|
||||
var pisanoPeriod = Fn.new { |m|
|
||||
var p = 0
|
||||
var c = 1
|
||||
for (i in 0...m*m) {
|
||||
var t = p
|
||||
p = c
|
||||
c = (t + c) % m
|
||||
if (p == 0 && c == 1) return i + 1
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
// Calculates the Pisano period of p^k where 'p' is prime and 'k' is a positive integer.
|
||||
var pisanoPrime = Fn.new { |p, k|
|
||||
if (!Int.isPrime(p) || k == 0) return 0 // can't do this one
|
||||
return p.pow(k-1) * pisanoPeriod.call(p)
|
||||
}
|
||||
|
||||
// Calculates the Pisano period of 'm' using pisanoPrime.
|
||||
var pisano = Fn.new { |m|
|
||||
var primes = Int.primeFactors(m)
|
||||
var primePowers = {}
|
||||
for (p in primes) {
|
||||
var v = primePowers[p]
|
||||
primePowers[p] = v ? v + 1 : 1
|
||||
}
|
||||
var pps = []
|
||||
for (me in primePowers) pps.add(pisanoPrime.call(me.key, me.value))
|
||||
if (pps.count == 0) return 1
|
||||
if (pps.count == 1) return pps[0]
|
||||
var f = pps[0]
|
||||
var i = 1
|
||||
while (i < pps.count) {
|
||||
f = Int.lcm(f, pps[i])
|
||||
i = i + 1
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
for (p in 2..14) {
|
||||
var pp = pisanoPrime.call(p, 2)
|
||||
if (pp > 0) Fmt.print("pisanoPrime($2d: 2) = $d", p, pp)
|
||||
}
|
||||
System.print()
|
||||
for (p in 2..179) {
|
||||
var pp = pisanoPrime.call(p, 1)
|
||||
if (pp > 0) Fmt.print("pisanoPrime($3d: 1) = $d", p, pp)
|
||||
}
|
||||
System.print("\npisano(n) for integers 'n' from 1 to 180 are:")
|
||||
for (n in 1..180) {
|
||||
Fmt.write("$3d ", pisano.call(n))
|
||||
if (n != 1 && n%15 == 0) System.print()
|
||||
}
|
||||
System.print()
|
||||
15
Task/Pisano-period/Zkl/pisano-period-1.zkl
Normal file
15
Task/Pisano-period/Zkl/pisano-period-1.zkl
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
var [const] BI=Import("zklBigNum"); // libGMP
|
||||
|
||||
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))
|
||||
}
|
||||
7
Task/Pisano-period/Zkl/pisano-period-2.zkl
Normal file
7
Task/Pisano-period/Zkl/pisano-period-2.zkl
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
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() });
|
||||
19
Task/Pisano-period/Zkl/pisano-period-3.zkl
Normal file
19
Task/Pisano-period/Zkl/pisano-period-3.zkl
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
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;
|
||||
}
|
||||
3
Task/Pisano-period/Zkl/pisano-period-4.zkl
Normal file
3
Task/Pisano-period/Zkl/pisano-period-4.zkl
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
println("Pisano(m) for integers 1 to 180:");
|
||||
[1..180].pump(List, pisano, "%4d".fmt)
|
||||
.pump(Void,T(Void.Read,14,False),fcn{ vm.arglist.concat().println() });
|
||||
Loading…
Add table
Add a link
Reference in a new issue