diff options
| author | Daniel Mita <mienaikage@gmail.com> | 2019-05-30 17:45:02 +0100 |
|---|---|---|
| committer | Daniel Mita <mienaikage@gmail.com> | 2019-05-30 17:45:02 +0100 |
| commit | a5365d6b7aa20ab1288d9103e47153df889adfa1 (patch) | |
| tree | 58b9da23c2d1f79e5ad2eb2bd52a290ea5aa7a17 /challenge-010/daniel-mita | |
| parent | 2d6fe89dbab4cfa5b3daf930765c441ee2048eff (diff) | |
| download | perlweeklychallenge-club-a5365d6b7aa20ab1288d9103e47153df889adfa1.tar.gz perlweeklychallenge-club-a5365d6b7aa20ab1288d9103e47153df889adfa1.tar.bz2 perlweeklychallenge-club-a5365d6b7aa20ab1288d9103e47153df889adfa1.zip | |
Move roman converter to module for precomp benefits
Diffstat (limited to 'challenge-010/daniel-mita')
| -rw-r--r-- | challenge-010/daniel-mita/perl6/RomanNumerals.pm6 | 29 | ||||
| -rw-r--r-- | challenge-010/daniel-mita/perl6/ch-1.p6 | 52 |
2 files changed, 43 insertions, 38 deletions
diff --git a/challenge-010/daniel-mita/perl6/RomanNumerals.pm6 b/challenge-010/daniel-mita/perl6/RomanNumerals.pm6 new file mode 100644 index 0000000000..ba136209ed --- /dev/null +++ b/challenge-010/daniel-mita/perl6/RomanNumerals.pm6 @@ -0,0 +1,29 @@ +unit module RomanNumerals; + +constant @letters = 「IVXLCDM」.comb; +constant @overlines = "\c[combining overline]", "\c[combining double overline]"; + +constant %letter-map = ( 1, |( * X* 5, 10 ) … ∞ ) Z=> + |@letters, |( @overlines XR~ @letters[1..*] ); + +constant %prefixes = %letter-map{ 10 X** 3, 6 } Z=> ( %letter-map<1> X~ @overlines ); + +sub to-roman ( + UInt() $_ where 0 < * < 4e9, + --> Str:D +) is pure is export { + return [~] gather { + for .flip.comb.pairs.reverse { + given 10 ** .key -> $key { + when .value == 4 | 9 { + take %prefixes{ %letter-map{$key} } || %letter-map{$key}; + take %letter-map{ $key * (.value + 1) }; + } + if .value ≥ 5 { + take %letter-map{ $key * 5 }; + } + take %letter-map{ $key } x .value % 5; + } + } + }; +} diff --git a/challenge-010/daniel-mita/perl6/ch-1.p6 b/challenge-010/daniel-mita/perl6/ch-1.p6 index 7a12b34226..601c2a67e3 100644 --- a/challenge-010/daniel-mita/perl6/ch-1.p6 +++ b/challenge-010/daniel-mita/perl6/ch-1.p6 @@ -1,16 +1,10 @@ #!/usr/bin/env perl6 use v6; +use lib $?FILE.IO.dirname; +use RomanNumerals; my %*SUB-MAIN-OPTS = :named-anywhere; -my constant @letters = 「IVXLCDM」.comb; -my constant @overlines = "\c[combining overline]", "\c[combining double overline]"; - -my constant %letter-map = ( 1, |( * X* 5, 10 ) … ∞ ) Z=> - |@letters, |( @overlines XR~ @letters[1..*] ); - -my constant %prefixes = %letter-map{ 10 X** 3, 6 } Z=> ( %letter-map<1> X~ @overlines ); - multi MAIN ( UInt:D $number where 0 < * < 4e9, #= A positive integer. --> Nil @@ -20,26 +14,30 @@ multi MAIN ( #| Not Yet Implemented multi MAIN ( - Str:D $roman-numerals + Str:D $roman-numerals where { $_ !~~ UInt && .chars > 0 } --> Nil ) is hidden-from-USAGE { say &?ROUTINE.WHY; } multi MAIN ( - Str:D $roman-numerals where *.chars > 0, #= A string of roman numerals. + Str:D $roman-numerals where { $_ !~~ UInt && .chars > 0 }, #= A string of roman numerals. Bool:D :bruteforce(:$b) where *.so, #= Convert using bruteforce method. --> Nil ) { - given |( @overlines.map(@letters X~ *).reverse ), @letters -> @set { + given |( + @RomanNumerals::overlines.map( @RomanNumerals::letters X~ * ).reverse + ), @RomanNumerals::letters -> @set { $roman-numerals.uc ~~ / ^ ( @(@set[0])+ )? ( @(@set[1])+ )? ( @(@set[2])+ )? $ /; } if $/ { given await gather { - take Promise.start( { (1..^4000).race.map(* * 1e6).first(*.&to-roman eq $0) } ) if $0; - take Promise.start( { (1..^4000).race.map(* * 1e3).first(*.&to-roman eq $1) } ) if $1; - take Promise.start( { (1..^4000).race.first(*.&to-roman eq $2) } ) if $2; + for $/[*].reverse.pairs -> $pair { + take Promise.start({ + (1..^4000).race.map( * × 10 ** ($pair.key × 3) ).first(*.&to-roman eq $pair.value) + }) if $pair.value; + } } { if .all.so && .sum.&to-roman eq $roman-numerals.uc { .sum.say; @@ -51,29 +49,7 @@ multi MAIN ( say "Error:\n The input was not understood.\n\n" ~ $*USAGE; } -sub to-roman ( - UInt() $_, - --> Str:D -){ - return [~] gather { - for .flip.comb.pairs.reverse { - given 10 ** .key -> $key { - when .value == 4 | 9 { - take %prefixes{ %letter-map{$key} } || %letter-map{$key}; - take %letter-map{ $key * (.value + 1) }; - } - if .value ≥ 5 { - take %letter-map{ $key * 5 }; - } - take %letter-map{ $key } x .value % 5; - } - } - }; -} - sub GENERATE-USAGE ( &main, |capture ) { - (capture[0] ~~ UInt && capture[0] ≥ 4e9 - ?? "Error:\n Numbers ≥ 4,000,000,000 not supported.\n\n" - !! '') - ~ $*USAGE; + "Error:\n Numbers ≥ 4,000,000,000 not supported.\n\n" + x (capture[0] ~~ UInt && capture[0] ≥ 4e9) ~ $*USAGE; } |
