From d49ff45f5b3fb5bb6bfbab76c4a123e111aad435 Mon Sep 17 00:00:00 2001 From: librasteve Date: Fri, 21 Jun 2024 09:55:11 +0100 Subject: [PATCH 1/3] state standard subtrtactove forms --- README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/README.md b/README.md index edc54bc..76c679f 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,35 @@ Future enhancements will include expansions to printf/sprintf with a custom form While it handles both additive and subtractive Roman numerals, it doesn't check that they're properly formatted. For instance 'IC' should be a compile-time error but instead it'll generate 101 as if nothing of consequence happened. +REFERENCE +========= + +According to [Wikipedia](https://en.wikipedia.org/wiki/Roman_numerals), the standard form is: + ++---+-----------+----------+------+-------+ +| | Thousands | Hundreds | Tens | Units | ++---+-----------+----------+------+-------+ +| 1 | M | C | X | I | ++---+-----------+----------+------+-------+ +| 2 | MM | CC | XX | II | ++---+-----------+----------+------+-------+ +| 3 | MMM | CCC | XXX | III | ++---+-----------+----------+------+-------+ +| 4 | | CD | XL | IV | ++---+-----------+----------+------+-------+ +| 5 | | D | L | V | ++---+-----------+----------+------+-------+ +| 6 | | DC | LX | VI | ++---+-----------+----------+------+-------+ +| 7 | | DCC | LXX | VII | ++---+-----------+----------+------+-------+ +| 8 | | DCCC | LXXX | VIII | ++---+-----------+----------+------+-------+ +| 9 | | CM | XC | IX | ++---+-----------+----------+------+-------+ + +The numerals for 4 (IV) and 9 (IX) are written using subtractive notation,where the smaller symbol (I) is subtracted from the larger one (V, or X), thus avoiding the clumsier IIII and VIIII. Subtractive notation is also used for 40 (XL), 90 (XC), 400 (CD) and 900 (CM). These are the only subtractive forms in standard use. + AUTHOR ====== From 2e2a69563aa165a953efd01ba6309b87cc556147 Mon Sep 17 00:00:00 2001 From: librasteve Date: Fri, 21 Jun 2024 09:56:17 +0100 Subject: [PATCH 2/3] drop IL example --- lib/Slang/Roman.rakumod | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/Slang/Roman.rakumod b/lib/Slang/Roman.rakumod index 3757123..c61c9c6 100644 --- a/lib/Slang/Roman.rakumod +++ b/lib/Slang/Roman.rakumod @@ -68,7 +68,6 @@ my sub to-number(Str:D $value) is export { # IV => IIII ( 5 - 1 == 4 ) # IX => VIIII ( 10 - 1 == 9 ) # XL => XXXX ( 50 - 10 == 40 ) - # IL => XXXXVIIII ( 50 - 1 == 49 ) # XC => LXXXX ( 100 - 10 == 90 ) # CD => CCCC ( 500 - 100 == 400 ) # CM => DCCCC ( 1000 - 100 == 900 ) From 47689d60f2e28d76ac9c43eaacef8962b9dee39a Mon Sep 17 00:00:00 2001 From: librasteve Date: Fri, 21 Jun 2024 11:46:04 +0100 Subject: [PATCH 3/3] adapt subtractives --- lib/Slang/Roman.rakumod | 36 ++++++++++++++++++------------------ t/01-basic.rakutest | 4 ++-- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/Slang/Roman.rakumod b/lib/Slang/Roman.rakumod index c61c9c6..5c5d89c 100644 --- a/lib/Slang/Roman.rakumod +++ b/lib/Slang/Roman.rakumod @@ -64,24 +64,24 @@ my sub to-roman(Int:D $val) is export { my sub to-number(Str:D $value) is export { # Find subtractives and convert them to additives - # - # IV => IIII ( 5 - 1 == 4 ) - # IX => VIIII ( 10 - 1 == 9 ) - # XL => XXXX ( 50 - 10 == 40 ) - # XC => LXXXX ( 100 - 10 == 90 ) - # CD => CCCC ( 500 - 100 == 400 ) - # CM => DCCCC ( 1000 - 100 == 900 ) - - $value.subst(/ - (<[ I Ⅰ X Ⅹ C Ⅽ M Ⅿ ↂ ]>) - (<[ V Ⅴ X Ⅹ L Ⅼ C Ⅽ D Ⅾ M Ⅿ ↁ ↂ ↇ ↈ ]>) - /, { - %char-map{$0} < %char-map{$1} - ?? to-roman(%char-map{$1} - %char-map{$0}) - !! $0 ~ $1 - }, :global).comb.map({ - %char-map{$_} // die "Unexpected '$_' in Roman numeral" - }).sum + + my %subtractives = ( + IV => 'IIII', #( 5 - 1 == 4 ) + IX => 'VIIII', #( 10 - 1 == 9 ) + XL => 'XXXX', #( 50 - 10 == 40 ) + XC => 'LXXXX', #( 100 - 10 == 90 ) + CD => 'CCCC', #( 500 - 100 == 400 ) + CM => 'DCCCC', #( 1000 - 100 == 900 ) + ); + + my Pair $p = (.keys => .values) given %subtractives; + + $value + .trans( $p ) + .comb.map({ + %char-map{$_} // die "Unexpected '$_' in Roman numeral" + }) + .sum } my role Grammar { diff --git a/t/01-basic.rakutest b/t/01-basic.rakutest index d5df14f..0b94845 100755 --- a/t/01-basic.rakutest +++ b/t/01-basic.rakutest @@ -29,8 +29,8 @@ subtest sub { is 0rXIV, 14, q{Roman numeral 14 subtractive}; is 0rXIX, 19, q{Roman numeral 19 subtractive}; is 0rXLIV, 44, q{Roman numeral 44 subtractive}; - is 0rIC, 99, q{Roman numeral 99 subtractive}; - is 0rMIM, 1999, q{Roman numeral 1999 subtractive}; + is 0rXC, 90, q{Roman numeral 90 subtractive}; + is 0rMCM, 1900, q{Roman numeral 1900 subtractive}; }, 'subtractive'; is 0rMMXVI, 2016, q{Year of module release};