[QUIZ] Roman Numerals (#22)

Hello mailing list. This has already been posted on Usenet, sorry for the duplication. (The gateway seems to be one-way at the moment.)

Dave

···

-----

Hi,

My solution is available here:

http://www.dave.burt.id.au/ruby/roman_numerals.rb

It can be used as a library (it pollutes String and Integer :slight_smile: or as
required from the command line, filtering integers to roman numeral strings
and vice-versa.

An outline:

# Contains methods to convert integers to roman numeral strings and
vice-versa.
module RomanNumerals

  # Maps roman numeral digits to their integer values
  DIGITS = {

  # The largest integer representable as a roman numerable by this module
  MAX = 3999

  # Stolen from O'Reilly's Perl Cookbook 6.23. Regular Expression Grabbag
  REGEXP = /^M*(D?C{0,3}|C[DM])(L?X{0,3}|X[LC])(V?I{0,3}|I[VX])$/i

  # Maps some integers to their roman numeral values
  @@digits_lookup = DIGITS.inject({

  # Converts +int+ to a roman numeral
  def self.from_integer(int)
  # main loop:
    @@digits_lookup.keys.sort.reverse.each do |digit_value|
      while remainder >= digit_value

  # Converts +roman_string+, a roman numeral, to an integer
  def self.to_integer(roman_string)
  # main loop:
    roman_string.to_s.upcase.split(//).reverse.inject(0) do |memo, digit|

  # Returns true iif +string+ is a roman numeral.
  def self.is_roman_numeral?(string)

class String
  # Considers string a roman numeral numeral,
  # and converts it to the corresponding integer.
  def to_i_roman

  # Returns true iif the subject is a roman numeral.
  def is_roman_numeral?

class Integer
  # Converts this integer to a roman numeral.
  def to_s_roman

# Processes ARGF as per Quiz requirement - converts numbers to roman
numerals and vice versa
if __FILE__ == $0

Cheers,
Dave

Thanks for copying it over here so I would see it, Dave. I went back and browsed the newsgroup and picked up Timothy Byrd's solution as well. That misbehaving gateway is hard on me. :smiley:

James Edward Gray II

···

On Mar 7, 2005, at 8:04 AM, Dave Burt wrote:

Hello mailing list. This has already been posted on Usenet, sorry for the duplication. (The gateway seems to be one-way at the moment.)

"James Edward Gray II" <james@grayproductions.net>:

Hello mailing list. This has already been posted on Usenet, sorry for the duplication. (The gateway seems to be one-way at the moment.)

Thanks for copying it over here so I would see it, Dave. I went back and browsed the newsgroup and picked up Timothy Byrd's solution as well. That misbehaving gateway is hard on me. :smiley:

Me too... having to join a hundred-plus-messages-per-day mailing list that floods my mailbox just to submit my quiz solution... life's tough, isn't it?

Anyway, I have an update quiz-solution-wise.

I had a niggling feeling something was missing from my solution before I submitted. And everyone else's once I'd read them all. And here it is:

# Enables uppercase roman numerals to be used interchangeably with integers.
# They are auto-vivified RomanNumeral constants
# Synopsis:
# 4 + IV #=> VIII
# VIII + 7 #=> XV
# III ** III #=> XXVII
# VIII.divmod(III) #=> [II, II]
def Object.const_missing sym
raise NameError.new("uninitialized constant: #{sym}") unless RomanNumerals::REGEXP === sym.to_s
const_set(sym, RomanNumeral.get(sym))
end

Of course, this requires a RomanNumeral class, which acts like an Integer but looks like a... well, roman numeral.

Go and download http://www.dave.burt.id.au/ruby/roman_numerals.rb again!

Cheers,
Dave

That is a neat trick! Thanks a lot for sharing.

Regards,

Brian

···

On Tue, 8 Mar 2005 16:29:11 +0900, Dave Burt <dave@burt.id.au> wrote:

"James Edward Gray II" <james@grayproductions.net>:
>> Hello mailing list. This has already been posted on Usenet, sorry for the
>> duplication. (The gateway seems to be one-way at the moment.)
>
> Thanks for copying it over here so I would see it, Dave. I went back and
> browsed the newsgroup and picked up Timothy Byrd's solution as well. That
> misbehaving gateway is hard on me. :smiley:

Me too... having to join a hundred-plus-messages-per-day mailing list that
floods my mailbox just to submit my quiz solution... life's tough, isn't it?

Anyway, I have an update quiz-solution-wise.

I had a niggling feeling something was missing from my solution before I
submitted. And everyone else's once I'd read them all. And here it is:

# Enables uppercase roman numerals to be used interchangeably with integers.
# They are auto-vivified RomanNumeral constants
# Synopsis:
# 4 + IV #=> VIII
# VIII + 7 #=> XV
# III ** III #=> XXVII
# VIII.divmod(III) #=> [II, II]
def Object.const_missing sym
raise NameError.new("uninitialized constant: #{sym}") unless
RomanNumerals::REGEXP === sym.to_s
const_set(sym, RomanNumeral.get(sym))
end

Of course, this requires a RomanNumeral class, which acts like an Integer but
looks like a... well, roman numeral.

Go and download http://www.dave.burt.id.au/ruby/roman_numerals.rb again!

Cheers,
Dave

--
Brian Schröder
http://ruby.brian-schroeder.de/

Dave Burt wrote:

Go and download http://www.dave.burt.id.au/ruby/roman_numerals.rb again!

Nice, now Ruby has them, too, like Perl did before. Small patch here:

--- roman_numerals.rb.1 Tue Mar 8 08:27:13 2005
+++ roman_numerals.rb Tue Mar 8 13:39:07 2005
@@ -135,7 +135,7 @@
                else
                        to_i = value.to_s.to_i_roman
                end
- @@all_roman_numerals[to_i] || RomanNumeral.new(to_i)
+ @@all_roman_numerals[to_i] || new(to_i)
        end
         def inspect

You can do funny things with those Roman numbers, BTW:

>> I += 1 ; I == II
(irb):1: warning: already initialized constant I
=> true

:wink:

···

--
Florian Frank