Orders Matter and Order Matters: Weekly Challenge #323
Welcome to Weekly Challenge #323
323 is a semiprime, a Lucas pseudoprime and a Fibonacci semiprime.
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
orx++
: increment by 1--x
orx--
: decrement by 1
Let’s Talk About It
An aside before we go in: increment and decrement as prefix differ whether it comes before or after the number. Consider the following code block:
my $i = 1;
my $j = $i++;
my $k = ++$i;
say join ' ', $i,$j,$k; # 3 1 3
$i
equals 3
, because it gets incremented twice. $j
gets assigned before the increment, because $i
comes before ++
. $k
gets assigned after the increment, so $i
becomes 3
, then $k
becomes $i
. There’s no assignment like that going on in in the midst of the operations, so it isn’t germane to the problem, but it’s an interesting piece of syntax that is easy to forget.
Anyway, I loop through the operations and increment and decrement based on whether the operation contains ++
or --
, then return the result.
The cool way would be to use scalar grep
to get a count of the plus and minuses, then return 0 + $plus - $minus
. It’s only slightly shorter, and probably similarly fast.
Show Me The Code!
#!/usr/bin/env perl
use strict;
use warnings;
use experimental qw{ say state postderef signatures };
use List::Util qw{ sum0 };
my @examples = (
[ "--x", "x++", "x++" ],
[ "x++", "++x", "x++" ],
[ "x++", "++x", "--x", "x--" ],
);
for my $example (@examples) {
my $operations = join ', ', map { qq{"$_"} } $example->@*;
my $output = increment_decrement($example->@*);
say <<"END";
Input: \@operations = ($operations)
Output: $output
END
}
sub increment_decrement (@operations) {
my $value = 0;
for my $op ( @operations ) {
$value ++ if $op =~ /\+\+/mx;
$value -- if $op =~ /\-\-/mx;
}
return $value;
}
$ ./ch-1.pl
Input: @operations = ("--x", "x++", "x++")
Output: 1
Input: @operations = ("x++", "++x", "x++")
Output: 3
Input: @operations = ("x++", "++x", "--x", "x--")
Output: 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.
Let’s Talk About It
We are taxed at the rate of a bracket for the income within a bracket. In the first example, the income is 10
.
- The first bracket is between
0
and3
, and the tax rate applies to the first3
whatevers from the income of 10. - The second bracket is between
3
and7
, and the tax rate applies to everything above7
and above3
, which, again, is totally covered by the income, so that’s4
. - The third bracket is between
7
and12
, and that’ just between7
and10
for us, and that’s3
.
Everything else is just multiplication and addition.
Show Me The Code!
#!/usr/bin/env perl
use strict;
use warnings;
use experimental qw{ say state postderef signatures };
use List::Util qw{ uniq };
my @examples = (
{ income => 10, tax => [ [ 3, 50 ], [ 7, 10 ], [ 12, 25 ] ] },
{ income => 2, tax => [ [ 1, 0 ], [ 4, 25 ], [ 5, 50 ] ] },
{ income => 0, tax => [ [ 2, 50 ] ] },
);
for my $example (@examples) {
my $income = $example->{income};
my @tax = $example->{tax}->@*;
my $tax = join ', ', map { qq{[ $_ ]} }
map { join ', ', $_->@* } @tax;
my $output = tax_amount($example);
say <<"END";
Input: \@income = $income,
\@tax = ($tax)
Output: $output
END
}
sub tax_amount($example) {
my $total = 0;
my $income = $example->{income};
my @tax = $example->{tax}->@*;
for my $i ( 0 .. $#tax ) {
my $bracket = $tax[$i];
my ( $upto, $rate ) = $bracket->@*;
my $prev = 0;
$prev = $i - 1 >= 0 ? $tax[ $i - 1 ][0] : 0;
my $subset = 0;
if ( $income >= $upto ) { $subset = $upto - $prev; }
elsif ( $income >= $prev ) { $subset = $income - $prev; }
my $subtax = $subset * ( $rate / 100 );
$total += $subtax;
}
return sprintf '%.02f', $total;
}
$ ./ch-2.pl
Input: @income = 10,
@tax = ([ 3, 50 ], [ 7, 10 ], [ 12, 25 ])
Output: 2.65
Input: @income = 2,
@tax = ([ 1, 0 ], [ 4, 25 ], [ 5, 50 ])
Output: 0.25
Input: @income = 0,
@tax = ([ 2, 50 ])
Output: 0.00