From 9fa20bcb70dbc6c3fdb5e193a597b1ae7c6d8515 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Mon, 18 Dec 2023 18:58:02 +0100 Subject: Add back --- roman.go | 28 ++++++++++++++++++++-------- roman_test.go | 30 +++++++++++++++++++----------- 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/roman.go b/roman.go index d1d382f..f57e655 100644 --- a/roman.go +++ b/roman.go @@ -1,23 +1,35 @@ // Package roman numerals +// +// For fluff, the unicode overbar is recognized as a factor of 1000. +// +// If you see boxes in the code below, those are supposed to be the +// Unicode combining overline (U+0305) and look like I̅V̅X̅L̅C̅D̅M̅. Or, if +// you see overstruck combinations of letters, that's a different font +// rendering problem. (If you need roman numerals > 3999 reliably, it +// might best to stick to chiseling them in stone...) +// +// Source: https://www.rosettacode.org/wiki/Roman_numerals/Encode#Go package roman var ( m0 = []string{"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"} m1 = []string{"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"} m2 = []string{"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"} - m3 = []string{"", "M", "MM", "MMM"} + m3 = []string{"", "M", "MM", "MMM", "I̅V̅", "V̅", "V̅I̅", "V̅I̅I̅", "V̅I̅I̅I̅", "I̅X̅"} + m4 = []string{"", "X̅", "X̅X̅", "X̅X̅X̅", "X̅L̅", "L̅", "L̅X̅", "L̅X̅X̅", "L̅X̅X̅X̅", "X̅C̅"} + m5 = []string{"", "C̅", "C̅C̅", "C̅C̅C̅", "C̅D̅", "D̅", "D̅C̅", "D̅C̅C̅", "D̅C̅C̅C̅", "C̅M̅"} + m6 = []string{"", "M̅", "M̅M̅", "M̅M̅M̅"} ) -// Roman numeral in interval 0 < x < 4000 +// Roman represents a roman numeral in interval 0 < x < 4e6 type Roman int -func (n Roman) Valid() bool { - return n > 0 && n < 4000 -} - func (n Roman) String() string { - if !n.Valid() { + if n <= 0 || n >= 4e6 { return "" } - return m3[n/1000] + m2[n%1000/100] + m1[n%100/10] + m0[n%10] + // this is efficient in Go. the seven operands are evaluated, + // then a single allocation is made of the exact size needed for the result. + return m6[n/1e6] + m5[n%1e6/1e5] + m4[n%1e5/1e4] + m3[n%1e4/1e3] + + m2[n%1e3/1e2] + m1[n%1e2/1e1] + m0[n%1e1] } diff --git a/roman_test.go b/roman_test.go index 3bd96fc..4ad62cf 100644 --- a/roman_test.go +++ b/roman_test.go @@ -10,11 +10,25 @@ func TestRoman(t *testing.T) { s string }{ {0, ""}, - {1666, "MDCLXVI"}, - {1990, "MCMXC"}, - {2008, "MMVIII"}, - {3888, "MMMDCCCLXXXVIII"}, - {3999, "MMMCMXCIX"}, + {1, "I"}, + {2, "II"}, + {3, "III"}, + {5, "V"}, + {8, "VIII"}, + {13, "XIII"}, + {21, "XXI"}, + {34, "XXXIV"}, + {55, "LV"}, + {89, "LXXXIX"}, + {100, "C"}, + {200, "CC"}, + {500, "D"}, + {1e3 - 1, "CMXCIX"}, + {2e3 - 1, "MCMXCIX"}, + {4e3 - 1, "MMMCMXCIX"}, + {1e6 - 1, "C̅M̅X̅C̅I̅X̅CMXCIX"}, + {2e6 - 1, "M̅C̅M̅X̅C̅I̅X̅CMXCIX"}, + {4e6 - 1, "M̅M̅M̅C̅M̅X̅C̅I̅X̅CMXCIX"}, } for _, tc := range testCases { t.Run(tc.s, func(t *testing.T) { @@ -24,9 +38,3 @@ func TestRoman(t *testing.T) { }) } } - -func BenchmarkRoman(b *testing.B) { - for i := 0; i < b.N; i++ { - Roman(1666).String() - } -} -- cgit v1.2.3