奥深き競技プログラミングの世界 〜 第1問・解答編 〜

さて勝手に始めている競技プログラミングシリーズの解答編第1問
出題編からだいぶ時間が空いてしまったが転職を含むプライベートでのアレコレが漸く片付いたので満を持して解答編をお送りしたい

どんな問題だったかを確認したい場合はこちらの過去記事をどうぞ
奥深き競技プログラミングの世界 〜 第1問・出題編 〜

第1問 「携帯文字入力」 Lv. ★

# 文字変換用テーブル
CHAR_MATRIX = [
    [''],
    ['.', ',', '!', '?', ' '],
    ['a', 'b', 'c'],
    ['d', 'e', 'f'],
    ['g', 'h', 'i'],
    ['j', 'k', 'l'],
    ['m', 'n', 'o'],
    ['p', 'q', 'r', 's'],
    ['t', 'u', 'v'],
    ['w', 'x', 'y', 'z']
]

# 与えられた文字列を文字に変換する関数
def convert(string):
    row    = int(string[:1])
    column = (len(string) - 2) % len(CHAR_MATRIX[row])

    return CHAR_MATRIX[row][column]

# (与えられた文字列が空になるまで…)先頭から'0'までを文字に変換して、残った部分に末尾再帰を行う関数
def execute(string, output=''):
    if len(string) == 0: return output

    preString  = string[:string.find('0') + 1]
    postString = string[string.find('0') + 1:]

    return execute(postString, output=output + convert(preString))

# メイン関数
def main():
    print(execute(input()))

if __name__ == '__main__': main()

時間が足りないためバリデーションや例外処理は行なっていないが多くの人がこの例と同じような考えで実装したのではないかと思う

ループを用いるか再帰を用いるかはどちらでも問題無いのだがもし再帰を用いる場合は末尾再帰となるように注意しなければならない
これは関数を呼ぶ際に積まれるコールスタックがオーバーフローを起こさないためである(※Pythonは末尾再帰最適化しないようだ…)