aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2025-05-30 23:41:38 +0100
committerGitHub <noreply@github.com>2025-05-30 23:41:38 +0100
commit70e2f3320050bf193bf74cf1a05b65fe62590004 (patch)
treec0c031f90e6fdade6bcf8731dad6b204b33a2582
parent9321ae09618dc52f7f956db35a9797b98acb34c4 (diff)
parentd2e78ad749aafa3f568cb7a3322be4d5020f4381 (diff)
downloadperlweeklychallenge-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.txt1
-rwxr-xr-xchallenge-323/jo-37/perl/ch-1.pl96
-rwxr-xr-xchallenge-323/jo-37/perl/ch-2.pl122
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;
+}