looking for a string method

A

adamw

Hi
I'm new to Ruby and programming and currently trying to write a program
converting Roman numerals to integers. I've done the following so far
(number validation check still not good) and stuck on the step when I
need to delete a specified string from the beginning (left side) of
some string and keep the rest. I've tried many String class methods but
none of them seems to meet my needs.

def roman_to_integer number
number = number.to_s
result = 0
roman = [ 'M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V',
'IV', 'I' ]
arab = [ 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 ]
if (number.capitalize).include?('M' || 'D' || 'C' || 'L' || 'X' ||
'V' || 'I')
n = 0
while n < 13
while number.include?(roman[n])
number[n].delete(roman[n]) <- THIS IS THE LINE
result = result + arab[n]
end
n += 1
end
print 'It equals: ' + result.to_s
else
puts 'Please enter a valid Roman numeral'
end
end
roman_to_integer 'MCmLxxVI'

Please help
Cheers
Adam
 
N

ndh.00008B

First of all, the type of method you want to use is a String instance
method. Class methods are ones that you call by using the class name
e.g. String.new.

I think what you want to do is use sub!(pattern, replacement) which
substitutes the replacement for the first match of the pattern. So, you
would call it like this.

number.sub!(roman[n],'')

which would replace the first occurrence of roman[n] with the null
string--removing it.

Does that help?

--Nick
 
R

Robert Klemme

Hi
I'm new to Ruby and programming and currently trying to write a
program converting Roman numerals to integers. I've done the
following so far (number validation check still not good) and stuck
on the step when I need to delete a specified string from the
beginning (left side) of some string and keep the rest. I've tried
many String class methods but none of them seems to meet my needs.

def roman_to_integer number
number = number.to_s
result = 0
roman = [ 'M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V',
'IV', 'I' ]
arab = [ 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 ]
if (number.capitalize).include?('M' || 'D' || 'C' || 'L' || 'X' ||
'V' || 'I')
n = 0
while n < 13
while number.include?(roman[n])
number[n].delete(roman[n]) <- THIS IS THE LINE
result = result + arab[n]
end
n += 1
end
print 'It equals: ' + result.to_s
else
puts 'Please enter a valid Roman numeral'
end
end
roman_to_integer 'MCmLxxVI'

Please help
Cheers
Adam

You can use []= to remove stuff from a string:
s="12345" => "12345"
s[0,2]='' => ""
s => "345"
s[-2..-1]='x' => "x"
s
=> "3x"

Here are some ideas for other improvements you can do to your code:

- your test does not work as you expect, notice this
=> "M"

So your code basically just does

if number.capitalize.include? 'M'

(Explanation: || is the boolean operator and as everything apart from false
and nil is treated as true it short circuits on the first element and
returns that.)

- you can make the sanity check with a regexp plus using an exception is
cleaner, e.g.

raise ArgumentError, "not a roman: #{number}" unless /^[mdclxvi]+$/ =~
number

(This one won't catch all illegal roman numbers, for example "IIII" goes
undetected, but it's a start and it does what you were actually trying to
accomplish with your test.)

- make roman and arab constants, so you do not recreate them on each method
invocation

- use #each_with_index for easier iteration or even Array#zip for iterating
in lock step, but:

- probably it's even better to merge roman and arab into a Hash, because
mapping of roman numbers to arab numbers is what you basically do

- in the next version you probably will be creating a class RomanNumber
that inherits Integer and implements +(), -(), coerce() etc.

Hope that helps.

Kind regards

robert
 
A

adamw

Yes, this is the answer to my question, however:

correct result = 1976

number[n].delete(roman[n]) REPLACED BY number.sub!(roman[n],'')
result = 1156

(doesn't see lowercase characters)

and then:
roman_to_integer 'MCmLxxVI' REPLACED BY roman_to_integer 'MCMLXXVI'
result = 2176

(sees 'C' and 'M' sepatrately, not as 'CM')

Still working on it. Thanks for your help.
Adam
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,104
Latest member
LesliVqm09
Top