見出し画像

続編: 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をゆっくり勉強中です。


いいなと思ったら応援しよう!