PWC 227

PWC 227

Challenge 1 (Friday 13th)

This challenge requires us to count the number of times Friday 13th occurs in a particular year.

I use Date::Manip. This module probably has easier ways to do this using a Date Range, but my approach is easy enough. My &friday_13th subroutine takes the year as input, throws an exception if it is outside the specified range (1753 to 9999), and then cycles through the 13th of each month, counting the Fridays.

use Date::Manip;

my $dateobj=Date::Manip::Date->new();

sub friday_13th {
    my ($year)=@_;
    my $retval=0;
    ( ($year > 9999) || ($year < 1753) ) &&
        die "Year should be between 1753 and 9999";

    map {
        ( ($dateobj->new_date("$year-$_-13")->printf('%w') ) == 5 ) &&
            $retval++;
    }
    1 .. 12;
    
    $retval;
}  


Challenge 2 (Roman Maths)

This challenge requires us to implement a calculator that parses infix math operations using roman numerals. 

There are several CPAN modules that do this. I use Math::Roman, which is the most full-featured. It is somewhat more full-featured than the task specification, which requires returning a ``non potest'' for operations that the Romans didn't know how to do (like go beyond 3999 or calculate fractions or write zero as a numeral). 

My subroutine takes the infix expression as input, verifies that it is valid, then checks for various situations where a 'non potest' or 'nulla' (zero in Latin) is called for, and finally evals the expression and returns the output if it is less than 4000.

use Math::Roman qw(roman);

sub roman_maths {
    my ($string)=@_;
    
    ($string =~ /([IVXLCMD]+)\s*([+-\/\*]\**)\s*([IVXLCMD]+)/)
        || die 'Invalid input';
     
     
     ( ($2 eq '-') && ($1 eq $3) ) && return 'nulla';
     
     ( ($2 eq '-') && ( roman($1) < roman($3) ) ) &&
        return 'non potest';
     
     ( ($2 eq '/') && ( (roman($1) % roman($3) ) > 0 ) ) &&
        return 'non potest';
        
     my $roman=eval("roman($1) $2 roman($3)");
     if ($roman > 3999) {
        return 'non potest';
     }
     else {
        return $roman;
    }
}

I realized too late that my input validation regex is not foolproof. It allows the expression to contain gibberish operators like '+*' or '***'. Anyway, inputs like these will throw an error a few steps later, when the expression is eval'd, so รงa va enfin.

Comments

Popular posts from this blog

PWC 258

PWC 253

PWC 251