4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

マルチスケールシミュレーション特論: roman numerals

Last updated at Posted at 2020-11-19

はじめに

今回は課題としてアラビア数字からローマ数字に変換するという課題が出たので、その課題を解いてみる事にする

解答

プログラム

  • 正直全く良い方法分からない、、、、、
num = ARGV[0]

def divide_num(num)
  ans_list,count = [],0
  while num > 0
    tmp = num % 10
    ans_list.push(tmp * (10 ** count))
    num = num / 10
    count = count + 1
  end
  return ans_list.reverse
end

ans_list,count = divide_num(num.to_i),0

def num_to_roman_hundred(num)
  if num == 900
    print "CM"
  elsif num <= 800 && num >= 500
    num = num - 500
    if num != 0
      print "D" + "C" * (num / 100)
    else
      print "D"
    end

  elsif num == 400
    print "CD"

  elsif num <= 300 && num >= 100
    num = num - 100
    if num != 0
      print "C" + "C" * (num / 100)
    else
      print "C"
    end
  end
end

def num_to_roman_ten(num)
  if num == 90
    print "XC"
  elsif num <= 80 && num >= 50
    num = num - 50
    if num != 0
      print "L" + "X" * (num / 10)
    else
      print "L"
    end

  elsif num == 40
    print "XL"

  elsif num <= 30 && num >= 10
    num = num - 10
    if num != 0
      print "X" + "X" * (num / 10)
    else
      print "X"
    end
  end
end

def num_to_roman(num)
  roman_first = ['I','II','III','IV','V','VI','VII','VIII','IX','X']

  if num >= 1000
    tmp = num / 1000
    x = "M" * tmp
    print x

  elsif num <= 900 && num >= 100
    num_to_roman_hundred(num)
  elsif num <= 90 && num >= 10
    num_to_roman_ten(num)
  elsif num <= 10 && num >= 1 
    print roman_first[num-1]

  end
end

for i in ans_list do
  num_to_roman(i)
end

print "\n"

自分で書いてて思います。頭悪い実装です(笑)

(深夜にやっていて頭回ってないという言い訳をしときます(笑))

個別の関数毎の説明

  • divide_num 関数の中で受けとった数字を分解

  • num_to_roman_hundred, num_to_roman_ten はそれぞれの桁数に合わせてローマ数字に変換を行う

  • num_to_roman で全ての数字をローマ数字に変換

  • 追記

    • コードの改良を行った – 11/21
    • 改良版を下の方に載せときます

答え合わせ

では作成したプログラムが正しいかどうかの答え合わせをしましょう!!

  • 以下のようなプログラム(a.sh)を作成します

    for i in $(seq 1 3999);do
      ruby a.rb $i # a.rb はソースコードの名前なので何でもいいです
    done
    
  • bash a.sh > tmp.txt

  • エクセルから 3999 までのローマ数字を作成(1 分以内で可能)し、tmp2.txt として保存

  • diff tmp.txt tmp2.txt

何も出力されなければ成功!!

逆に出力されたら失敗してます。。。

追記(コード改良版)

  • num_to_roman_hundred と num_to_roman_ten の関数を統合してnum_to_roman_each 関数に変更した(new_roman_numeral.rb)

これで少しはコード少くなったかな?

(元のアルゴリズムが良くないからそんなに短くなってないけど、、、、)

num = ARGV[0]

def divide_num(num)
  ans_list,count = [],0
  while num > 0
    tmp = num % 10
    ans_list.push(tmp * (10 ** count))
    num = num / 10
    count = count + 1
  end
  return ans_list.reverse
end

ans_list,count = divide_num(num.to_i),0


def num_to_roman_each(num, f_str, s_str, t_str, fo_str)
  f_num = num.to_s[0].to_i
  if f_num == 9
    print f_str

  elsif f_num <= 8 && f_num >= 5
    if (f_num - 5) != 0
      print s_str + t_str * (f_num - 5)      
    else
      print s_str
    end

  elsif f_num == 4
    print fo_str

  elsif f_num <= 3 && f_num >= 1
    if (f_num - 1) != 0
      print t_str + t_str * (f_num - 1)
    else
      print t_str
    end

  end
end

def num_to_roman(num)
  roman_first = ['I','II','III','IV','V','VI','VII','VIII','IX','X']

  if num >= 1000
    tmp = num / 1000
    x = "M" * tmp
    print x

  elsif num <= 900 && num >= 100
    num_to_roman_each(num, "CM", "D", "C", "CD")

  elsif num <= 90 && num > 10
    num_to_roman_each(num, "XC", "L", "X", "XL")

  elsif num <= 10 && num >= 1 
    print roman_first[num-1]

  end
end

for i in ans_list do
  num_to_roman(i)
end

print "\n"

GitHub

以下の URL に全てのプログラムと txt file を置いておきます。


  • source ~/Downloads/git/grad_members_20f/members/taiseiyo/memos/roman.org
4
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
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?