challenge 変形Fizz-Buzz問題

どもraynstardです。
どちらにしようか迷いましたが発想の元ネタがUIさんの投稿からなので
こちらに投稿してみます。
--------------
以下の仕様を満たす文字列を
20行出力するプログラムを作成してください。

1. 1行の出力は「<行番号> ':' <メッセージ>」であること。
2. 行番号が 3の倍数であるとき、メッセージは「Fizz」であること
3. 行番号が 5の倍数であるとき、メッセージは「Buzz」であること
4. 行番号が 3の倍数かつ5の倍数であるとき、メッセージは「FizzBuzz」であること
5. 上記に記した条件以外のメッセージについては「hoge」であること
6. 条件分岐する場合、if文のみが使用でき、
   かつ、論理式が成立した場合の処理のみが記述できます。
#アセンブリなどifがなければif以外でもかまわないです。(意味が同じならば)

というわけでこの問題はFizz-Buzz問題をelseなしならどう書く?という問題です。

出力例:
 1:hoge
 2:hoge
 3:Fizz
 4:hoge
 5:Buzz
 6:Fizz
 7:hoge
 8:hoge
 9:Fizz
10:Buzz
11:hoge
12:Fizz
13:hoge
14:hoge
15:FizzBuzz
16:hoge
17:hoge
18:Fizz
19:hoge
20:Buzz

Posted feedbacks - Python

elseを使わないってのはこういうことなんでしょうか?
elseと同等のコードがcontinueで書けてしまってますが。

三項演算子を使おうかと思ったけど、三項演算子もelesだよなぁと思った。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
def FizzBuzz(num):
    for x in xrange(1,num+1):
        if x % 15 == 0:
            print "%2d:FizzBuzz" % x
            continue
        if x % 5 == 0:
            print "%2d:Buzz" % x
            continue
        if x % 3 == 0:
            print "%2d:Fizz" % x
            continue
        print "%2d:hoge" % x
        
FizzBuzz(20)

FizzBuzzを表示する行数が可変では無いので、
この答えでもお題を満たすような気がしてきた。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
print ''' 1:hoge
 2:hoge
 3:Fizz
 4:hoge
 5:Buzz
 6:Fizz
 7:hoge
 8:hoge
 9:Fizz
10:Buzz
11:hoge
12:Fizz
13:hoge
14:hoge
15:FizzBuzz
16:hoge
17:hoge
18:Fizz
19:hoge
20:Buzz'''

if文を使わない方法。

あらかじめ3つとばし、5つとばし、15個飛ばしで必要な文字列を書き込んでおきます。後から書いた15飛ばしので上書きされるのでelseが消えるという話。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
def fizzbuzz(n):
    r = range(n + 1)
    map = {}
    for i in r[::3]:
        map[i] = "Fizz"
    for i in r[::5]:
        map[i] = "Buzz"
    for i in r[::15]:
        map[i] = "FizzBuzz"
    for i in r[1:]:
        print "%d:%s" %(i, map.get(i, "hoge"))

        
fizzbuzz(20)

DRYではありませんが。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
def fizzbuzz(n=20):
  d = len( str(n))
  
  for i in range(1,n+1):
    F,B = i%3==0,i%5==0
    
    if F==B:
      if not F:  print "%*d:hoge"%(d,i)
      if F:     print "%*d:FizzBuzz"%(d,i)
    if F<>B:
      if F:     print "%*d:Fizz"%(d,i)
      if not F:  print "%*d:Buzz"%(d,i)

周期3のリストと周期5のリストを合成。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from itertools import izip, cycle

def messages():
    for x, y in izip(cycle('  Fizz'.split(' ')), cycle('    Buzz'.split(' '))):
        yield x + y or 'hoge'

def fizzbuzz():
    for i, s in izip(range(1, 1 + 20), messages()):
        print '%2d:%s' % (i, s)

if __name__ == '__main__':
    fizzbuzz()

素直なのはこうかな。
continue が散らばるのは良くなさそう。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
def message(n):
    s = ''
    if n % 3 == 0:
        s += 'Fizz'
    if n % 5 == 0:
        s += 'Buzz'
    if len(s) == 0:
        s = 'hoge'
    return s

def fizzbuzz():
    for i in range(1, 1 + 20):
        print '%2d:%s' % (i, message(i))

if __name__ == '__main__':
    fizzbuzz()

出力は4パターンしかないんだから、適当に整数変換できれば良い。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
_MESSAGES = 'hoge Fizz Buzz FizzBuzz'.split()
def message(n):
    i = int(n % 3 == 0) + int(n % 5 == 0) * 2
    return _MESSAGES[i]

def fizzbuzz():
    for i in range(1, 1 + 20):
        print '%2d:%s' % (i, message(i))

if __name__ == '__main__':
    fizzbuzz()

あえて穴を捜すなら、行番号を1ずつ増やせとはどこにも書いていないのでこれも仕様通りだと主張できるかもw
1
print "1:hoge\n" * 20

list内包で遊んでたらワンライナになった。
1
for m in ['%2d:%s' %(i,('hoge','Fizz','Buzz','FizzBuzz')[ int(i%3==0)+int(i%5==0)*2 ]) for i in range(1,21)]:print m

Index

Feed

Other

Link

Pathtraq

loading...