LoginSignup
2
0

More than 3 years have passed since last update.

roman numerals

Last updated at Posted at 2020-12-30

お題

アラビア数字(arabic numerals)を受け取って,ローマ数字(roman numerals)を返すmethodを書きなさい1

ローマ数字で使われる文字

arabic numerals roman numerals
1 I
5 V
10 X
50 L
100 C
500 D
1000 M

arabic numerals roman numerals
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

コード

require 'colorize'
class Number
  def initialize(arabic_numeral)
    @arabic_numeral = arabic_numeral.to_i # string to int

    @num_thousands = @arabic_numeral / 1000 
    @num_hundreds = (@arabic_numeral - @num_thousands*1000) / 100
    @num_tens = (@arabic_numeral - @num_thousands*1000 - @num_hundreds*100) / 10
    @num_ones = @arabic_numeral % 10

    @roman_numeral = ""

  end

  def convert_roman
    if  @arabic_numeral > 3999 or @arabic_numeral == 0
      puts "arabic_numeral :: #{@arabic_numeral.to_s}"
      puts "can't convert".red
      exit 0
    end

    self.to_roman(@num_thousands, 6)
    self.to_roman(@num_hundreds, 4)
    self.to_roman(@num_tens, 2)
    self.to_roman(@num_ones, 0)

  end

  def to_roman(num, digit)
    element = ['I','V','X','L','C','D','M']

    case num 
    when 0..3 then
      @roman_numeral = @roman_numeral + element[digit] * num
    when 4 then
      @roman_numeral = @roman_numeral + element[digit] + element[digit+1]
    when 5..8 then
      @roman_numeral = @roman_numeral + element[digit+1] +  element[digit]*(num-5)
    when 9 then
      @roman_numeral = @roman_numeral + element[digit] + element[digit+2]
    end
  end

  def puts_numeral
    puts "arabic_numeral :: #{@arabic_numeral.to_s}"
    puts "roman_numeral :: #{@roman_numeral}".green
  end

end     

def gets_num
  num = ARGV[0]
  if num == nil
    puts "What\'s the number?".green
    num = gets.chomp
  end

  return num
end

num = gets_num
numeral = Number.new(num)
#numeral.initialize(num)
numeral.convert_roman
numeral.puts_numeral

解説

初期化の部分

def initialize(arabic_numeral)
    @arabic_numeral = arabic_numeral.to_i # string to int

    @num_thousands = @arabic_numeral / 1000 
    @num_hundreds = (@arabic_numeral - @num_thousands*1000) / 100
    @num_tens = (@arabic_numeral - @num_thousands*1000 - @num_hundreds*100) / 10
    @num_ones = @arabic_numeral % 10

    @roman_numeral = ""

    end

まずは必要な変数の初期化です.

  • "@"をつけないとクラス内で使えないので忘れないようにしましょう.
  • それぞれの桁の数値をわける関数もあるようですが中身がよくわからないので,計算で求めました.

アラビア数字からローマ数字へ

def to_roman(num, digit)
    element = ['I','V','X','L','C','D','M']

    case num 
    when 0..3 then
      @roman_numeral = @roman_numeral + element[digit] * num
    when 4 then
      @roman_numeral = @roman_numeral + element[digit] + element[digit+1]
    when 5..8 then
      @roman_numeral = @roman_numeral + element[digit+1] +  element[digit]*(num-5)
    when 9 then
      @roman_numeral = @roman_numeral + element[digit] + element[digit+2]
    end
    end

アラビア数字からローマ数字への変換の部分です.

  • digit で桁数を指定して,num を元に場合分けを行います.
  • roman_numeral に文字を追加する形で実装してます.

一つの桁に対して3種類の文字を使う可能性があります.

  • 例えば 1~9 の場合だと 'I','V','X' の3つ必要になります.
  • 使う文字の組み合わせはコードのように 4 通りあるのでそれぞれ分けましょう
  • 10 以上の数値の場合については各桁ごとに分けてつなげます

実際の変換部分

def convert_roman
    if  @arabic_numeral > 3999 or @arabic_numeral == 0
      puts "arabic_numeral :: #{@arabic_numeral.to_s}"
      puts "can't convert".red
      exit 0
    end

    self.to_roman(@num_thousands, 6)
    self.to_roman(@num_hundreds, 4)
    self.to_roman(@num_tens, 2)
    self.to_roman(@num_ones, 0)

  end

アラビア数字からローマ数字へ実際に変換する部分です.

まず,今回の実装では 1 ~ 3999 の数値しか変換が行なえません.そのためそれ以外が入力されている場合はエラーがでるようにしました.

  • 数字以外が入力された場合は0になるので今回の処理で弾けるようですね
  • せっかくなのでエラーといえば赤という感じで色もつけました.成功した場合は緑になります.

参照文献


  • source ~/Documents/my_ruby/grad_members_20f/members/toshi0707/c6_roman_numerals.org

  1. "初めてのプログラミング", Chris Pine (著), 西山 伸 (翻訳),オライリー・ジャパン (2006/7/24). 

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0