pharo-users@lists.pharo.org

Any question about pharo is welcome

View all threads

roman numbers

RW
Roelof Wobben
Thu, Sep 17, 2020 3:20 PM

Hello,

Can someone help me with a good plan to convert numbers to roman numbers.

I could make a dictionary with 1,4,5,9,10,99,100, 999, 1000 but that
feels like a overkill.

Regards,

Roelof

Hello, Can someone help me with a good plan to convert numbers to roman numbers. I could make a dictionary with 1,4,5,9,10,99,100, 999, 1000 but that feels like a overkill. Regards, Roelof
AS
Aliaksei Syrel
Thu, Sep 17, 2020 4:13 PM

Hi Roelof,

You will not believe!

2 printStringRoman “II”

Have fun!

On Thu, 17 Sep 2020 at 18:20, Roelof Wobben via Pharo-users <
pharo-users@lists.pharo.org> wrote:

Hello,

Can someone help me with a good plan to convert numbers to roman numbers.

I could make a dictionary with 1,4,5,9,10,99,100, 999, 1000 but that

feels like a overkill.

Regards,

Roelof

--

Cheers,
Alex

Hi Roelof, You will not believe! 2 printStringRoman “II” Have fun! On Thu, 17 Sep 2020 at 18:20, Roelof Wobben via Pharo-users < pharo-users@lists.pharo.org> wrote: > Hello, > > > > Can someone help me with a good plan to convert numbers to roman numbers. > > > > I could make a dictionary with 1,4,5,9,10,99,100, 999, 1000 but that > > feels like a overkill. > > > > Regards, > > > > Roelof > > -- Cheers, Alex
RW
Roelof Wobben
Thu, Sep 17, 2020 4:57 PM

Hello,

The challenge is to do it manually.
But I can take a look how that function is implented.

Roelof

Op 17-9-2020 om 18:13 schreef Aliaksei Syrel:

Hi Roelof,

You will not believe!

2 printStringRoman “II”

Have fun!

On Thu, 17 Sep 2020 at 18:20, Roelof Wobben via Pharo-users <pharo-users@lists.pharo.org> wrote:

Hello,

Can someone help me with a good plan to convert numbers to roman numbers.

I could make a dictionary with 1,4,5,9,10,99,100, 999, 1000 but that

feels like a overkill.

Regards,

Roelof

--
Cheers, Alex

RO
Richard O'Keefe
Fri, Sep 18, 2020 4:45 AM

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?
  • Are you required to support zero?
  • Are you required to support n/12 fractions (1<=n<=11)?
  • Are you allowed, required, or forbidden to use the "overline"
    convention, where an overline means "multiply by 1000"?
    =-------
    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.

I am not happy with the way that (0 printStringRoman) quietly
produces ''.

Assuming you're generating regular modern Roman numbers,
you pretty much have to think of an integer as having 4 parts:
n // 1000      -- this many copies of M
n // 100 \ 10 -- hundreds using M, D, C
n // 10 \ 100 -- tens using    C, L, X
n \ 10        -- units using    X, V, I

If Squeak/Pharo's (0 printStringRoman) would answer 'N'
instead of '' I'd be happier with it.

While you really want to write your own code --- this
being an exercism task --- it would be a very good idea
to start by using #printStringRoman so that you know
what it's like to pass the tests.

On Fri, 18 Sep 2020 at 04:58, Roelof Wobben via Pharo-users <
pharo-users@lists.pharo.org> wrote:

Hello,

The challenge is to do it manually.
But I can take a look how that function is implented.

Roelof

Op 17-9-2020 om 18:13 schreef Aliaksei Syrel:

Hi Roelof,

You will not believe!

2 printStringRoman “II”
Have fun!

On Thu, 17 Sep 2020 at 18:20, Roelof Wobben via Pharo-users <
pharo-users@lists.pharo.org> wrote:

Hello,

Can someone help me with a good plan to convert numbers to roman numbers.

I could make a dictionary with 1,4,5,9,10,99,100, 999, 1000 but that

feels like a overkill.

Regards,

Roelof

--

Cheers,
Alex

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? - Are you required to support zero? - Are you required to support n/12 fractions (1<=n<=11)? - Are you allowed, required, or forbidden to use the "overline" convention, where an overline means "multiply by 1000"? =------- 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. I am not happy with the way that (0 printStringRoman) quietly produces ''. Assuming you're generating regular modern Roman numbers, you pretty much have to think of an integer as having 4 parts: n // 1000 -- this many copies of M n // 100 \\ 10 -- hundreds using M, D, C n // 10 \\ 100 -- tens using C, L, X n \\ 10 -- units using X, V, I If Squeak/Pharo's (0 printStringRoman) would answer 'N' instead of '' I'd be happier with it. While you really want to write your own code --- this being an exercism task --- it would be a very good idea to start by using #printStringRoman so that you know what it's like to pass the tests. On Fri, 18 Sep 2020 at 04:58, Roelof Wobben via Pharo-users < pharo-users@lists.pharo.org> wrote: > Hello, > > The challenge is to do it manually. > But I can take a look how that function is implented. > > Roelof > > > > Op 17-9-2020 om 18:13 schreef Aliaksei Syrel: > > Hi Roelof, > > You will not believe! > > 2 printStringRoman “II” > Have fun! > > On Thu, 17 Sep 2020 at 18:20, Roelof Wobben via Pharo-users < > pharo-users@lists.pharo.org> wrote: > >> Hello, >> >> >> >> Can someone help me with a good plan to convert numbers to roman numbers. >> >> >> >> I could make a dictionary with 1,4,5,9,10,99,100, 999, 1000 but that >> >> feels like a overkill. >> >> >> >> Regards, >> >> >> >> Roelof >> >> -- > Cheers, > Alex > > >
RW
Roelof Wobben
Fri, Sep 18, 2020 1:46 PM

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

PN
Pablo Navarro
Fri, Sep 18, 2020 2:13 PM

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

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 >
RW
Roelof Wobben
Fri, Sep 18, 2020 5:09 PM

Op 18-9-2020 om 16:13 schreef Pablo Navarro:

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.

No problem. I searching for a idea not somebody who solves it for me.

Roelof

RO
Richard O'Keefe
Sat, Sep 19, 2020 8:45 AM

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

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