パスワードを忘れた? アカウント作成
13378608 journal
日記

tuneoの日記: なつやすみのじゆうけんきゅう:ふぃずばず 4

日記 by tuneo

世にあまたあるFizzBuzzプログラムを見ていてイマイチぐっと来ない点が「なんで剰余を2回計算してんねん」というところだったりする。

  • 整数nが3の倍数だったら文字列Fizzを表示する
  • 整数nが5の倍数だったら文字列Buzzを表示する
  • 整数nが3の倍数かつ5の倍数だったら文字列FizzBuzzを表示する
  • 整数nがそれ以外の場合は何も表示しない

と言われて、

msg = ""
if (n % 3 == 0) and (n % 5 == 0):
  msg = "FizzBuzz"
elif n % 3 == 0:
  msg = "Fizz"
elif n % 5 == 0:
  msg = "Buzz"
print(msg)

と書くのって、控えめに言ってもバカっぽくない?整数の剰余計算なら繰り返してもそれほど困らない(し、言語処理系によってはオプティマイザが鼻歌交じりに最適化してくれる)が、例えば「ファイルの中を全文検索して云々」とか言われたらやっとれんだろうに。計算結果は再利用してなんぼ。

mod3 = n % 3
mod5 = n % 5
msg = ""
if mod3 == 0 & mod5 == 0:
  msg = "FizzBuzz"
elif mod3 == 0:
  msg = "Fizz"
elif mod5 == 0:
  msg = "Buzz"
print(msg)

少なくともこれぐらいはやりたいが、これも剰余と0の比較が2回あるのが好かない。

isMultipleOf3 = (n % 3) == 0
isMultipleOf5 = (n % 5) == 0
msg = ""
if isMultipleOf3 and isMultipleOf5:
  msg = "FizzBuzz"
elif isMultipleOf3:
  msg = "Fizz"
elif isMultipleOf5:
  msg = "Buzz"
print(msg)

こんな感じか。Pythonに特化すると、タプルはイミュータブルなシーケンスなので辞書のキーになれることを利用して

fizzbuzz = { (False, False) : "", (True, False) : "Fizz", (False, True) : "Buzz", (True, True) : "FizzBuzz" }
print(fizzbuzz[(n % 3 == 0, n % 5 == 0)])

と書いてしまうこともできるな。
なお、3の倍数でFizz、5の倍数でBuzz、3と5の公倍数ならそれらを連結したもの、と考えれば、文字列連結で手抜きができる。

msg = ""
if n % 3 == 0:
  msg += "Fizz"
if n % 5 == 0:
  msg += "Buzz"
print(msg)

一行で

print("".join(("Fizz" if n % 3 == 0 else "", "Buzz" if n % 5 == 0 else "")))

なんてのも。ただし、例えば3の倍数でfoo,5の倍数でbar,3と5の公倍数でbazを表示しろ、なんて仕様だと破綻するけどw

ちなみにこのFizzBuzz、剰余演算子を使わないで倍数の判定をやる、という縛りを入れることもあるんだとか。5の倍数の判定は十進表記の1の位が「0」か「5」になるから簡単だけど、3の倍数はどういう性質があったかな。3の倍数は全桁の数字の和も3の倍数になる、というのはかろうじて覚えてるんで、10未満になるまで各桁の数字を繰り返し足して、3/6/9のどれかだったら3の倍数、ってことになるのか。美しくない。

この議論は、tuneo (2938)によって「 テキとトモのテキ禁止」として作成されている。 君は誰かに嫌われているようだね★
typodupeerror

クラックを法規制強化で止められると思ってる奴は頭がおかしい -- あるアレゲ人

読み込み中...