Find Roman numerals in Ruby

!Mac OS-11.1!ruby-2.6.6p146

Roman numerals

Create a method that takes Arabic numerals as input and returns Roman numerals.

Answer (before refactoring)

It's wasteful and it's a level that shouldn't be seen for a long time, so I fold it.
def getNums()
  lines = readlines
  len = lines.length

  (0..len-1).each do |i|
    lines[i] = lines[i].chomp.to_i
  end

  return lines
end

class Integer
  def to_roman
    sym = ['I', 'V', 'X', 'L', 'C', 'D', 'M']
    roman = ''
    to_arr(4).each_with_index do |num, i|
      case i
      when 0 then
	roman += sym[6] * num
      when 1 then
	case num
	when 0..3 then
	  roman += sym[4] * num
	when 4 then
	  roman += sym[4] + sym[5]
	when 5..8 then
	  roman += sym[5] + sym[4] * (num-5)
	when 9 then
	  roman += sym[4] + sym[6]
	end
      when 2 then
	case num
	when 0..3 then
	  roman += sym[2] * num
	when 4 then
	  roman += sym[2] + sym[3]
	when 5..8 then
	  roman += sym[3] + sym[2] * (num-5)
	when 9 then
	  roman += sym[2] + sym[4]
	end
      when 3 then
	case num
	when 0..3 then
	  roman += sym[0] * num
	when 4 then
	  roman += sym[0] + sym[1]
	when 5..8 then
	  roman += sym[1] + sym[0] * (num-5)
	when 9 then
	  roman += sym[0] + sym[2]
	end
      end
    end
    roman
  end

  def to_arr(n)
    arr = []
    (Math.log10(self).to_i + 1).upto(n-1) do
      arr.unshift(0)
    end
    arr + digits.reverse
  end
end

if $PROGRAM_NAME == __FILE__
  getNums().each do |i|
    puts i.to_roman
  end
end

Answer (after refactoring)

def getNums()
  lines = readlines

  (0..lines.length-1).each do |i|
    lines[i] = lines[i].chomp.to_i
  end
  lines
end

class Integer
  def to_roman
    sym = ['I', 'V', 'X', 'L', 'C', 'D', 'M']
    roman = ''
    base = sym.length-1
    to_arr(4).each_with_index do |num, i|
      case num
      when 0..3 then
	roman += sym[base-i*2] * num
      when 4 then
	roman += sym[base-i*2] + sym[base-i*2+1]
      when 5..8 then
	roman += sym[base-i*2+1] + sym[base-i*2] * (num-5)
      when 9 then
	roman += sym[base-i*2] + sym[base-(i-1)*2]
      end
    end
    roman
  end

  def to_arr(n)
    arr = Array.new(n - Math.log10(self).to_i - 1, 0)
    arr + digits.reverse
  end
end

if $PROGRAM_NAME == __FILE__
  getNums().each do |i|
    # puts "#{i} => #{i.to_roman}"
    printf("%4d => %s\n", i, i.to_roman)
  end
end

Commentary

Receive input of Arabic numerals

def getNums()
  lines = readlines

  (0..lines.length-1).each do |i|
    lines[i] = lines[i].chomp.to_i
  end
  lines
end

This is the part that receives input from standard input.

--Since it is intended for multi-line input, you can enter it separated by line breaks. --Cast the string with the line feed code removed to Integer and store it as an array in lines.

Execution part

if $PROGRAM_NAME == __FILE__
  getNums().each do |i|
    # puts "#{i} => #{i.to_roman}"
    printf("%4d => %s\n", i, i.to_roman)
  end
end

This is the part that is executed when the program is executed with $ ruby ​​roman_numerals.rb etc.

--Receive the input with getNums () and output it to the return object (array) as standard output. --As will be described later, since it is overridden to the Integer class, you can get Roman numerals as a character string with (Integer) .to_roman.

Method to return Roman numerals

class Integer
  def to_roman
    sym = ['I', 'V', 'X', 'L', 'C', 'D', 'M']
    roman = ''
    base = sym.length-1
    to_arr(4).each_with_index do |num, i|
      case num
      when 0..3 then
	roman += sym[base-i*2] * num
      when 4 then
	roman += sym[base-i*2] + sym[base-i*2+1]
      when 5..8 then
	roman += sym[base-i*2+1] + sym[base-i*2] * (num-5)
      when 9 then
	roman += sym[base-i*2] + sym[base-(i-1)*2]
      end
    end
    roman
  end

  def to_arr(n)
    arr = Array.new(n - Math.log10(self).to_i - 1, 0)
    arr + digits.reverse
  end
end

This is the implementation part of this time.

--Implemented to override the Integer class.

To an array of 4 elements (to \ _arr (n))

--Roman numerals can represent 1 to 3999. - to_arr(n) --This method arranges the entered Arabic numerals by dividing them into digits. -- n means the maximum number of digits, and numbers less than that digit are padded with zeros. --Example

n = 8
n.to_arr(4) # [0, 0, 0, 8]

To Roman numerals

--Refer to Wikipedia etc. for each symbol of Roman numerals. --The Roman numerals to be assembled are stored in the string variable roman. - to_arr(4).each_with_index -- self can be omitted, so it is omitted. --Convert to a 4-element array with to_arr (4), and then process each digit. --Cases are classified according to the case statement. The most important Roman numerals are 4 and 9. --The processing for each number is the concept and array of Roman numerals in Wikipedia above sym = ['I','V','X','L','C','D','M' You can understand it by comparing with] . --The final Roman numeral roman is output. --Example

n = 8
n.to_roman # "VIII"
n = 1999
n.to_roman # "MCMXCIX"

Execution result

First, prepare the following text file (in.txt) as input.

1
2
4
5
6
9
10
11
14
15
19
38
42
49
51
97
99
439
483
499
732
961
999
1999

The execution result when this is given as input is as follows.

$ ruby roman_numerals.rb < in.text
   1 => I
   2 => II
   4 => IV
   5 => V
   6 => VI
   9 => IX
  10 => X
  11 => XI
  14 => XIV
  15 => XV
  19 => XIX
  38 => XXXVIII
  42 => XLII
  49 => XLIX
  51 => LI
  97 => XCVII
  99 => XCIX
 439 => CDXXXIX
 483 => CDLXXXIII
 499 => CDXCIX
 732 => DCCXXXII
 961 => CMLXI
 999 => CMXCIX
1999 => MCMXCIX

moved!!!!!


Recommended Posts

Find Roman numerals in Ruby
Convert numbers to Roman numerals in Ruby
[Ruby] Find numbers in arrays
roman numerals
roman numerals
roman numerals
roman numerals
roman numerals
Roman Numerals
roman numerals
roman numerals
Class in Ruby
Heavy in Ruby! ??
EX1: roman numerals
About eval in Ruby
Output triangle in Ruby
Variable type in ruby
Fast popcount in Ruby
Validate JWT token in Ruby
Implemented XPath 1.0 parser in Ruby
Read design patterns in Ruby
Write class inheritance in Ruby
Update Ruby in Unicorn environment
Integer unified into Integer in Ruby 2.4
[Ruby] Exception handling in functions
Use ruby variables in javascript.
Cannot find javax.annotation.Generated in Java 11
Multiplication in a Ruby array
About regular expressions in Ruby
Find a subset in Java
Birthday attack calculation in Ruby
Try using gRPC in Ruby
NCk mod p in Ruby
Chinese Remainder Theorem in Ruby
Sorting hashes in a Ruby array
How to find May'n in XPath
Basics of sending Gmail in Ruby
How to iterate infinitely in Ruby
Try to implement Yubaba in Ruby
Implementation of ls command in Ruby
Achieve 3-digit delimited display in Ruby
Encoding when getting in Windows + Ruby
Run GraphQL Ruby resolver in parallel
Ruby on Rails Japanese-English support i18n
[Ruby] Extracting double hash in array
[Ruby] then keyword and case in
How to install Bootstrap in Ruby
String output method memo in Ruby
Implement a gRPC client in Ruby
[Super Introduction] About Symbols in Ruby
Hanachan in Ruby (non-destructive array manipulation)
Is there no type in Ruby?
Try file locking in Ruby directory
[Ruby] undefined method `dark?'occurs in rqr_code
openssl version information in ruby OPENSSL_VERSION
Ruby methods often used in Rails
Make Ruby segfault in two lines