続編: Pythonでアラビア数字をローマ数字に変換する工夫
リンク先↓のnotebookを参考に、chatGPTが書きました。
続編: Pythonでアラビア数字をローマ数字に変換する工夫
前回のブログ記事では、whileループを使ってアラビア数字をローマ数字に変換する方法を紹介しました。今回は、このコードをさらに工夫して、引き算を割り算に変えて効率よくローマ数字を生成する方法を紹介します。
Pythonでは、引き算の代わりに割り算を使って、より簡潔にローマ数字を構築できます。このアイデアを実際のコードに落とし込んで、ローマ数字をさらにスマートに作り出しましょう!
ステップ1:もとのコードを振り返る
まず、前回のコードを簡単におさらいします。このコードでは、whileループを使って引き算を行いながら、数字をローマ数字に変換していました。
number = 3 # 変換したいアラビア数字
result = ""
for arabic, roman in roman_numerals:
while number >= arabic:
number -= arabic
result += roman
print(roman, "残り:", number)
print(result)
たとえば、3を変換すると、出力は以下の通りです:
I 残り: 2
I 残り: 1
I 残り: 0
III
この方法でもうまく動作しますが、毎回「引いては足す」という処理を繰り返すため、もう少し効率化できる部分があると感じました。そこで、割り算を使ってみましょう!
ステップ2:割り算(商と余り)を使ったアプローチ
Pythonには便利な divmod() 関数があり、割り算の商と余りを一度に計算してくれます。この機能を活用して、引き算を繰り返す代わりに、ローマ数字を一気に追加できるようにしてみます。
まず、 divmod() がどう働くかを確認してみましょう。
# 3 / 1 の場合
div, mod = divmod(3, 1)
print(div, mod)
# 13 / 10 の場合
div, mod = divmod(13, 10)
print(div, mod)
出力は以下のようになります:
3 0
1
ここで div が商、 mod が余りを表しています。これを使って、商の回数分ローマ数字を足し、余りを次の処理に回すことができます。
ステップ3:引き算を割り算に置き換える
今度は、whileループを divmod() を使った割り算に書き換えます。商が計算できれば、その回数分だけローマ数字を一気に追加し、残りの数(余り)で次のループを続けることができます。
number = 33 # 変換したいアラビア数字
result = ''
for arabic, roman in roman_numerals:
div, mod = divmod(number, arabic)
result += div * roman
number = mod
print("ローマ数字:", roman, "商:", div, "途中経過:", result, "残り:", number)
これを実行すると:
ローマ数字: M 商: 0 途中経過: 残り: 33
ローマ数字: CM 商: 0 途中経過: 残り: 33
ローマ数字: D 商: 0 途中経過: 残り: 33
ローマ数字: CD 商: 0 途中経過: 残り: 33
ローマ数字: C 商: 0 途中経過: 残り: 33
ローマ数字: XC 商: 0 途中経過: 残り: 33
ローマ数字: L 商: 0 途中経過: 残り: 33
ローマ数字: XL 商: 0 途中経過: 残り: 33
ローマ数字: X 商: 3 途中経過: XXX 残り: 3
ローマ数字: IX 商: 0 途中経過: XXX 残り: 3
ローマ数字: V 商: 0 途中経過: XXX 残り: 3
ローマ数字: IV 商: 0 途中経過: XXX 残り: 3
ローマ数字: I 商: 3 途中経過: XXXIII 残り: 0
最終的な答えは:
答え: XXXII
割り算を使うことで、繰り返し処理がシンプルになり、商を使って一度にローマ数字を追加できるようになりました。
ステップ4:関数にまとめる
最後に、この新しいアプローチを関数にまとめて、再利用しやすくしてみましょう。
def convert_to_roman(number):
# ローマ数字とアラビア数字の対応表
roman_numerals = [
(1000, 'M'),
(900, 'CM'),
(500, 'D'),
(400, 'CD'),
(100, 'C'),
(90, 'XC'),
(50, 'L'),
(40, 'XL'),
(10, 'X'),
(9, 'IX'),
(5, 'V'),
(4, 'IV'),
(1, 'I')
]
result = ''
for arabic, roman in roman_numerals:
div, mod = divmod(number, arabic)
result += div * roman
number = mod
return result
この関数を使って、いろいろな数字を変換してみましょう。
ステップ5:テストしてみよう
さっそくテストしてみます!
print("8 => ", convert_to_roman(8)) # VIII と表示されるはず
print("9 => ", convert_to_roman(9)) # IX と表示されるはず
print("10 => ", convert_to_roman(10)) # X と表示されるはず
print("11 => ", convert_to_roman(11)) # XI と表示されるはず
print("578 => ", convert_to_roman(578)) # DLXXVIII と表示されるはず
実行結果:
8 => VIII
9 => IX
10 => X
11 => XI
578 => DLXXVIII
まとめ
今回は、前回のwhileループによる引き算をさらに改善して、割り算を使ったより効率的な方法でアラビア数字をローマ数字に変換する方法を紹介しました。この方法を使うことで、計算がシンプルになり、コードの見通しもよくなりましたね!
このように、プログラムの中のちょっとした工夫が、大きな改善につながることも多いです。ぜひ、今回のアイデアを他のプロジェクトにも応用してみてください!
次回も、楽しいPythonのトピックを取り上げていきますので、お楽しみに!
最後に
この記事の課題は、私が師と仰ぐ、
「かめ@米国データサイエンティスト」 さんのコミュニティーの中の coding_challenge の課題を参考にしています。
3年くらい前から、「かめ@米国データサイエンティスト」 さんのブログ、Udemy講座などで、pythonとDSをゆっくり勉強中です。