This is a problem where the only data structures you need, other than the integer you are encoding and the string you are building, is a small number of array literals.
Here is pseudo-code. If self is negative, emit a negative sign. If self is zero, emit N and finish. Let n be the absolute value of self. Emit M (n//1000) times -- use #next:put: Encode n // 100 \\ 10 using M D C. Encode n // 10 \\ 10 using C L X. Encode n \\10 using X V I To encode a digit using x v i, write the characters of #('' 'i' 'ii' 'iii' 'iv' 'v' 'vi' 'vii' 'viii' 'ix' 'x') at the digit + 1 (use #nextPutAll:). I have checked this pseudocode by writing #asRomanPrintString (2 lines including header) calling #asRomanPrintOn: (9 lines including header) and verified that each number from -4000 to +4000 gets the same result from #printStringRoman and #asRomanPrintString (except 0, which Pharo gets wrong). Now we *could* do the "encode a digit" using smaller or no tables, but it would take more code. In this case we can check that the right output for a digit is produced just by LOOKING at the table, rather than by checking complicated code. On Sat, 19 Sep 2020 at 02:13, Pablo Navarro <pablo...@gmail.com> wrote: > Hi! Maybe you can use this algorithm: > > Define a dictionary with these elements: > > 1000:'M', > 900:'CM', > 500: 'D', > 400: 'CD', > 100:"C", > 90:'XC', > 50:'L', > 40:'XL', > 10:'X', > 9:'IX', > 5:'V', > 4:'IV', > 1:'I' > > Using this dictionary (romansDic), you define a recursive function: > > toRomans(number){ > i = return the greatest key less than or equal to given key from > ‘romansDic' . > if (number == i ){ > return romansDic.get(number) > } > return string_concat(romansDic.get(i), toRomans(number-i)) > } > > Sorry for the pseudocode. > > Saludos Pablo. > > > El 18 de sep. de 2020 10:46 -0300, Roelof Wobben via Pharo-users < > pharo-users@lists.pharo.org>, escribió: > > Op 18-9-2020 om 06:45 schreef Richard O'Keefe: > > Roman numerals are much more complicated and much less consistent > than most people realise. The regular M DC LX VI system is both > more modern and less capable than anything the Romans would have > recognised. In particular, > - in the 8th century, N (short for "nulla") was adopted for zero > - the Roman system always had fractions like S for 1/2, . for 1/12 > - there were numerals for much larger numbers. > Unicode code block [2150] has characters for the Roman numerals > including > 216C L ROMAN NUMERAL FIFTY > 216D C ROMAN NUMERAL ONE HUNDRED > 216E D ROMAN NUMERAL FIVE HUNDRED > 216F M ROMAN NUMERAL ONE THOUSAND > 2181 ↁ ROMAN NUMERAL FIVE THOUSAND > 2182 ↂ ROMAN NUMERAL TEN THOUSAND > 2187 ↇ ROMAN NUMERAL FIFTY THOUSAND > 2188 ↈ ROMAN NUMERAL ONE HUNDRED THOUSAND > (In fact these are ligated versions of forms using "apostrophic" brackets; > the pattern goes as high as you want, e.g., (((|))) for a million. > D and M were originally |) and (|). There is > > So the first thing is to make sure that you understand the > requirements for the problem. > - Are you required to produce ASCII characters, required to > produce Unicode ones, or allowed to produce either? > > > as far as I can see from the tests only ASCI characters. > > - Are you required to support zero? > > > No > > - Are you required to support n/12 fractions (1<=n<=11)? > > > NO > > - Are you allowed, required, or forbidden to use the "overline" > convention, where an overline means "multiply by 1000"? > =------- > > > In the test that one is not used. > > ICCXXXIVDLXVII = 1,234,567 > - Are you allowed, required, or forbidden to use "additive" > form "IIII" as well as/instead of "subtractive" form "IV"? > - Are you to use upper case or lower case letters? > - And so on. > > > > > the number 4 needs to be "IV" > > Roelof > >