aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJörg Sommrey <28217714+jo-37@users.noreply.github.com>2023-09-30 15:20:13 +0100
committerJörg Sommrey <28217714+jo-37@users.noreply.github.com>2023-09-30 15:20:13 +0100
commitd3e58539d87fc81a3cd4ef6462402a2081545bfe (patch)
tree6dcd11bf326a68002c17106cba72c9617e8e6c52
parent4f0cf89dcc92da3c3852d25b3e14e441f5787e04 (diff)
parentf6a6e42fabfe628dc5a17253a5db28f203312f73 (diff)
downloadperlweeklychallenge-club-d3e58539d87fc81a3cd4ef6462402a2081545bfe.tar.gz
perlweeklychallenge-club-d3e58539d87fc81a3cd4ef6462402a2081545bfe.tar.bz2
perlweeklychallenge-club-d3e58539d87fc81a3cd4ef6462402a2081545bfe.zip
Solutions to challenge 236
-rwxr-xr-xchallenge-236/jo-37/perl/ch-1.pl82
-rwxr-xr-xchallenge-236/jo-37/perl/ch-2.pl66
2 files changed, 148 insertions, 0 deletions
diff --git a/challenge-236/jo-37/perl/ch-1.pl b/challenge-236/jo-37/perl/ch-1.pl
new file mode 100755
index 0000000000..36ae37769e
--- /dev/null
+++ b/challenge-236/jo-37/perl/ch-1.pl
@@ -0,0 +1,82 @@
+#!/usr/bin/perl -s
+
+use v5.24;
+use Test2::V0;
+use List::Util qw(min);
+
+our ($tests, $examples);
+
+run_tests() if $tests || $examples; # does not return
+
+die <<EOS unless @ARGV;
+usage: $0 [-examples] [-tests] [B...]
+
+-examples
+ run the examples from the challenge
+
+-tests
+ run some tests
+
+B...
+ list $5, $10 and $20 bills
+EOS
+
+
+### Input and Output
+
+say sell_juice(@ARGV) ? 'true' : 'false';
+
+
+### Implementation
+
+sub sell_juice {
+ # At the beginning, the trays for $5, $10 and $20 bills in our cash
+ # register are empty. Counting $20 bills, but never return them.
+ (\my %register)->@{5, 10, 20} = (0, 0, 0);
+ state $price = 5;
+
+ # Try to sell a juice for every given bill.
+ for my $bill (@_) {
+ # The amount to be returned.
+ my $return = $bill - $price;
+ # There is only one case, where the action is not uniquely
+ # defined: If we are to return $15, have three or more $5 bills
+ # and one or more $10 bills. In this situation we give one $10
+ # bill and one $5 bill.
+ for my $tray (10, 5) {
+ my $cnt = min $register{$tray}, int $return / $tray;
+ # Take the bill(s) from the tray and adjust the to be
+ # returned amount.
+ $register{$tray} -= $cnt;
+ $return -= $cnt * $tray;
+ }
+ # Put the received bill into its tray.
+ $register{$bill}++;
+ # Fail if we cannot return the exact change.
+ return if $return;
+ }
+ # Here we succeeded.
+ 1;
+}
+
+
+### Examples and tests
+
+sub run_tests {
+ SKIP: {
+ skip "examples" unless $examples;
+
+ ok sell_juice(5, 5, 5, 10, 20), 'example 1';
+ ok !sell_juice(5, 5, 10, 10, 20), 'example 2';
+ ok sell_juice(5, 5, 5, 20), 'example 3';
+ }
+
+ SKIP: {
+ skip "tests" unless $tests;
+
+ ok sell_juice(5, 5, 5, 5, 10, 20, 10), 'prefer 1x10 + 1x5 over 3x5';
+ }
+
+ done_testing;
+ exit;
+}
diff --git a/challenge-236/jo-37/perl/ch-2.pl b/challenge-236/jo-37/perl/ch-2.pl
new file mode 100755
index 0000000000..2002c6db96
--- /dev/null
+++ b/challenge-236/jo-37/perl/ch-2.pl
@@ -0,0 +1,66 @@
+#!/usr/bin/perl -s
+
+use v5.25;
+use Test2::V0;
+use Math::Permutation;
+
+our ($tests, $examples);
+
+run_tests() if $tests || $examples; # does not return
+
+die <<EOS unless @ARGV;
+usage: $0 [-examples] [-tests] [N...]
+
+-examples
+ run the examples from the challenge
+
+-tests
+ run some tests
+
+N...
+ zero-based permutation of any size in one-line notation
+
+EOS
+
+
+### Input and Output
+
+say cycles(@ARGV);
+
+
+### Implementation
+
+# As the given numbers shall be unique and at the same time be indices
+# into an array of the same size, they actually represent a zero-based
+# permutation in one-line notation. This task asks for the number of
+# cycles. Transforming the numbers into a one-based one-line notation,
+# creating a permutation thereof, converting to cycles and counting
+# these with the help of CY's Math::Permutation module.
+
+sub cycles {
+ scalar Math::Permutation->wrepr([map $_ + 1, @_])->cyc->@*;
+}
+
+
+### Examples and tests
+
+sub run_tests {
+ SKIP: {
+ skip "examples" unless $examples;
+
+ is cycles(4,6,3,8,15,0,13,18,7,16,14,19,17,5,11,1,12,2,9,10),
+ 3, 'example 1';
+ is cycles(0,1,13,7,6,8,10,11,2,14,16,4,12,9,17,5,3,18,15,19),
+ 6, 'example 2';
+ is cycles(9,8,3,11,5,7,13,19,12,4,14,10,18,2,16,1,0,15,6,17),
+ 1, 'example 3';
+
+ }
+
+ SKIP: {
+ skip "tests" unless $tests;
+ }
+
+ done_testing;
+ exit;
+}