diff options
| author | Roger Bell_West <roger@firedrake.org> | 2023-09-26 15:05:47 +0100 |
|---|---|---|
| committer | Roger Bell_West <roger@firedrake.org> | 2023-09-26 15:05:47 +0100 |
| commit | 505f0065a1e22c26aa7347f82f0c899eeda4c396 (patch) | |
| tree | d14773d2873ba068fc6b15e05229368a2c42ef41 | |
| parent | debce30c9732613662c4b075bc70edee05255876 (diff) | |
| download | perlweeklychallenge-club-505f0065a1e22c26aa7347f82f0c899eeda4c396.tar.gz perlweeklychallenge-club-505f0065a1e22c26aa7347f82f0c899eeda4c396.tar.bz2 perlweeklychallenge-club-505f0065a1e22c26aa7347f82f0c899eeda4c396.zip | |
RogerBW solutions for challenge no. 236
21 files changed, 1461 insertions, 0 deletions
diff --git a/challenge-236/roger-bell-west/javascript/ch-1.js b/challenge-236/roger-bell-west/javascript/ch-1.js new file mode 100755 index 0000000000..98b6a4569e --- /dev/null +++ b/challenge-236/roger-bell-west/javascript/ch-1.js @@ -0,0 +1,72 @@ +#! /usr/bin/node + +"use strict" + +function Reserve(vv) { + let r = Object.create(Reserve.methods); + let vq = vv.sort(function(a, b) { + return b - a; + }); + r.values = vq; + r.counts = []; + r.vm = new Map; + for (let i = 0; i < vq.length; i++) { + r.counts.push(0); + r.vm.set(vq[i], i); + } + return r; +} + +Reserve.methods = { + makechange(price, tendered) { + let val = 0; + for (let note of tendered) { + if (!this.vm.has(note)) { + return false; + } + this.counts[this.vm.get(note)]++; + val += note; + } + if (val < price) { + return false; + } + val -= price; + for (let bid = 0; bid < this.values.length; bid++) { + while (val >= this.values[bid] && this.counts[bid] > 0) { + val -= this.values[bid]; + this.counts[bid]--; + } + } + return (val == 0); + } +} + +function exactchange(a) { + var reserve = Reserve([5, 10, 20]) + for (let tendered of a) { + if (!reserve.makechange(5, [tendered])) { + return false; + } + } + return true; +} + + +if (exactchange([5, 5, 5, 10, 20])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (!exactchange([5, 5, 10, 10, 20])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (exactchange([5, 5, 5, 20])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write("\n"); diff --git a/challenge-236/roger-bell-west/javascript/ch-2.js b/challenge-236/roger-bell-west/javascript/ch-2.js new file mode 100755 index 0000000000..2af581a1ea --- /dev/null +++ b/challenge-236/roger-bell-west/javascript/ch-2.js @@ -0,0 +1,54 @@ +#! /usr/bin/node + +"use strict" + +function arrayloops(a) { + let loop_id = 0; + let loops = new Map; + for (let origin = 0; origin < a.length; origin++) { + if (!loops.has(origin)) { + let li = 0; + let thisloop = new Set; + let x = origin; + while (true) { + if (x >= a.length) { + break; + } + thisloop.add(x); + x = a[x]; + if (loops.has(x)) { + li = loops.get(x); + break; + } + if (thisloop.has(x)) { + loop_id += 1; + li = loop_id; + break; + } + } + for (let i of thisloop) { + loops.set(i, li); + } + } + } + return loop_id; +} + +if (arrayloops([4, 6, 3, 8, 15, 0, 13, 18, 7, 16, 14, 19, 17, 5, 11, 1, 12, 2, 9, 10]) == 3) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (arrayloops([0, 1, 13, 7, 6, 8, 10, 11, 2, 14, 16, 4, 12, 9, 17, 5, 3, 18, 15, 19]) == 6) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (arrayloops([9, 8, 3, 11, 5, 7, 13, 19, 12, 4, 14, 10, 18, 2, 16, 1, 0, 15, 6, 17]) == 1) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write("\n"); diff --git a/challenge-236/roger-bell-west/kotlin/ch-1.kt b/challenge-236/roger-bell-west/kotlin/ch-1.kt new file mode 100644 index 0000000000..e72f15fedc --- /dev/null +++ b/challenge-236/roger-bell-west/kotlin/ch-1.kt @@ -0,0 +1,72 @@ +class Reserve(vls: List<Int>) { + var vll: ArrayList<Int> = ArrayList(0) + var counts: ArrayList<Int> = ArrayList(0) + var vm = mutableMapOf<Int, Int>() + + init { + var vq = ArrayList(vls) + vq.sort() + vq.reverse() + vll = vq + for (i in 1..vq.size) { + counts.add(0) + } + vq.forEachIndexed {i, v -> vm.put(v, i)} + } + + fun makechange(price: Int, tendered: List<Int>): Boolean { + var vl = 0 + for (note in tendered) { + if (!vm.contains(note)) { + return false + } + counts[vm.getValue(note)] += 1 + vl += note + } + if (vl < price) { + return false + } + vl -= price + for (bid in 0..vll.size-1) { + while (vl >= vll[bid] && counts[bid] > 0) { + vl -= vll[bid] + counts[bid] -= 1 + } + } + return (vl == 0) + } +} + +fun exactchange(a: List<Int>): Boolean { + var reserve = Reserve(listOf(5, 10, 20)) + for (tendered in a) { + if (!reserve.makechange(5, listOf(tendered))) { + return false + } + } + return true +} + + +fun main() { + + if (exactchange(listOf(5, 5, 5, 10, 20))) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (!exactchange(listOf(5, 5, 10, 10, 20))) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (exactchange(listOf(5, 5, 5, 20))) { + print("Pass") + } else { + print("Fail") + } + println("") + +} diff --git a/challenge-236/roger-bell-west/kotlin/ch-2.kt b/challenge-236/roger-bell-west/kotlin/ch-2.kt new file mode 100644 index 0000000000..dc176509dd --- /dev/null +++ b/challenge-236/roger-bell-west/kotlin/ch-2.kt @@ -0,0 +1,54 @@ +fun arrayloops(a: List<Int>): Int { + var loop_id = 0 + var loops = mutableMapOf<Int, Int>() + for (origin in 0..a.size-1) { + if (!loops.contains(origin)) { + var li = 0 + var thisloop = mutableSetOf<Int>() + var x = origin + while (true) { + if (x >= a.size) { + break + } + thisloop.add(x) + x = a[x] + if (loops.contains(x)) { + li = loops.getValue(x) + break + } + if (thisloop.contains(x)) { + loop_id += 1 + li = loop_id + break + } + } + for (i in thisloop) { + loops.put(i, li) + } + } + } + return loop_id +} + +fun main() { + + if (arrayloops(listOf(4, 6, 3, 8, 15, 0, 13, 18, 7, 16, 14, 19, 17, 5, 11, 1, 12, 2, 9, 10)) == 3) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (arrayloops(listOf(0, 1, 13, 7, 6, 8, 10, 11, 2, 14, 16, 4, 12, 9, 17, 5, 3, 18, 15, 19)) == 6) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (arrayloops(listOf(9, 8, 3, 11, 5, 7, 13, 19, 12, 4, 14, 10, 18, 2, 16, 1, 0, 15, 6, 17)) == 1) { + print("Pass") + } else { + print("Fail") + } + println("") + +} diff --git a/challenge-236/roger-bell-west/lua/ch-1.lua b/challenge-236/roger-bell-west/lua/ch-1.lua new file mode 100755 index 0000000000..85014cd27d --- /dev/null +++ b/challenge-236/roger-bell-west/lua/ch-1.lua @@ -0,0 +1,87 @@ +#! /usr/bin/lua + +-- by hookenz at +-- https://stackoverflow.com/questions/9168058/how-to-dump-a-table-to-console +function dump(o) + if type(o) == 'table' then + local s = '{ ' + for k,v in pairs(o) do + if type(k) ~= 'number' then k = '"'..k..'"' end + s = s .. '['..k..'] = ' .. dump(v) .. ',' + end + return s .. '} ' + else + return tostring(o) + end +end + +Reserve = {values = {}, counts = {}, vm = {}} + +function Reserve:new(vv) + local o = {} + self.__index = self + setmetatable(o,self) + o.values = vv + table.sort(o.values, function (aa, bb) return bb < aa end) + o.counts = {} + o.vm = {} + for i, n in ipairs(o.values) do + table.insert(o.counts, 0) + o.vm[n] = i + end + return o +end + +function Reserve:makechange(price, tendered) + local val = 0 + for _, note in ipairs(tendered) do + if self.vm[note] == nil then + return false + end + self.counts[self.vm[note]] = self.counts[self.vm[note]] + 1 + val = val + note + end + if val < price then + return false + end + val = val - price + for bid = 1, #self.values do + while val >= self.values[bid] and self.counts[bid] > 0 do + val = val - self.values[bid] + self.counts[bid] = self.counts[bid] - 1 + end + end + return (val == 0) +end + +function exactchange(a) + local reserve = Reserve:new({5, 10, 20}) + for _, tendered in ipairs(a) do + if not reserve:makechange(5, {tendered}) then + return false + end + end + return true +end + +if exactchange({5, 5, 5, 10, 20}) then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if not exactchange({5, 5, 10, 10, 20}) then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if exactchange({5, 5, 5, 20}) then + io.write("Pass") +else + io.write("FAIL") +end +print("") + diff --git a/challenge-236/roger-bell-west/lua/ch-2.lua b/challenge-236/roger-bell-west/lua/ch-2.lua new file mode 100755 index 0000000000..5dbb9294be --- /dev/null +++ b/challenge-236/roger-bell-west/lua/ch-2.lua @@ -0,0 +1,55 @@ +#! /usr/bin/lua + +function arrayloops(a) + local loop_id = 0 + local loops = {} + for _i, origin in ipairs(a) do + if loops[origin] == nil then + local li = 0 + local thisloop = {} + local x = origin + while true do + if x < 0 or x >= #a then + break + end + thisloop[x] = true + x = a[x + 1] + if loops[x] ~= nil then + li = loops[x] + break + end + if thisloop[x] ~= nil then + loop_id = loop_id + 1 + li = loop_id + break + end + end + for i, _t in pairs(thisloop) do + loops[i] = li + end + end + end + return loop_id +end + +if arrayloops({4, 6, 3, 8, 15, 0, 13, 18, 7, 16, 14, 19, 17, 5, 11, 1, 12, 2, 9, 10}) == 3 then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if arrayloops({0, 1, 13, 7, 6, 8, 10, 11, 2, 14, 16, 4, 12, 9, 17, 5, 3, 18, 15, 19}) == 6 then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if arrayloops({9, 8, 3, 11, 5, 7, 13, 19, 12, 4, 14, 10, 18, 2, 16, 1, 0, 15, 6, 17}) == 1 then + io.write("Pass") +else + io.write("FAIL") +end +print("") + diff --git a/challenge-236/roger-bell-west/perl/ch-1.pl b/challenge-236/roger-bell-west/perl/ch-1.pl new file mode 100755 index 0000000000..e1c98df3e5 --- /dev/null +++ b/challenge-236/roger-bell-west/perl/ch-1.pl @@ -0,0 +1,59 @@ +#! /usr/bin/perl + +use strict; +use warnings; +use experimental 'signatures'; + +use Test::More tests => 3; + +is(exactchange([5, 5, 5, 10, 20]), 1, 'example 1'); +is(exactchange([5, 5, 10, 10, 20]), 0, 'example 2'); +is(exactchange([5, 5, 5, 20]), 1, 'example 3'); + +sub exactchange($a) { + my $reserve = Reserve->new([5, 10, 20]); + foreach my $tendered (@{$a}) { + unless ($reserve->makechange(5, [$tendered])) { + return 0; + } + } + return 1; +} + +package Reserve; + +sub new($class, $init) { + my $self = { + vall => [sort {$b <=> $a} @{$init}], + counts => [(0) x scalar @{$init}], + }; + bless $self, $class; + my %vm; + foreach my $n (0..$#{$self->{vall}}) { + $vm{$self->{vall}[$n]} = $n; + } + $self->{vm} = \%vm; + return $self; +} + +sub makechange($self, $price, $tendered) { + my $val = 0; + foreach my $note (@{$tendered}) { + unless (exists $self->{vm}{$note}) { + return 0; + } + $self->{counts}[$self->{vm}{$note}]++; + $val += $note; + } + if ($val < $price) { + return 0; + } + $val -= $price; + foreach my $bid (0..$#{$self->{vall}}) { + while ($val >= $self->{vall}[$bid] && $self->{counts}[$bid] > 0) { + $val -= $self->{vall}[$bid]; + $self->{counts}[$bid]--; + } + } + return ($val == 0); +} diff --git a/challenge-236/roger-bell-west/perl/ch-2.pl b/challenge-236/roger-bell-west/perl/ch-2.pl new file mode 100755 index 0000000000..1ef37df3e3 --- /dev/null +++ b/challenge-236/roger-bell-west/perl/ch-2.pl @@ -0,0 +1,43 @@ +#! /usr/bin/perl + +use strict; +use warnings; +use experimental 'signatures'; + +use Test::More tests => 3; + +is(arrayloops([4, 6, 3, 8, 15, 0, 13, 18, 7, 16, 14, 19, 17, 5, 11, 1, 12, 2, 9, 10]), 3, 'example 1'); +is(arrayloops([0, 1, 13, 7, 6, 8, 10, 11, 2, 14, 16, 4, 12, 9, 17, 5, 3, 18, 15, 19]), 6, 'example 2'); +is(arrayloops([9, 8, 3, 11, 5, 7, 13, 19, 12, 4, 14, 10, 18, 2, 16, 1, 0, 15, 6, 17]), 1, 'example 3'); + +sub arrayloops($a) { + my $loop_id = 0; + my %loops; + foreach my $origin (0..$#{$a}) { + unless (exists $loops{$origin}) { + my $li = 0; + my %thisloop; + my $x = $origin; + while (1) { + if ($x < 0 || $x > $#{$a}) { + last; + } + $thisloop{$x} = 1; + $x = $a->[$x]; + if (exists $loops{$x}) { + $li = $loops{$x}; + last; + } + if (exists $thisloop{$x}) { + $loop_id++; + $li = $loop_id; + last; + } + } + foreach my $i (keys %thisloop) { + $loops{$i} = $li; + } + } + } + return $loop_id; +} diff --git a/challenge-236/roger-bell-west/postscript/ch-1.ps b/challenge-236/roger-bell-west/postscript/ch-1.ps new file mode 100644 index 0000000000..b2cb52dcd6 --- /dev/null +++ b/challenge-236/roger-bell-west/postscript/ch-1.ps @@ -0,0 +1,221 @@ +%!PS + +% begin included library code +% see https://codeberg.org/Firedrake/postscript-libraries/ +/quicksort.cmp { + 2 copy + lt { + pop pop -1 + } { + gt { + 1 + } { + 0 + } ifelse + } ifelse +} bind def + +/quicksort.main { % lo hi -> (null) + 3 dict begin + /hi exch def + /lo exch def + /xit false def + lo 0 lt { + /xit true def + } if + hi 0 lt { + /xit true def + } if + lo hi ge { + /xit true def + } if + xit not { + /p quicksort.partition def + lo p quicksort.main + p 1 add hi quicksort.main + } if + end +} bind def + +/quicksort { + { quicksort.cmp } quicksort.with_comparator +} bind def + +/test.start { + print (:) print + /test.pass 0 def + /test.count 0 def +} bind def + +/quicksort.partition { + 3 dict begin + /pivot arr hi lo add 2 idiv get def + /i lo 1 sub def + /j hi 1 add def + { + { + /i i 1 add def + arr i get pivot cmp 0 ge { + exit + } if + } loop + { + /j j 1 sub def + arr j get pivot cmp 0 le { + exit + } if + } loop + i j ge { + j + exit + } if + i j quicksort.swap + } loop + end +} bind def + +/quicksort.swap { + 2 dict begin + /bi exch def + /ai exch def + arr ai get + arr bi get + arr exch ai exch put + arr exch bi exch put + end +} bind def + +/quicksort.with_comparator { % [ a c b ] { comparator } -> [ a b c ] + 2 dict begin + /cmp exch def + /arr exch def + arr length 0 gt { + 0 arr length 1 sub quicksort.main + } if + arr + end +} bind def + +/test { + /test.count test.count 1 add def + { + /test.pass test.pass 1 add def + } { + ( ) print + test.count (....) cvs print + (-fail) print + } ifelse +} bind def + +/test.end { + ( ) print + test.count 0 gt { + (Passed ) print + test.pass (...) cvs print + (/) print + test.count (...) cvs print + ( \() print + test.pass 100 mul test.count idiv (...) cvs print + (%\)) print + (\r\n) print + } if +} bind def + +/reverse { + 1 dict begin + dup length /l exch def + [ exch + aload pop + 2 1 l { + -1 roll + } for + ] + end +} bind def + + +% end included library code + +/reserve.new { + 0 dict begin + /self 3 dict def + quicksort reverse self exch /values exch put + self /counts [ self (values) get length { 0 } repeat ] put + /vm self (values) get length dict def + 0 1 self (values) get length 1 sub { + dup + self (values) get exch get + exch + vm 3 1 roll + put + } for + self (vm) vm put + self + end +} bind def + +/reserve.makechange { + 0 dict begin + /tendered exch def + /price exch def + /self exch def + /val 0 def + true + 1 { + tendered { + /note exch def + self (vm) get note known not { + pop false + exit + } if + self (counts) get self (vm) get note get get 1 add + self (counts) get self (vm) get note get 3 -1 roll put + /val val note add def + } forall + dup not { + exit + } if + val price lt { + pop false + exit + } if + /val val price sub def + 0 1 self (values) get length 1 sub { + /bid exch def + { + val self (values) get bid get lt { + exit + } if + self (counts) get bid get 0 le { + exit + } if + /val val self (values) get bid get sub def + self (counts) get dup bid get 1 sub bid exch put + } loop + } for + } repeat + val 0 eq and + end +} bind def + +/exactchange { + 0 dict begin + /reserve [5 10 20] reserve.new def + true exch + { + /tendered exch def + reserve 5 [ tendered ] reserve.makechange not { + pop false + exit + } if + } forall + end +} bind def + +[ 5 10 20 ] reserve.new + +(exactchange) test.start +[5 5 5 10 20] exactchange test +[5 5 10 10 20] exactchange not test +[5 5 5 20] exactchange test +test.end diff --git a/challenge-236/roger-bell-west/postscript/ch-2.ps b/challenge-236/roger-bell-west/postscript/ch-2.ps new file mode 100644 index 0000000000..45b04c6137 --- /dev/null +++ b/challenge-236/roger-bell-west/postscript/ch-2.ps @@ -0,0 +1,87 @@ +%!PS + +% begin included library code +% see https://codeberg.org/Firedrake/postscript-libraries/ +/keys { % dict -> array of dict keys + [ exch + { + pop + } forall + ] +} bind def + +/test.end { + ( ) print + test.count 0 gt { + (Passed ) print + test.pass (...) cvs print + (/) print + test.count (...) cvs print + ( \() print + test.pass 100 mul test.count idiv (...) cvs print + (%\)) print + (\r\n) print + } if +} bind def + +/test.start { + print (:) print + /test.pass 0 def + /test.count 0 def +} bind def + +/test { + /test.count test.count 1 add def + { + /test.pass test.pass 1 add def + } { + ( ) print + test.count (....) cvs print + (-fail) print + } ifelse +} bind def + + +% end included library code + +/arrayloops { + 0 dict begin + /a exch def + /loop_id 0 def + /loops 0 dict def + a { + /origin exch def + loops origin known not { + /li 0 def + /thisloop 0 dict def + /x origin def + { + x 0 lt x a length ge or { + exit + } if + thisloop x true put + /x a x get def + loops x known { + /li loops x get def + exit + } if + thisloop x known { + /loop_id loop_id 1 add def + /li loop_id def + exit + } if + } loop + thisloop keys { + loops exch li put + } forall + } if + } forall + loop_id + end +} bind def + +(arrayloops) test.start +[4 6 3 8 15 0 13 18 7 16 14 19 17 5 11 1 12 2 9 10] arrayloops 3 eq test +[0 1 13 7 6 8 10 11 2 14 16 4 12 9 17 5 3 18 15 19] arrayloops 6 eq test +[9 8 3 11 5 7 13 19 12 4 14 10 18 2 16 1 0 15 6 17] arrayloops 1 eq test +test.end diff --git a/challenge-236/roger-bell-west/python/ch-1.py b/challenge-236/roger-bell-west/python/ch-1.py new file mode 100755 index 0000000000..638c1ca054 --- /dev/null +++ b/challenge-236/roger-bell-west/python/ch-1.py @@ -0,0 +1,49 @@ +#! /usr/bin/python3 + +class Reserve(object): + def __init__(self, _vv): + _vq = _vv + _vq.sort() + _vq.reverse() + _vm = dict() + for i, v in enumerate(_vq): + _vm[v] = i + self.values = _vq + self.counts = [0] * len(_vv) + self.vm = _vm + + def makechange(self, price, tendered): + val = 0 + for bill in tendered: + if bill not in self.vm: + return False + self.counts[self.vm.get(bill)] += 1 + val += bill + val -= price + for bid in range(len(self.values)): + while val >= self.values[bid] and self.counts[bid] > 0: + val -= self.values[bid] + self.counts[bid] -= 1 + return (val == 0) + +def exactchange(a): + reserve = Reserve([5, 10, 20]) + for tendered in a: + if not reserve.makechange(5, [tendered]): + return False + return True + +import unittest + +class TestExactchange(unittest.TestCase): + + def test_ex1(self): + self.assertEqual(exactchange([5, 5, 5, 10, 20]), True, 'example 1') + + def test_ex2(self): + self.assertEqual(exactchange([5, 5, 10, 10, 20]), False, 'example 2') + + def test_ex3(self): + self.assertEqual(exactchange([5, 5, 5, 20]), True, 'example 3') + +unittest.main() diff --git a/challenge-236/roger-bell-west/python/ch-2.py b/challenge-236/roger-bell-west/python/ch-2.py new file mode 100755 index 0000000000..d00cdd365a --- /dev/null +++ b/challenge-236/roger-bell-west/python/ch-2.py @@ -0,0 +1,40 @@ +#! /usr/bin/python3 + +def arrayloops(a): + loop_id = 0 + loops = dict() + for origin in range(len(a)): + if origin not in loops: + li = 0 + thisloop = set() + x = origin + while True: + if x < 0 or x >= len(a): + break + thisloop.add(x) + x = a[x] + if x in loops: + li = loops[x] + break + if x in thisloop: + loop_id += 1 + li = loop_id + break + for i in thisloop: + loops[i] = li + return loop_id + +import unittest + +class TestArrayloops(unittest.TestCase): + + def test_ex1(self): + self.assertEqual(arrayloops([4, 6, 3, 8, 15, 0, 13, 18, 7, 16, 14, 19, 17, 5, 11, 1, 12, 2, 9, 10]), 3, 'example 1') + + def test_ex2(self): + self.assertEqual(arrayloops([0, 1, 13, 7, 6, 8, 10, 11, 2, 14, 16, 4, 12, 9, 17, 5, 3, 18, 15, 19]), 6, 'example 2') + + def test_ex3(self): + self.assertEqual(arrayloops([9, 8, 3, 11, 5, 7, 13, 19, 12, 4, 14, 10, 18, 2, 16, 1, 0, 15, 6, 17]), 1, 'example 3') + +unittest.main() diff --git a/challenge-236/roger-bell-west/raku/ch-1.p6 b/challenge-236/roger-bell-west/raku/ch-1.p6 new file mode 100755 index 0000000000..cafe4c4b6d --- /dev/null +++ b/challenge-236/roger-bell-west/raku/ch-1.p6 @@ -0,0 +1,56 @@ +#! /usr/bin/raku + +use Test; + +plan 3; + +is(exactchange([5, 5, 5, 10, 20]), True, 'example 1'); +is(exactchange([5, 5, 10, 10, 20]), False, 'example 2'); +is(exactchange([5, 5, 5, 20]), True, 'example 3'); + +class Reserve { + has @!values; + has @!counts; + has %!vm; + + method TWEAK(:@notes) { + my @vq = @notes.sort({$^b <=> $^a}); + for (0..@vq.end) -> $i { + %!vm{@vq[$i]} = $i; + } + @!values = @vq; + @!counts = 0 xx @vq.elems; + } + + method makechange($price, @tendered) { + my $val = 0; + for @tendered -> $note { + unless (%!vm{$note}:exists) { + return False; + } + @!counts[%!vm{$note}]++; + $val += $note; + } + if ($val < $price) { + return False; + } + $val -= $price; + for 0..@!values.end -> $bid { + while ($val >= @!values[$bid] && @!counts[$bid] > 0) { + $val -= @!values[$bid]; + @!counts[$bid]--; + } + } + return ($val == 0); + } +} + +sub exactchange(@a) { + my $reserve = Reserve.new(notes => [5, 10, 20]); + for @a -> $tendered { + unless ($reserve.makechange(5, [$tendered])) { + return False; + } + } + return True; +} |
