Permalink
Browse files

new arithmetic examples

  • Loading branch information...
1 parent d3f185c commit c956764cffb7115a32608b3d671554a95bca4463 @philandstuff 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
View
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
View
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
View
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:<coprime> (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
View
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:<coprime> (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

0 comments on commit c956764

Please sign in to comment.