diff options
| author | Mohammad Sajid Anwar <Mohammad.Anwar@yahoo.com> | 2025-05-30 23:41:38 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-30 23:41:38 +0100 |
| commit | 70e2f3320050bf193bf74cf1a05b65fe62590004 (patch) | |
| tree | c0c031f90e6fdade6bcf8731dad6b204b33a2582 | |
| parent | 9321ae09618dc52f7f956db35a9797b98acb34c4 (diff) | |
| parent | d2e78ad749aafa3f568cb7a3322be4d5020f4381 (diff) | |
| download | perlweeklychallenge-club-70e2f3320050bf193bf74cf1a05b65fe62590004.tar.gz perlweeklychallenge-club-70e2f3320050bf193bf74cf1a05b65fe62590004.tar.bz2 perlweeklychallenge-club-70e2f3320050bf193bf74cf1a05b65fe62590004.zip | |
Merge pull request #12105 from jo-37/contrib
Solutions to challenge 323
| -rw-r--r-- | challenge-323/jo-37/blog.txt | 1 | ||||
| -rwxr-xr-x | challenge-323/jo-37/perl/ch-1.pl | 96 | ||||
| -rwxr-xr-x | challenge-323/jo-37/perl/ch-2.pl | 122 |
3 files changed, 219 insertions, 0 deletions
diff --git a/challenge-323/jo-37/blog.txt b/challenge-323/jo-37/blog.txt new file mode 100644 index 0000000000..2f9d93ee1f --- /dev/null +++ b/challenge-323/jo-37/blog.txt @@ -0,0 +1 @@ +https://github.sommrey.de/the-bears-den/2025/05/30/ch-323.html diff --git a/challenge-323/jo-37/perl/ch-1.pl b/challenge-323/jo-37/perl/ch-1.pl new file mode 100755 index 0000000000..4963dc1fe1 --- /dev/null +++ b/challenge-323/jo-37/perl/ch-1.pl @@ -0,0 +1,96 @@ +#!/usr/bin/perl + +use v5.26; +use Test2::V0 -no_srand; +use Test2::Tools::Subtest 'subtest_streamed'; +use Getopt::Long; +use experimental 'signatures'; + +use List::Util qw(reduce sum0); + + +### Options and Arguments + +my ($tests, $examples, $verbose); +GetOptions( + 'examples!' => \$examples, + 'tests!' => \$tests, + 'verbose!' => \$verbose, +) or usage(); + +run_tests($examples, $tests); # tests do not return + +usage() unless @ARGV; + +sub usage { + die <<~EOS; + $0 - increment decrement + + usage: $0 [-examples] [-tests] [-- op...] + + -examples + run the examples from the challenge + + -tests + run some tests + + op... + operations consisting of 'x++', '++x', 'x--' or '--x' + + EOS +} + + +### Input and Output + +say inc_dec(@ARGV); + + +### Implementation +# +# For details see: +# https://github.sommrey.de/the-bears-den/2025/05/30/ch-323.html#task-1 + + +sub inc_dec { + sum0 map /^(?=.{3}$)x?([-+])\1x?$/ && "${1}1", @_ +} + + +### Examples and Tests + +sub run_tests ($examples, $tests) { + return unless $examples || $tests; + + state sub run_example ($args, $expected, $name) { + my $result = inc_dec(@$args); + is $result, $expected, + "$name: (@$args) -> $expected"; + } + + plan 2; + + $examples ? subtest_streamed(examples => sub { + my @examples = ( + [["--x", "x++", "x++"], 1, 'example 1'], + [["x++", "++x", "x++"], 3, 'example 2'], + [["x++", "++x", "--x", "x--"], 0, 'example 3'], + ); + plan scalar @examples; + for (@examples) { + run_example @$_; + } + }) : pass 'skip examples'; + + $tests ? subtest_streamed(tests => sub { + plan 6; + is inc_dec(qw(++y y++)), 0, 'invalid inc'; + is inc_dec(qw(--y y--)), 0, 'invalid dec'; + is inc_dec(qw(+x x+)), 0, 'invalid inc'; + is inc_dec(qw(-x x-)), 0, 'invalid dec'; + is inc_dec(qw(++x++x)), 0, 'two in one'; + is inc_dec(qw(+-x)), 0, 'mixed'; + }) : pass 'skip tests'; + + exit; +} diff --git a/challenge-323/jo-37/perl/ch-2.pl b/challenge-323/jo-37/perl/ch-2.pl new file mode 100755 index 0000000000..1926fbbce2 --- /dev/null +++ b/challenge-323/jo-37/perl/ch-2.pl @@ -0,0 +1,122 @@ +#!/usr/bin/perl + +use v5.26; +use Test2::V0 '!float', float => {-as => 'float2'}, -no_srand; +use Test2::Tools::Subtest 'subtest_streamed'; +use Getopt::Long; +use experimental 'signatures'; + +use PDL; +use PDL::NiceSlice; + + +### Options and Arguments + +my ($tests, $examples, $verbose, $income); +GetOptions( + 'examples!' => \$examples, + 'tests!' => \$tests, + 'verbose!' => \$verbose, + 'income=f' => \$income, +) or usage(); + +run_tests($examples, $tests); # tests do not return + +usage() unless @ARGV == 1 && defined $income; + +sub usage { + die <<~EOS; + $0 - tax amount + + usage: $0 [-examples] [-tests] [-income I] [TAXES] + + -examples + run the examples from the challenge + + -tests + run some tests + + -income I + income + + TAXES + tax brackets in forms like 'u1, t1; u2, t2;...' or + '[u1, t1], [u2, t2],...' + + EOS +} + + +### Input and Output + +say tax_amount($income, tax_pp(shift)); + + +### Implementation +# +# For details see: +# https://github.sommrey.de/the-bears-den/2025/05/30/ch-323.html#task-2 + + +sub tax_pp { + my $tax = pdl @_; + $tax(1) /= 100; + my $low = pdl(0)->append($tax((0))); + + cat $low, + $tax((1))->append(pdl(0)), + pdl(0)->append((($low(1:-1) - $low(0:-2)) * $tax((1)))->cumusumover); +} + +sub tax_amount ($income, $tp) { + my $tax = $tp(vsearch_bin_inclusive($income, $tp(,(0)));-); + + sclr $tax(2) + $tax(1) * ($income - $tax(0)); +} + + +### Examples and Tests + +sub run_tests ($examples, $tests) { + return unless $examples || $tests; + + state sub run_example ($args, $expected, $name) { + my $result = tax_amount($args->[0], tax_pp($args->[1])); + is $result, float2($expected, precision => 2), + "$name: ($args->[0], (" . + (join ' ', map "[@$_]", $args->[1]->@*) . + ")) -> $expected"; + } + + plan 2; + + $examples ? subtest_streamed(examples => sub { + my @examples = ( + [[10, [[3, 50], [7, 10], [12,25]]], 2.65, 'example 1'], + [[2, [[1, 0], [4, 25], [5,50]]], .25, 'example 2'], + [[0, [[2, 50]]], 0, 'example 3'], + ); + plan scalar @examples; + for (@examples) { + run_example @$_; + } + }) : pass 'skip examples'; + + $tests ? subtest_streamed(tests => sub { + my @examples = ( + [2, 1, 'first slot'], + [3, 1.5, 'end of first slot'], + [5, 1.7, 'second slot'], + [7, 1.9, 'end of second slot'], + [12, 3.15, 'end of third slot'], + [14, 3.15, 'last slot'], + [2.6, 1.3, 'broken income'], + ); + my $tp = tax_pp([3, 50], [7, 10], [12,25]); + plan scalar @examples; + is tax_amount($_->[0], $tp), float2($_->[1], precision => 2), $_->[2] + for @examples; + }) : pass 'skip tests'; + + exit; +} |
