はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【Python】FizzBuzz問題を解いてみる

はじめに

普段はC#を使っているのですが、最近どうしてもPythonを使わなければいけなくなったので勉強をしています。

以前このような記事を書いたのですが、Pythonを慣れるためにこれをPythonでやってみようと思った訳です。
www.hanachiru-blog.com

早速みていきましょう。

簡単な実装

一番シンプルそうな実装をまずしてみたいと思います。

def fizzbuzz(start, end):
    n = start
    while n < end:
        if n % 15 == 0:
            yield "FizzBuzz"
        elif n % 3 == 0:
            yield "Fizz"
        elif n % 5 == 0:
            yield "Buzz"
        else:
            yield str(n)
        n = n + 1

for item in fizzbuzz(1, 20):
    print(item)

これはジェネレータ関数を使って実装した例になります。

ジェネレータはイテラブルなオブジェクト(C#でいうコレクション?)と同じようにfor-inで値を取り出せるのでエレガントにかけます。

また必要な時に適宜要素を取り出す、いわゆる遅延評価ができるのでメモリにも優しいです。

名前や文法は違えど、C#でもほぼ同じような書き方ができますよね。
【C#】約数を列挙するプログラムを実装してみる - はなちるのマイノート

改良版

C#での記事同様、ルールを追加できるように改良してみましょう。

class FizzBuzz:
    def __init__(self):
        self.__rules = []

    def excute(self, start, end, func):
        for i in range(start, end):
            func(self.__get_text(i))

    def add_rule(self, rule):
        self.__rules.append(rule)

    def __get_text(self, n):
        s = ""
        for rule in self.__rules:
            s += rule(n)
        return s if s != "" else n

game = FizzBuzz()
game.add_rule(lambda n : "Fizz" if n % 3 == 0 else "")
game.add_rule(lambda n : "Buzz" if n % 5 == 0 else "")
game.excute(1, 20, lambda n : print(n))

なんとかちゃんと動くようにできましたが、はっきり言ってPythonのあまりの書きにくさに驚きを隠せませんでした。

私の理解不足なだけかもしれませんが、引数の型を指定できない(一応警告?みたいのは出せるらしい)点は言語としてどうなのかと思います。

例えばルールを付け加えるときにも、クラスの構造を知っている人しか正しく引数を設定できないような気がしてならないんですよね。特に複数人で作業なんて無謀のような。。。

それとも毎回希望する型以外の引数が来たらエラーを吐いたりなんかをしなきゃいけないのでしょうか。うーん。

さいごに

私は本当にPython初心者なので、結構間違った書き方なんかをしてたりするかもしれません。

最後の方は愚痴がたくさんこぼれてしまいましたが、最近の一番人気な言語ということで今後の需要も高まるに違いないでしょう。

もしご指摘などがありましたら、是非コメント等で教えていただけると幸いです。

ではまた。