aboutsummaryrefslogtreecommitdiff
path: root/challenge-094/andinus/README.org
blob: c4f5da3378ccd83757c441f183578912165ff3bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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