aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-090/andinus/README94
-rw-r--r--challenge-090/andinus/README.org75
-rw-r--r--challenge-090/andinus/blog-2.txt1
-rwxr-xr-xchallenge-090/andinus/raku/ch-2.raku38
4 files changed, 175 insertions, 33 deletions
diff --git a/challenge-090/andinus/README b/challenge-090/andinus/README
index b372bec8d3..b662f1cb50 100644
--- a/challenge-090/andinus/README
+++ b/challenge-090/andinus/README
@@ -1,67 +1,95 @@
━━━━━━━━━━━━━━━
- CHALLENGE 086
+ CHALLENGE 090
Andinus
━━━━━━━━━━━━━━━
- 2020-11-15
+ 2020-12-08
Table of Contents
─────────────────
-1. Task 1 - Pair Difference
-.. 1. Perl
+1. Task 2 - Ethiopian Multiplication
+.. 1. Raku
-1 Task 1 - Pair Difference
-══════════════════════════
+1 Task 2 - Ethiopian Multiplication
+═══════════════════════════════════
- You are given an array of integers @N and an integer $A.
+ You are given two positive numbers $A and $B.
- Write a script to find find if there exists a pair of elements in the
- array whose difference is $A.
+ Write a script to demonstrate [Ethiopian Multiplication] using the
+ given numbers.
- Print 1 if exists otherwise 0.
+[Ethiopian Multiplication]
+<https://threesixty360.wordpress.com/2009/06/09/ethiopian-multiplication/>
-1.1 Perl
+1.1 Raku
────────
- • Program: <file:perl/ch-1.pl>
+ • Program: <file:perl/ch-2.raku>
- @N & $A are taken from stdin, $A is the last argument.
+ Start by taking `$A' & `$B' which are defined to be `Int' & positive.
┌────
- │ die "usage: ./ch-1.pl <integers \@N> <integer \$A>\n"
- │ unless scalar @ARGV >= 3;
- │
- │ my $A = pop @ARGV;
- │ my @N = @ARGV;
+ │ sub MAIN (
+ │ #= positive numbers
+ │ Int $A is copy where * > 0,
+ │ Int $B is copy where * > 0
+ │ ) {
+ │ ...
+ │ }
└────
- We just loop over @N over a loop over @N & find the difference. If
- it's equal to `$A' or `-$A' then we print `1' & exit. The first loop
- is `shift''ing the numbers out of array `@N' because we are matching
- for both `$A' & `-$A' so we don't need the number again.
+ Here's relevant part from the link that was given above:
+ Start with the two numbers on top. Halve one, ignoring any
+ remainders or fractions, and double the other, stopping
+ when you get to 1.
- For example, if `@N = [1, 2]' & we don't `shift' in first loop then
- we'll perform 2 subtraction operations: `1 - 2' & `2 - 1' & we won't
- have to match for `-$A' but if we just match for `-$A' then we can use
- `shift' & we'll only have to perform 1 subtraction operation `1 - 2'.
+ 14 & 12 7 & 24 3 & 48 [See how I ignored the fact that
+ halving 7 leaves 1 left over?] 1 & 96 <— Stop here.
- We assume subtraction costs more than matching with `-$A', that makes
- this more efficient. But it doesn't matter much.
+ Now look at the numbers on the right. Some are across from
+ an even number: in this case, 12 is across from the
+ original 14. Ignore those, and add the rest. So we’ll add
+ 24, 48, and 96, which were across from odd numbers, and
+ get 168. And that’s the product! Isn’t that cool?
+
+ We do the same thing & also print the instructions.
┌────
- │ while (my $int = shift @N) {
- │ foreach (@N) {
- │ my $diff = $int - $_;
- │ print "1\n" and exit 0 if ($diff == $A or $diff == -$A);
+ │ my %sets;
+ │
+ │ say "Ethopian Multiplication.\n";
+ │ say "Start with $A, $B.";
+ │ say "Divide $A by 2 & multiple $B by 2 at each step.";
+ │ say "Continue until $A equals 1. Drop the remainder, both should be Integer.\n";
+ │
+ │ say "$A, $B";
+ │ while True {
+ │ %sets{$A} = $B.Int;
+ │ $A = ($A / 2).Int;
+ │ $B = ($B * 2).Int;
+ │ last if $A < 1;
+ │ say "$A, $B";
+ │ }
+ │
+ │ say "\nNow to find the product, simply add all the numbers on right side of ','.";
+ │ say "But skip those numbers which have an even number on the left side.\n";
+ │
+ │ my Int $product = 0;
+ │ for %sets.sort({.key.Int}).reverse -> $pair {
+ │ if $pair.key % 2 != 0 {
+ │ $product += $pair.value;
+ │ say "- Adding ", $pair.value, " to product.";
+ │ } else {
+ │ say "- Skipping ", $pair.value, " because ", $pair.key, " is even.";
│ }
│ }
- │ print "0\n";
+ │ say "\nProduct: $product";
└────
diff --git a/challenge-090/andinus/README.org b/challenge-090/andinus/README.org
new file mode 100644
index 0000000000..c4f5da3378
--- /dev/null
+++ b/challenge-090/andinus/README.org
@@ -0,0 +1,75 @@
+#+SETUPFILE: ~/.emacs.d/org-templates/level-2.org
+#+HTML_LINK_UP: ../index.html
+#+OPTIONS: toc:2
+#+EXPORT_FILE_NAME: index
+#+DATE: 2020-12-08
+#+TITLE: Challenge 090
+
+* Task 2 - Ethiopian Multiplication
+You are given two positive numbers $A and $B.
+
+Write a script to demonstrate [[https://threesixty360.wordpress.com/2009/06/09/ethiopian-multiplication/][Ethiopian Multiplication]] using the given
+numbers.
+** Raku
+- Program: [[file:perl/ch-2.raku]]
+
+Start by taking =$A= & =$B= which are defined to be =Int= & positive.
+#+BEGIN_SRC raku
+sub MAIN (
+ #= positive numbers
+ Int $A is copy where * > 0,
+ Int $B is copy where * > 0
+) {
+ ...
+}
+#+END_SRC
+
+Here's relevant part from the link that was given above:
+#+BEGIN_QUOTE
+Start with the two numbers on top. Halve one, ignoring any remainders or
+fractions, and double the other, stopping when you get to 1.
+
+14 & 12
+7 & 24
+3 & 48 [See how I ignored the fact that halving 7 leaves 1 left over?]
+1 & 96 <— Stop here.
+
+Now look at the numbers on the right. Some are across from an even
+number: in this case, 12 is across from the original 14. Ignore those,
+and add the rest. So we’ll add 24, 48, and 96, which were across from
+odd numbers, and get 168. And that’s the product! Isn’t that cool?
+#+END_QUOTE
+
+We do the same thing & also print the instructions.
+#+BEGIN_SRC raku
+my %sets;
+
+say "Ethopian Multiplication.\n";
+say "Start with $A, $B.";
+say "Divide $A by 2 & multiple $B by 2 at each step.";
+say "Continue until $A equals 1. Drop the remainder, both should be Integer.\n";
+
+say "$A, $B";
+while True {
+ %sets{$A} = $B.Int;
+ $A = ($A / 2).Int;
+ $B = ($B * 2).Int;
+ last if $A < 1;
+ say "$A, $B";
+}
+
+say "\nNow to find the product, simply add all the numbers on right side of ','.";
+say "But skip those numbers which have an even number on the left side.\n";
+
+my Int $product = 0;
+for %sets.sort({.key.Int}).reverse -> $pair {
+ if $pair.key % 2 != 0 {
+ $product += $pair.value;
+ say "- Adding ", $pair.value, " to product.";
+ } else {
+ say "- Skipping ", $pair.value, " because ", $pair.key, " is even.";
+ }
+}
+
+say "\nProduct: $product";
+#+END_SRC
diff --git a/challenge-090/andinus/blog-2.txt b/challenge-090/andinus/blog-2.txt
new file mode 100644
index 0000000000..5b667faed0
--- /dev/null
+++ b/challenge-090/andinus/blog-2.txt
@@ -0,0 +1 @@
+https://andinus.tilde.institute/pwc/challenge-090/
diff --git a/challenge-090/andinus/raku/ch-2.raku b/challenge-090/andinus/raku/ch-2.raku
new file mode 100755
index 0000000000..5a30ae90b4
--- /dev/null
+++ b/challenge-090/andinus/raku/ch-2.raku
@@ -0,0 +1,38 @@
+#!/usr/bin/env raku
+
+sub MAIN (
+ #= positive numbers
+ Int $A is copy where * > 0,
+ Int $B is copy where * > 0
+) {
+ my %sets;
+
+ say "Ethopian Multiplication.\n";
+ say "Start with $A, $B.";
+ say "Divide $A by 2 & multiple $B by 2 at each step.";
+ say "Continue until $A equals 1. Drop the remainder, both should be Integer.\n";
+
+ say "$A, $B";
+ while True {
+ %sets{$A} = $B.Int;
+ $A = ($A / 2).Int;
+ $B = ($B * 2).Int;
+ last if $A < 1;
+ say "$A, $B";
+ }
+
+ say "\nNow to find the product, simply add all the numbers on right side of ','.";
+ say "But skip those numbers which have an even number on the left side.\n";
+
+ my Int $product = 0;
+ for %sets.sort({.key.Int}).reverse -> $pair {
+ if $pair.key % 2 != 0 {
+ $product += $pair.value;
+ say "- Adding ", $pair.value, " to product.";
+ } else {
+ say "- Skipping ", $pair.value, " because ", $pair.key, " is even.";
+ }
+ }
+
+ say "\nProduct: $product";
+}