Perl Weekly Challenge 323.
My solutions (task 1 and task 2 ) to the The Weekly Challenge - 323.
Task 1: Increment Decrement
Submitted by: Mohammad Sajid Anwar
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
Operation "--x" => 0 - 1 => -1
Operation "x++" => -1 + 1 => 0
Operation "x++" => 0 + 1 => 1
Example 2
Input: @operations = ("x++", "++x", "x++")
Output: 3
Example 3
Input: @operations = ("x++", "++x", "--x", "x--")
Output: 0
Operation "x++" => 0 + 1 => 1
Operation "++x" => 1 + 1 => 2
Operation "--x" => 2 - 1 => 1
Operation "x--" => 1 - 1 => 0
For the short answer I’ll ignore the actual name of the variable that is being incremented and decremented and I’ll assume the input is well formed. Thus, I only have to count how many increment and decrement operators there are and subtract them. The result fits a half-liner.
Example 1:
perl -E '
say "@ARGV -> ", (grep{/\+\+/}@ARGV)-(grep{/--/}@ARGV);
' -- --x x++ x++
Results:
--x x++ x++ -> 1
Example 2:
perl -E '
say "@ARGV -> ", (grep{/\+\+/}@ARGV)-(grep{/--/}@ARGV);
' -- x++ ++x x++
Results:
x++ ++x x++ -> 3
Example 3:
perl -E '
say "@ARGV -> ", (grep{/\+\+/}@ARGV)-(grep{/--/}@ARGV);
' -- x++ ++x --x x--
Results:
x++ ++x --x x-- -> 0
For the full code it would be more interesting if I allow different variables to be incremented/decremented. For simplicity I’ll assume variable names contain only alphabetical characters.
1 # Perl weekly challenge 323
2 # Task 1:
3 #
4 # See https://wlmb.github.io/2025/05/26/PWC323/#task-1-
5 use v5.36;
6 die <<~"FIN" unless @ARGV;
7 Usage: $0 E1 E2...
8 to apply increment and decrement expressions ~En~
9 of the form ++x, x++ --x, x--
10 where x is the name of a variable
11 FIN
12 my %vars;
13 for(@ARGV){
14 $vars{$1}//=0, $vars{$1}++, next if /^\+\+([[:alpha:]]+)$/;
15 $vars{$1}//=0, $vars{$1}--, next if /^--([[:alpha:]]+)$/;
16 $vars{$1}//=0, $vars{$1}++, next if /^([[:alpha:]]+)\+\+$/;
17 $vars{$1}//=0, $vars{$1}--, next if /^([[:alpha:]]+)--$/;
18 die "Wrong format: $_";
19 }
20 print "@ARGV -> ";
21 print "$_=$vars{$_} " for keys %vars;
22 print "\n";
Examples:
./ch-1.pl --x x++ x++
./ch-1.pl x++ ++x x++
./ch-1.pl x++ ++x --x x--
Results:
--x x++ x++ -> x=1
x++ ++x x++ -> x=3
x++ ++x --x x-- -> x=0
Example with more variables:
./ch-1.pl --x y++ z++ x++ ++y ++z x++ y++ --z z--
Results:
--x y++ z++ x++ ++y ++z x++ y++ --z z-- -> y=3 x=1 z=0
Task 2: Tax Amount
Submitted by: Mohammad Sajid Anwar
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: 1.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)
=> 0 + 0.25
=> 0.25
Example 3
Input: $income = 0, @tax = ([2, 50])
Output: 0
In the first example, the lowest incomes gets the highest tax, and the highest incomes, those above the last bracket, are not taxed at all. This strange scheme is becomming common! I would have expected a last bracket without an upper bound. But anyway, to solve the problem I have to find how much of the income is within each bracket and tax it accordingly. The code fits a two liner:
Example 1:
perl -MList::Util=min -E '
print "I=", $x=$i=shift, " tax=";$l=0;for my($h,$p)(@ARGV){print "[$h,$p]";
$r=$h-$l;$l=$h;next if $x<0;$q=min($x,$r);$t+=$q*$p/100;$x-=$q}say "-> $t";
' 10 3 50 7 10 12 25
Results:
I=10 tax=[3,50][7,10][12,25]-> 2.65
Example 2:
perl -MList::Util=min -E '
print "I=", $x=$i=shift, " tax=";$l=0;for my($h,$p)(@ARGV){print "[$h,$p]";
$r=$h-$l;$l=$h;next if $x<0;$q=min($x,$r);$t+=$q*$p/100;$x-=$q}say "-> $t";
' 2 1 0 4 25 5 50
Results:
I=2 tax=[1,0][4,25][5,50]-> 0.25
Example 3:
perl -MList::Util=min -E '
print "I=", $x=$i=shift, " tax=";$l=0;for my($h,$p)(@ARGV){print "[$h,$p]";
$r=$h-$l;$l=$h;next if $x<0;$q=min($x,$r);$t+=$q*$p/100;$x-=$q}say "-> $t";
' 0 2 50
Results:
I=0 tax=[2,50]-> 0
The full code is:
1 # Perl weekly challenge 323
2 # Task 2: Tax Amount
3 #
4 # See https://wlmb.github.io/2025/05/26/PWC323/#task-2-tax-amount
5 use v5.36;
6 use List::Util qw(min);
7 die <<~"FIN" unless @ARGV && @ARGV%2==1;
8 Usage: $0 I M1 P1 M2 P2...
9 to compute taxes corresponding to income I where Mn is the maximum
10 income in bracket n which is taxed with a percentage Pn
11 FIN
12 my $income = shift;
13 my $low = 0; # lowest bound of current bracket
14 my @tax;
15 my $result=0;
16 my $remaining = $income;
17 for my ($high, $percentage)(@ARGV){
18 push @tax, [$high, $percentage];
19 my $range=$high-$low;
20 $low=$high; # update for next iteration
21 next if $remaining < 0;
22 my $taxable = min($remaining, $range);
23 $result += $taxable*$percentage/100;
24 $remaining -= $taxable;
25 }
26 say "income=$income, tax=", join(", ", map{"[@$_]"} @tax)," -> $result";
Example:
./ch-2.pl 10 3 50 7 10 12 25
./ch-2.pl 2 1 0 4 25 5 50
./ch-2.pl 0 2 50
Results:
income=10, tax=[3 50], [7 10], [12 25] -> 2.65
income=2, tax=[1 0], [4 25], [5 50] -> 0.25
income=0, tax=[2 50] -> 0