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 <pablo1n7@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