diff options
| -rw-r--r-- | challenge-047/simon-proctor/raku/ch-1.p6 | 73 | ||||
| -rw-r--r-- | challenge-047/simon-proctor/raku/ch-1.raku | 73 | ||||
| -rw-r--r-- | challenge-047/simon-proctor/raku/ch-2.p6 | 10 | ||||
| -rw-r--r-- | challenge-047/simon-proctor/raku/ch-2.raku | 10 |
4 files changed, 166 insertions, 0 deletions
diff --git a/challenge-047/simon-proctor/raku/ch-1.p6 b/challenge-047/simon-proctor/raku/ch-1.p6 new file mode 100644 index 0000000000..0211d9e47e --- /dev/null +++ b/challenge-047/simon-proctor/raku/ch-1.p6 @@ -0,0 +1,73 @@ +#!/usr/bin/env perl6 + +use v6.d; + +# Cribbing my code from challenge 10 +# Note that I'm skipping the Unicode values this time for size mostly +subset RomanStr of Str where * ~~ /^ <[M C D X L V I]>+ $/; +subset RomanInt of Int where 0 < * < 3001; +subset Operator of Str where * ~~ /^ ( "*" | "+" | "-" | "/" ) $ /; + +#| Given two roman numerals and an operation on them +#| produce the result. +#| Note that division only works where the first value is greater than the second. +#| Results over 3000 and non valid numerals will return an error +multi sub MAIN ( + RomanStr $i, Operator $operator, RomanStr $j +) { + say "$i $operator $j = {perf-op( $operator, $i, $j )}"; +} + +#| Single String of operation to parse +multi sub MAIN ( + Str $compound where m!^ (<[M C D X L V I]>+) " "? ( "*" | "+" | "-" | "/" ) " "? (<[M C D X L V I]>+) $!; +) { + MAIN( $0.Str, $1.Str, $2.Str ); +} + +multi sub perf-op( "+", RomanStr $i, RomanStr $j ) { + to-roman( from-roman($i) + from-roman($j) ); +} + +multi sub perf-op( "-", RomanStr $i, RomanStr $j ) { + to-roman( from-roman($i) - from-roman($j) ); +} + +multi sub perf-op( "*", RomanStr $i, RomanStr $j ) { + to-roman( from-roman($i) * from-roman($j) ); +} + +multi sub perf-op( "/", RomanStr $i, RomanStr $j where { from-roman($i) > from-roman($j) } ) { + my $res = from-roman($i) div from-roman($j); + my $rem = from-roman($i) % from-roman($j); + to-roman($res) ~ ( $rem ?? " remainder {to-roman($rem)}" !! "" ); +} + +multi sub perf-op(*@){ die "Invalid operation. Did you try and create a fraction?" } + +sub to-roman (RomanInt $number is copy) { + my $out = ""; + my @values = ( :1000M, :900CM, :500D, :400CD, :100C, :90XC, :50L, :40XL, :10X, :9IX, :5V, :4IV, :1I ); + for @values -> $pair { + my ( $sigil, $num ) = $pair.kv; + while ( $number >= $num ) { + $out ~= $sigil; + $number -= $num; + } + } + + $out; +} + +sub from-roman( RomanStr $roman is copy ) { + my %roman-map = (:1000M, :900CM, :500D, :400CD, :100C, :90XC, :50L, :40XL, :10X, :9IX, :5V, :4IV, :1I ); + + my $out = 0; + while my $match = $roman ~~ s!^ "M" | "CM" | "D" | "CD" | + "C" | "XC" | "L" | "XL" | + "X" | "IX" | "V" | "IV" | "I" + !! { + $out += %roman-map{$match}; + } + $out; +} diff --git a/challenge-047/simon-proctor/raku/ch-1.raku b/challenge-047/simon-proctor/raku/ch-1.raku new file mode 100644 index 0000000000..0211d9e47e --- /dev/null +++ b/challenge-047/simon-proctor/raku/ch-1.raku @@ -0,0 +1,73 @@ +#!/usr/bin/env perl6 + +use v6.d; + +# Cribbing my code from challenge 10 +# Note that I'm skipping the Unicode values this time for size mostly +subset RomanStr of Str where * ~~ /^ <[M C D X L V I]>+ $/; +subset RomanInt of Int where 0 < * < 3001; +subset Operator of Str where * ~~ /^ ( "*" | "+" | "-" | "/" ) $ /; + +#| Given two roman numerals and an operation on them +#| produce the result. +#| Note that division only works where the first value is greater than the second. +#| Results over 3000 and non valid numerals will return an error +multi sub MAIN ( + RomanStr $i, Operator $operator, RomanStr $j +) { + say "$i $operator $j = {perf-op( $operator, $i, $j )}"; +} + +#| Single String of operation to parse +multi sub MAIN ( + Str $compound where m!^ (<[M C D X L V I]>+) " "? ( "*" | "+" | "-" | "/" ) " "? (<[M C D X L V I]>+) $!; +) { + MAIN( $0.Str, $1.Str, $2.Str ); +} + +multi sub perf-op( "+", RomanStr $i, RomanStr $j ) { + to-roman( from-roman($i) + from-roman($j) ); +} + +multi sub perf-op( "-", RomanStr $i, RomanStr $j ) { + to-roman( from-roman($i) - from-roman($j) ); +} + +multi sub perf-op( "*", RomanStr $i, RomanStr $j ) { + to-roman( from-roman($i) * from-roman($j) ); +} + +multi sub perf-op( "/", RomanStr $i, RomanStr $j where { from-roman($i) > from-roman($j) } ) { + my $res = from-roman($i) div from-roman($j); + my $rem = from-roman($i) % from-roman($j); + to-roman($res) ~ ( $rem ?? " remainder {to-roman($rem)}" !! "" ); +} + +multi sub perf-op(*@){ die "Invalid operation. Did you try and create a fraction?" } + +sub to-roman (RomanInt $number is copy) { + my $out = ""; + my @values = ( :1000M, :900CM, :500D, :400CD, :100C, :90XC, :50L, :40XL, :10X, :9IX, :5V, :4IV, :1I ); + for @values -> $pair { + my ( $sigil, $num ) = $pair.kv; + while ( $number >= $num ) { + $out ~= $sigil; + $number -= $num; + } + } + + $out; +} + +sub from-roman( RomanStr $roman is copy ) { + my %roman-map = (:1000M, :900CM, :500D, :400CD, :100C, :90XC, :50L, :40XL, :10X, :9IX, :5V, :4IV, :1I ); + + my $out = 0; + while my $match = $roman ~~ s!^ "M" | "CM" | "D" | "CD" | + "C" | "XC" | "L" | "XL" | + "X" | "IX" | "V" | "IV" | "I" + !! { + $out += %roman-map{$match}; + } + $out; +} diff --git a/challenge-047/simon-proctor/raku/ch-2.p6 b/challenge-047/simon-proctor/raku/ch-2.p6 new file mode 100644 index 0000000000..dd2e54bbfe --- /dev/null +++ b/challenge-047/simon-proctor/raku/ch-2.p6 @@ -0,0 +1,10 @@ +#!/usr/bin/env perl6 + +use v6.d; + +#| Calculate the the first $count gapful numbers greater than 100 +sub MAIN ( + UInt $count = 20 #= Number of gapful numbers to calulate (default 20) +) { + .say for (100..*).grep( { $^a %% $^a.comb[0,*-1].join.Int } )[^$count] +} diff --git a/challenge-047/simon-proctor/raku/ch-2.raku b/challenge-047/simon-proctor/raku/ch-2.raku new file mode 100644 index 0000000000..dd2e54bbfe --- /dev/null +++ b/challenge-047/simon-proctor/raku/ch-2.raku @@ -0,0 +1,10 @@ +#!/usr/bin/env perl6 + +use v6.d; + +#| Calculate the the first $count gapful numbers greater than 100 +sub MAIN ( + UInt $count = 20 #= Number of gapful numbers to calulate (default 20) +) { + .say for (100..*).grep( { $^a %% $^a.comb[0,*-1].join.Int } )[^$count] +} |
