aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-323/bob-lied/README.md6
-rw-r--r--challenge-323/bob-lied/perl/ch-1.pl68
-rw-r--r--challenge-323/bob-lied/perl/ch-2.pl113
3 files changed, 184 insertions, 3 deletions
diff --git a/challenge-323/bob-lied/README.md b/challenge-323/bob-lied/README.md
index dbc624cc0a..0552741691 100644
--- a/challenge-323/bob-lied/README.md
+++ b/challenge-323/bob-lied/README.md
@@ -1,4 +1,4 @@
-# Solutions to weekly challenge 322 by Bob Lied
+# Solutions to weekly challenge 323 by Bob Lied
-## [PWC](https://perlweeklychallenge.org/blog/perl-weekly-challenge-322/)
-## [GitHub](https://github.com/boblied/perlweeklychallenge-club/tree/master/challenge-322/bob-lied)
+## [PWC](https://perlweeklychallenge.org/blog/perl-weekly-challenge-323/)
+## [GitHub](https://github.com/boblied/perlweeklychallenge-club/tree/master/challenge-323/bob-lied)
diff --git a/challenge-323/bob-lied/perl/ch-1.pl b/challenge-323/bob-lied/perl/ch-1.pl
new file mode 100644
index 0000000000..3ffa3c3523
--- /dev/null
+++ b/challenge-323/bob-lied/perl/ch-1.pl
@@ -0,0 +1,68 @@
+#!/usr/bin/env perl
+# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu:
+#=============================================================================
+# Copyright (c) 2025, Bob Lied
+#=============================================================================
+# ch-1.pl Perl Weekly Challenge 323 Task 1 Increment Decrement
+#=============================================================================
+# You are given a list of operations. Write a script to return the final
+# value after performing the given operations in order. The initial value
+# is always 0. Possible Operations:
+# ++x or x++: increment by 1
+# --x or x--: decrement by 1
+# Example 1 Input: @operations = ("--x", "x++", "x++")
+# Output: 1
+# Example 2 Input: @operations = ("x++", "++x", "x++")
+# Output: 3
+# Example 3 Input: @operations = ("x++", "++x", "--x", "x--")
+# Output: 0
+#=============================================================================
+
+use v5.40;
+use List::Util qw/sum0/;
+
+
+use Getopt::Long;
+my $Verbose = false;
+my $DoTest = false;
+my $Benchmark = 0;
+
+GetOptions("test" => \$DoTest, "verbose" => \$Verbose, "benchmark:i" => \$Benchmark);
+my $logger;
+{
+ use Log::Log4perl qw(:easy);
+ Log::Log4perl->easy_init({ level => ($Verbose ? $DEBUG : $INFO ),
+ layout => "%d{HH:mm:ss.SSS} %p{1} %m%n" });
+ $logger = Log::Log4perl->get_logger();
+}
+#=============================================================================
+
+exit(!runTest()) if $DoTest;
+exit( runBenchmark($Benchmark) ) if $Benchmark;
+
+say incdec(@ARGV);
+
+#=============================================================================
+sub incdec(@operations)
+{
+ return sum0 map { substr($_,1,1) eq '+' ? 1 : -1 } @operations;
+}
+
+sub runTest
+{
+ use Test2::V0;
+
+ is( incdec("--x", "x++", "x++"), 1, "Example 1");
+ is( incdec("x++", "++x", "x++"), 3, "Example 2");
+ is( incdec("x++", "++x", "--x", "x--"), 0, "Example 3");
+ done_testing;
+}
+
+sub runBenchmark($repeat)
+{
+ use Benchmark qw/cmpthese/;
+
+ cmpthese($repeat, {
+ label => sub { },
+ });
+}
diff --git a/challenge-323/bob-lied/perl/ch-2.pl b/challenge-323/bob-lied/perl/ch-2.pl
new file mode 100644
index 0000000000..91dc1d2367
--- /dev/null
+++ b/challenge-323/bob-lied/perl/ch-2.pl
@@ -0,0 +1,113 @@
+#!/usr/bin/env perl
+# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu:
+#=============================================================================
+# Copyright (c) 2025, Bob Lied
+#=============================================================================
+# ch-2.pl Perl Weekly Challenge 323 Task 2 Tax Amount
+#=============================================================================
+# You are given an income amount and tax brackets.
+# Write a script to calculate the total tax amount.
+# Example 1
+# Input: $income = 10, @tax = ([3, 50], [7, 10], [12,25])
+# Output: 2.65
+# 1st tax bracket upto 3, tax is 50%.
+# 2nd tax bracket upto 7, tax is 10%.
+# 3rd tax bracket upto 12, tax is 25%.
+# Total Tax => (3 * 50/100) + (4 * 10/100) + (3 * 25/100)
+# => 1.50 + 0.40 + 0.75
+# => 2.65
+# Example 2
+# Input: $income = 2, @tax = ([1, 0], [4, 25], [5,50])
+# Output: 0.25
+# Total Tax => (1 * 0/100) + (1 * 25/100)
+# Example 3
+# Input: $income = 0, @tax = ([2, 50])
+# Output: 0
+#=============================================================================
+
+use v5.40;
+use List::AllUtils qw/min pairs/;
+
+use Getopt::Long;
+my $Verbose = false;
+my $DoTest = false;
+my $Benchmark = 0;
+
+GetOptions("test" => \$DoTest, "verbose" => \$Verbose, "benchmark:i" => \$Benchmark);
+my $logger;
+{
+ use Log::Log4perl qw(:easy);
+ Log::Log4perl->easy_init({ level => ($Verbose ? $DEBUG : $INFO ),
+ layout => "%d{HH:mm:ss.SSS} %p{1} %m%n" });
+ $logger = Log::Log4perl->get_logger();
+}
+#=============================================================================
+
+exit(!runTest()) if $DoTest;
+exit( runBenchmark($Benchmark) ) if $Benchmark;
+
+my $INCOME = shift;
+say taxAmount($INCOME, pairs @ARGV);
+
+#=============================================================================
+sub taxAmount($income, @tax)
+{
+ my $tax = 0;
+
+ # Sort brackets by threshold amount.
+ @tax = sort { $a->[0] <=> $b->[0] } @tax;
+
+ # Find overlapping ranges between income and bracket.
+ my $bracketMin = 0;
+ foreach ( @tax )
+ {
+ my $bracketMax = $_->[0];
+ my $rate = $_->[1] / 100.0;
+
+ if ( $income > $bracketMin )
+ {
+ my $amount = min($income, $bracketMax) - $bracketMin;
+ $tax += $amount * $rate;
+ }
+ $bracketMin = $bracketMax;
+ }
+ return $tax;
+}
+
+sub runTest
+{
+ use Test2::V0;
+
+ is( taxAmount(10, ([3, 50], [7, 10], [12,25])), 2.65, "Example 1");
+ is( taxAmount( 2, ([1, 0], [4, 25], [ 5,50])), 0.25, "Example 2");
+ is( taxAmount( 0, ([2, 50]) ), 0.00, "Example 3");
+
+ is( taxAmount(100_000, ([ 23_850, 10],
+ [ 96_950, 12],
+ [206_700, 22],
+ [394_600, 24],
+ [501_050, 32],
+ [751_600, 35],
+ [10_000_000_000, 37]) ),
+ 11_828, "US 2025 Married filing jointly");
+
+ is( taxAmount(100_000, ([ 11_925, 10],
+ [ 48_475, 12],
+ [103_350, 22],
+ [197_300, 24],
+ [250_525, 32],
+ [626_350, 35],
+ [10_000_000_000, 37]) ),
+ 16_914, "US 2025 Single");
+
+ done_testing;
+}
+
+sub runBenchmark($repeat)
+{
+ use Benchmark qw/cmpthese/;
+
+ cmpthese($repeat, {
+ label => sub { },
+ });
+}