# perl6/perl6-examples

new arithmetic examples

1 parent d3f185c commit c956764cffb7115a32608b3d671554a95bca4463 philandstuff committed Sep 5, 2010
Showing with 125 additions and 0 deletions.
1. +20 −0 99-problems/P31-rhebus.pl
2. +20 −0 99-problems/P32-rhebus.pl
3. +37 −0 99-problems/P33-rhebus.pl
4. +48 −0 99-problems/P34-rhebus.pl
20 99-problems/P31-rhebus.pl
 @@ -0,0 +1,20 @@ +use v6; + +# Specification: +# P31 (**) Determine whether a given integer number is prime. +# Example: +# > say is_prime 7 +# 1 + + +sub is_prime (Int \$n) { + for 2..sqrt \$n -> \$k { + return Bool::False if \$n %% \$k; + } + return Bool::True; +} + +say "Is \$_ prime? ", is_prime(\$_) ?? 'yes' !! 'no' + for (list(2 .. 10), 49,137,219,1723); + +# vim:ft=perl6
20 99-problems/P32-rhebus.pl
 @@ -33,4 +33,24 @@ (Int \$a, Int \$b) gcdr(36,63).say; gcdr(63,36).say; + +# Example 3: series operator +# The series operator generates series lazily. It takes some start terms, a +# generation rule, and possibly a limit, and produces a series. +# To create the Fibonacci series, we write: +# (1, 1, *+* ... *) +# The generation rule is to sum the previous two terms: *+*. +# A limit of * continues the series forever. +# +# We exploit this to generate the series of intermediate values in Euclid's +# algorithm: each step in the series is the mod of the last two terms. When +# we reach 0, the term before that was the gcd. +sub gcds (Int \$a, Int \$b) { + return (\$a, \$b, *%* ... 0)[*-2]; +} + +gcds(8,12).say; +gcds(36,63).say; +gcds(63,36).say; + # vim:ft=perl6
37 99-problems/P33-rhebus.pl
 @@ -0,0 +1,37 @@ +use v6; + +# Specification: +# P33 (*) Determine whether two positive integer numbers are coprime. +# Two numbers are coprime if their greatest common divisor equals 1. +# Example: +# > say coprime(35,64) +# 1 + + +# This is from P32-rhebus.pl +sub gcds (Int \$a, Int \$b) { + return (\$a, \$b, *%* ... 0)[*-2]; +} + +sub coprime (Int \$a, Int \$b) { gcds(\$a,\$b) == 1 } + +say coprime(35,64); + + +# Another option is to make coprime an operator: +# (theoretically 'our' is unnecessary but rakudo needs it +our sub infix: (Int \$a, Int \$b) { gcds(\$a,\$b) == 1 } + +# All adjacent fibonacci pairs are coprime. +# We can test a number of fibonacci pairs at once +# with the hyper operator »coprime« + +my @fib = (1,2,3,5,8,13,21,34,55); +say \$_ for @fib[0..^+@fib-1] »coprime« @fib[1..^+@fib]; + +# And here's another famous series: +my @pow = (1,2,4,{\$_*2} ... 4096); +say \$_ for @pow[0..^+@pow-1] »coprime« @pow[1..^+@pow]; + + +# vim:ft=perl6
48 99-problems/P34-rhebus.pl
 @@ -0,0 +1,48 @@ +use v6; + +# Specification: +# P34 (**) Calculate Euler's totient function phi(m). +# Euler's so-called totient function phi(m) is defined as the number of +# positive integers r (1 <= r < m) that are coprime to m. +# Example: +# m = 10: r = 1,3,7,9; thus phi(m) = 4. Note the special case: phi(1) = 1. +# > say totient_phi 10 +# 4 +# +# Find out what the value of phi(m) is if m is a prime number. Euler's totient +# function plays an important role in one of the most widely used public key +# cryptography methods (RSA). In this exercise you should use the most +# primitive method to calculate this function (there are smarter ways that we +# shall discuss later). + + +# from P32-rhebus.pl +sub gcds (Int \$a, Int \$b) { + return (\$a, \$b, *%* ... 0)[*-2]; +} + +# from P33-rhebus.pl +our sub infix: (Int \$a, Int \$b) { gcds(\$a,\$b) == 1 } + + +# Example 1: iteration +sub totient_phi_i (Int \$n) { + return 1 if \$n ~~ 1; + my \$total = 0; + for 1..^\$n -> \$k { \$total++ if \$n coprime \$k } + return \$total; +} + +say "phi(\$_): ", totient_phi_i \$_ for (1..20); + + + +# Example 2: «coprime« hyper operator +sub totient_phi (Int \$n) { + return 1 if \$n ~~ 1; + return [+] (\$n «coprime« list(1..^\$n)); +} + +say "phi(\$_): ",totient_phi \$_ for (1..20); + +# vim:ft=perl6