aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2025-05-30 03:26:32 +0100
committerGitHub <noreply@github.com>2025-05-30 03:26:32 +0100
commit35ac29b79c68eb7a11abd17baf01e60132326b37 (patch)
treea2e4a015e730c2611ae426974eb90f4c162cb5e6
parentd698df4daf5cf87897d08cad8e10e16da3e3f888 (diff)
parentf8eeff1f9b16a0c7913cbcb0112cbf61259d574f (diff)
downloadperlweeklychallenge-club-35ac29b79c68eb7a11abd17baf01e60132326b37.tar.gz
perlweeklychallenge-club-35ac29b79c68eb7a11abd17baf01e60132326b37.tar.bz2
perlweeklychallenge-club-35ac29b79c68eb7a11abd17baf01e60132326b37.zip
Merge pull request #12103 from packy/master
Challenge 323 solutions by Packy Anderson
-rw-r--r--challenge-323/packy-anderson/README.md2
-rw-r--r--challenge-323/packy-anderson/blog.txt1
-rwxr-xr-xchallenge-323/packy-anderson/elixir/ch-1.exs43
-rwxr-xr-xchallenge-323/packy-anderson/elixir/ch-2.exs89
-rwxr-xr-xchallenge-323/packy-anderson/perl/ch-1.pl32
-rwxr-xr-xchallenge-323/packy-anderson/perl/ch-2.pl57
-rwxr-xr-xchallenge-323/packy-anderson/python/ch-1.py33
-rwxr-xr-xchallenge-323/packy-anderson/python/ch-2.py62
-rwxr-xr-xchallenge-323/packy-anderson/raku/ch-1.raku31
-rwxr-xr-xchallenge-323/packy-anderson/raku/ch-2.raku54
10 files changed, 403 insertions, 1 deletions
diff --git a/challenge-323/packy-anderson/README.md b/challenge-323/packy-anderson/README.md
index 766d853167..528307c718 100644
--- a/challenge-323/packy-anderson/README.md
+++ b/challenge-323/packy-anderson/README.md
@@ -23,4 +23,4 @@
## Blog Post
-[Perl Weekly Challenge: The array is rank, but the string is formatted](https://packy.dardan.com/b/VE)
+[Perl Weekly Challenge: Should five percent appear too small...](https://packy.dardan.com/b/Ve)
diff --git a/challenge-323/packy-anderson/blog.txt b/challenge-323/packy-anderson/blog.txt
new file mode 100644
index 0000000000..812fe5334f
--- /dev/null
+++ b/challenge-323/packy-anderson/blog.txt
@@ -0,0 +1 @@
+https://packy.dardan.com/b/Ve \ No newline at end of file
diff --git a/challenge-323/packy-anderson/elixir/ch-1.exs b/challenge-323/packy-anderson/elixir/ch-1.exs
new file mode 100755
index 0000000000..711e1d33c0
--- /dev/null
+++ b/challenge-323/packy-anderson/elixir/ch-1.exs
@@ -0,0 +1,43 @@
+#!/usr/bin/env elixir
+
+defmodule PWC do
+ defp fmt(num) do
+ String.pad_leading(to_string(num), 2)
+ end
+
+ def incDec([], x, explain), do:
+ {x, Enum.join(explain, "\n")}
+
+ def incDec([op | operations], x, explain) do
+ old_x = x
+ {x, o} = cond do
+ String.contains?(op, "++") ->
+ { x + 1, "+" }
+ true ->
+ { x - 1, "-" }
+ end
+ incDec(operations, x, explain ++ [
+ "Operation \"#{op}\" => #{fmt(old_x)} #{o} 1 => #{fmt(x)}"
+ ])
+ end
+
+ def incDec(operations) do
+ incDec(operations, 0, [])
+ end
+
+ def solution(operations) do
+ display = "\"" <> Enum.join(operations, "\", \"") <> "\""
+ IO.puts("Input: @operations = (#{display})")
+ {output, explain} = incDec(operations)
+ IO.puts("Output: #{output}\n\n#{explain}")
+ end
+end
+
+IO.puts("Example 1:")
+PWC.solution(["--x", "x++", "x++"])
+
+IO.puts("\nExample 2:")
+PWC.solution(["x++", "++x", "x++"])
+
+IO.puts("\nExample 3:")
+PWC.solution(["x++", "++x", "--x", "x--"])
diff --git a/challenge-323/packy-anderson/elixir/ch-2.exs b/challenge-323/packy-anderson/elixir/ch-2.exs
new file mode 100755
index 0000000000..5321ca5897
--- /dev/null
+++ b/challenge-323/packy-anderson/elixir/ch-2.exs
@@ -0,0 +1,89 @@
+#!/usr/bin/env elixir
+
+defmodule PWC do
+ defp fmt(num) do
+ cond do
+ num == 0 ->
+ 0 # don't format a zero value
+ true ->
+ :erlang.float_to_binary(num, [decimals: 2])
+ end
+ end
+
+ defp plusJoin(arr), do:
+ Enum.join(arr, " + ")
+
+ def taxAmt([], _, _, operations, subtotals, total) do
+ # there's no more brackets, return the summary
+ {
+ total,
+ "Total Tax => #{plusJoin(operations)}\n" <>
+ " => #{plusJoin(subtotals)}\n" <>
+ " => #{fmt(total)}"
+ }
+ end
+
+ def taxAmt(_, income, _, operations, subtotals, total)
+ when income == 0 do
+ # there's no more income to tax, skip to the end
+ taxAmt([], 0, 0, operations, subtotals, total)
+ end
+
+ def taxAmt([tax | remaining], income, last_max, operations,
+ subtotals, total) do
+ # the maximum amount to tax at this rate is the first
+ # element of the tax bracket; but we need to adjust this
+ # amount to be relative to the amount of last bracket
+ max = List.first(tax) - last_max
+ # the tax rate is the second element of the bracket
+ rate = List.last(tax)
+ # the amount to be taxed at this rate
+ amt = min(income, max)
+ # calculate the tax
+ tax = amt * rate/100
+
+ taxAmt(
+ remaining,
+ # we've just taxed amt, so remove it from income
+ income - amt,
+ # adjust the last rate for the next loop
+ max + last_max,
+ # save the steps so we can display them at the end
+ operations ++ ["(#{amt} * #{rate}/100)"],
+ # make sure we display to 100ths place
+ # if we hace a non-zero tax amount
+ subtotals ++ ["#{fmt(tax)}"],
+ total + tax
+ )
+ end
+
+ def taxAmt(income, tax) do
+ if income == 0 do
+ { 0, "" } # special case
+ else
+ taxAmt(tax, income, 0, [], [], 0)
+ end
+ end
+
+ defp fmtArray(t, arr) do
+ arr = arr ++ [ "[#{List.first(t)},#{List.last(t)}]" ]
+ { t, arr }
+ end
+
+ def solution(income, tax) do
+ {_, brackets} = Enum.map_reduce(tax, [], &fmtArray/2)
+ display = Enum.join(brackets, ", ")
+ IO.puts("Input: $income = #{income}, @tax = (#{display})")
+ {total, explain} = taxAmt(income, tax)
+ IO.puts("Output: #{total}\n\n#{explain}")
+ end
+end
+
+IO.puts("Example 1:")
+PWC.solution(10, [[3, 50], [7, 10], [12,25]])
+
+IO.puts("\nExample 2:")
+PWC.solution(2, [[1, 0], [4, 25], [5,50]])
+
+IO.puts("\nExample 3:")
+PWC.solution(0, [[2, 50],])
diff --git a/challenge-323/packy-anderson/perl/ch-1.pl b/challenge-323/packy-anderson/perl/ch-1.pl
new file mode 100755
index 0000000000..3ec5d260c9
--- /dev/null
+++ b/challenge-323/packy-anderson/perl/ch-1.pl
@@ -0,0 +1,32 @@
+#!/usr/bin/env perl
+use v5.40;
+
+sub incDec(@operations) {
+ my ($x, $old_x, $o) = (0, 0, q{});
+ my @explain;
+ for my $op ( @operations ) {
+ $x = ($op =~ /\+\+/) ? $x + 1 : $x - 1;
+ $o = ($op =~ /\+\+/) ? '+' : '-';
+ push @explain,
+ sprintf 'Operation "%s" => %2d %s 1 => %2d',
+ $op, $old_x, $o, $x
+ ;
+ $old_x = $x;
+ }
+ return ($x, join("\n", @explain));
+}
+
+sub solution($operations) {
+ say 'Input: @operations = ("' . join('", "', @$operations) . '")';
+ my ($output, $explain) = incDec(@$operations);
+ say "Output: $output\n\n$explain";
+}
+
+say "Example 1:";
+solution(["--x", "x++", "x++"]);
+
+say "\nExample 2:";
+solution(["x++", "++x", "x++"]);
+
+say "\nExample 3:";
+solution(["x++", "++x", "--x", "x--"]);
diff --git a/challenge-323/packy-anderson/perl/ch-2.pl b/challenge-323/packy-anderson/perl/ch-2.pl
new file mode 100755
index 0000000000..1239856bf6
--- /dev/null
+++ b/challenge-323/packy-anderson/perl/ch-2.pl
@@ -0,0 +1,57 @@
+#!/usr/bin/env perl
+use v5.40;
+
+use List::AllUtils qw( min sum );
+
+sub taxAmt($income, @tax) {
+ return (0, "") if $income == 0; # special case
+
+ my $last_max = 0;
+ my @operations;
+ my @subtotals;
+ for my $bracket (@tax) {
+ my($max, $rate) = @$bracket;
+ # adjust the maximum amount at this rate
+ # to be relative to the last rate
+ $max -= $last_max;
+ # the amount to be taxed at this rate
+ my $amt = min($income, $max);
+ my $tax = $amt * $rate/100;
+ # make sure we display to 100ths place
+ # if we hace a non-zero tax amount
+ $tax = sprintf '%0.2f', $tax if $tax > 0;
+ # save the steps so we can display them at the end
+ push @operations, "($amt * $rate/100)";
+ push @subtotals, $tax;
+ # we've just taxed $amt, so remove it from $income
+ $income -= $amt;
+ # adjust the last rate for the next loop
+ $last_max += $max;
+ # bail if there's no more income
+ last if $income <= 0;
+ }
+ my $total = sum @subtotals;
+ $total = sprintf '%0.2f', $total if $total > 0;
+ my $explain = "Total Tax => " . join(' + ', @operations) . "\n"
+ . " => " . join(' + ', @subtotals) . "\n"
+ . " => $total";
+
+ return $total, $explain;
+}
+
+sub solution($income, $tax) {
+ my @display = map { "[" . join(',', @$_) . "]" } @$tax;
+ say "Input: \$income = $income, "
+ . "\@tax = (" . join(', ', @display) . ")";
+ my ($output, $explain) = taxAmt($income, @$tax);
+ say "Output: $output\n\n$explain";
+}
+
+say "Example 1:";
+solution(10, [[3, 50], [7, 10], [12,25]]);
+
+say "\nExample 2:";
+solution(2, [[1, 0], [4, 25], [5,50]]);
+
+say "\nExample 3:";
+solution(0, [[2, 50],]);
diff --git a/challenge-323/packy-anderson/python/ch-1.py b/challenge-323/packy-anderson/python/ch-1.py
new file mode 100755
index 0000000000..5cbccba4aa
--- /dev/null
+++ b/challenge-323/packy-anderson/python/ch-1.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+
+def incDec(operations):
+ x = 0
+ old_x = 0
+ o = ''
+ explain = []
+ for op in operations:
+ x = x + 1 if "++" in op else x - 1
+ o = '+' if "++" in op else '-'
+ explain.append(
+ 'Operation "{}" => {:2d} {} 1 => {:2d}'.format(
+ op, old_x, o, x
+ )
+ )
+ old_x = x
+ return x, "\n".join(explain)
+
+def solution(operations):
+ display = '"' + '", "'.join(operations) + '"'
+ print(f'Input: @operations = ({display})')
+ output, explain = incDec(operations)
+ print(f'Output: {output}\n\n{explain}')
+
+
+print('Example 1:')
+solution(["--x", "x++", "x++"])
+
+print('\nExample 2:')
+solution(["x++", "++x", "x++"])
+
+print('\nExample 3:')
+solution(["x++", "++x", "--x", "x--"])
diff --git a/challenge-323/packy-anderson/python/ch-2.py b/challenge-323/packy-anderson/python/ch-2.py
new file mode 100755
index 0000000000..c5c646192d
--- /dev/null
+++ b/challenge-323/packy-anderson/python/ch-2.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+
+def fmt(num):
+ if num > 0:
+ # display to 100ths place
+ return '{:0.2f}'.format(num)
+ else:
+ # format it as a string
+ return f"{int(num)}"
+
+def taxAmt(income, tax):
+ if income == 0:
+ return 0, "" # special case
+
+ last_max = 0
+ total = 0
+ operations = []
+ subtotals = []
+ for max_income, rate in tax:
+ # adjust the maximum amount at this rate
+ # to be relative to the last rate
+ max_income -= last_max
+ # the amount to be taxed at this rate
+ amt = min(income, max_income)
+ tax = amt * rate/100
+ total += tax
+ # make sure we display to 100ths place
+ # if we hace a non-zero tax amount
+ tax = fmt(tax)
+ # save the steps so we can display them at the end
+ operations.append(f"({amt} * {rate}/100)")
+ subtotals.append(tax)
+ # we've just taxed $amt, so remove it from $income
+ income -= amt
+ # adjust the last rate for the next loop
+ last_max += max_income
+ # bail if there's no more income
+ if income <= 0: break
+
+ return (
+ total,
+ "Total Tax => " + ' + '.join(operations) + "\n" +
+ " => " + ' + '.join(subtotals) + "\n" +
+ " => " + fmt(total)
+ )
+
+def solution(income, tax):
+ brackets = [ f"[{t[0]},{t[1]}]" for t in tax ]
+ display = ", ".join(brackets)
+ print(f'Input: $income = {income}, @tax = ({display})')
+ output, explain = taxAmt(income, tax)
+ print(f'Output: {output}\n\n{explain}')
+
+
+print('Example 1:')
+solution(10, [[3, 50], [7, 10], [12,25]])
+
+print('\nExample 2:')
+solution(2, [[1, 0], [4, 25], [5,50]])
+
+print('\nExample 3:')
+solution(0, [[2, 50],])
diff --git a/challenge-323/packy-anderson/raku/ch-1.raku b/challenge-323/packy-anderson/raku/ch-1.raku
new file mode 100755
index 0000000000..213e6498c7
--- /dev/null
+++ b/challenge-323/packy-anderson/raku/ch-1.raku
@@ -0,0 +1,31 @@
+#!/usr/bin/env raku
+use v6;
+
+sub incDec(@operations) {
+ my ($x, $old_x, $o) = (0, 0, q{});
+ my @explain;
+ for @operations -> $op {
+ ($x, $o) = ($op ~~ /\+\+/) ?? ($x + 1, '+') !! ($x - 1, '-');
+ @explain.push(
+ sprintf 'Operation "%s" => %2d %s 1 => %2d',
+ $op, $old_x, $o, $x
+ );
+ $old_x = $x;
+ }
+ return ($x, @explain.join("\n"));
+}
+
+sub solution(@operations) {
+ say 'Input: @operations = ("' ~ @operations.join('", "') ~ '")';
+ my ($output, $explain) = incDec(@operations);
+ say "Output: $output\n\n$explain";
+}
+
+say "Example 1:";
+solution(["--x", "x++", "x++"]);
+
+say "\nExample 2:";
+solution(["x++", "++x", "x++"]);
+
+say "\nExample 3:";
+solution(["x++", "++x", "--x", "x--"]);
diff --git a/challenge-323/packy-anderson/raku/ch-2.raku b/challenge-323/packy-anderson/raku/ch-2.raku
new file mode 100755
index 0000000000..d5d2e3b63e
--- /dev/null
+++ b/challenge-323/packy-anderson/raku/ch-2.raku
@@ -0,0 +1,54 @@
+#!/usr/bin/env raku
+use v6;
+
+sub taxAmt($income is copy, @tax) {
+ return (0, "") if $income == 0; # special case
+
+ my $last_max = 0;
+ my @operations;
+ my @subtotals;
+ for @tax -> ($max is copy, $rate) {
+ # adjust the maximum amount at this rate
+ # to be relative to the last rate
+ $max -= $last_max;
+ # the amount to be taxed at this rate
+ my $amt = min($income, $max);
+ my $tax = $amt * $rate/100;
+ # make sure we display to 100ths place
+ # if we hace a non-zero tax amount
+ $tax = sprintf '%0.2f', $tax if $tax > 0;
+ # save the steps so we can display them at the end
+ @operations.push("($amt * $rate/100)");
+ @subtotals.push($tax);
+ # we've just taxed $amt, so remove it from $income
+ $income -= $amt;
+ # adjust the last rate for the next loop
+ $last_max += $max;
+ # bail if there's no more income
+ last if $income <= 0;
+ }
+ my $total = @subtotals.sum;
+ $total = sprintf '%0.2f', $total if $total > 0;
+ my $explain = "Total Tax => " ~ @operations.join(' + ') ~ "\n"
+ ~ " => " ~ @subtotals.join(' + ') ~ "\n"
+ ~ " => $total";
+
+ return $total, $explain;
+}
+
+sub solution($income, @tax) {
+ my @display = @tax.map({ "[" ~ $_.join(',') ~ "]" });
+ say "Input: \$income = $income, "
+ ~ "\@tax = (" ~ @display.join(', ') ~ ")";
+ my ($output, $explain) = taxAmt($income, @tax);
+ say "Output: $output\n\n$explain";
+}
+
+say "Example 1:";
+solution(10, [[3, 50], [7, 10], [12,25]]);
+
+say "\nExample 2:";
+solution(2, [[1, 0], [4, 25], [5,50]]);
+
+say "\nExample 3:";
+solution(0, [[2, 50],]);