PythonでFizzBuzz を色々と書いてみた

twitterのタイムラインがFizzBuzzの話題で盛り上がっていたので、やってみた。
普通のFizzBuzzだと面白さが足りないので、4つの実装方法で書いた。

仕様

1から100までの数をプリントするプログラムを書け。ただし3の倍数のときは数の代わりに「Fizz」と、5の倍数のときは「Buzz」とプリントし、3と5両方の倍数の場合には「FizzBuzz」とプリントすること。

実装 1 〜 シンプルなif...elif...

FizzBuzz で最初に挙がる回答だと思う。

#!/usr/bin/env python
# -*- coding: utf-8 -*-


class FizzBuzz(object):
    @classmethod
    def get_results(self, limit=100):
        results = []
        for n in range(1, limit + 1):
            if n % 3 == 0 and n % 5 == 0:
                results.append('FizzBuzz')
            elif n % 3 == 0:
                results.append('Fizz')
            elif n % 5 == 0:
                results.append('Buzz')
            else:
                results.append(str(n))
        return results


if __name__ == '__main__':
    for x in FizzBuzz.get_results():
        print x

実装 2 〜 リスト内包表記

Python三項演算子を使って、こんな感じ。
改行が多いのは、pep8に怒られないようにするためです。

    @classmethod
    def get_results(self, limit=100):
        return ['FizzBuzz' if x % 3 == 0 and x % 5 == 0 \ 
                else 'Fizz' if x % 3 == 0 \ 
                else 'Buzz' if x % 5 == 0 \ 
                else str(x) for x in range(1, limit + 1)] 
参考にしたページ

実装 3 〜 ジェネレータ式

ジェネレータ式を使ってみた。
仕様は100までだけど、大きな数字まで出力する場合はジェネレータ式がいいかも。

    @classmethod
    def get_results(self):
        n = 0
        while n < 100:
            n += 1
            if n % 3 == 0 and n % 5 == 0:
                yield 'FizzBuzz'
            elif n % 3 == 0:
                yield 'Fizz'
            elif n % 5 == 0:
                yield 'Buzz'
            else:
                yield str(n)

実装 4 〜 デコレータ式

数値型をfizzbuzzでラップしてみた・・・というネタ。

#!/usr/bin/env python
# -*- coding: utf-8 -*-


def fizzbuzz(num):
    class Wrapper(object):
        def __init__(self, num):
            self.__num = num
            if num % 3 == 0 and num % 5 == 0:
                self.fizzbuzz = 'FizzBuzz'
            elif num % 3 == 0:
                self.fizzbuzz = 'Fizz'
            elif num % 5 == 0:
                self.fizzbuzz = 'Buzz'
            else:
                self.fizzbuzz = str(num)

        def __getattr__(self, name):
            return getattr(self.__num, name)

        def __dir__(self):
            return dir(self.__num) + ['fizzbuzz']

    return Wrapper(num)


if __name__ == '__main__':
    for x in range(1, 101):
        num = fizzbuzz(x)
        print num.fizzbuzz