fizzbuzz関数のif文無し・ワンライナー縛り
今Flexで仕事していてたまに長いビルドがかかる時とかにちょろっと自動化のスクリプト書いたりしてるんですが、その時タイプミスしたことに気づかず実行したときに論理演算子のトリッキーな使い方を見つけた。
それが以下のコード。ちなみに言語はPythonです。
>>> hoge or "piyo": #hoge == False 'piyo'
おわかり頂けただろうか。
少しコードを変えて見てみよう。
>>> hoge and "piyo": #hoge == True piyo
正直なんでこうなるかっつーのはよく理解してないんだけどまあこんな仕様なんだろうということで遊び半分でfizzbuzz関数を書いてみた。
#! python # -*- coding:utf-8 -*- import unittest def fizzbuzz(num): return num % 15 == 0 and "fizzbuzz" or num % 3 == 0 and "fizz" or num % 5 == 0 and "buzz" or str(num) class TestFizzbuzz(unittest.TestCase): def test_return_fizz(self): self.assertEquals("fizz", fizzbuzz(3)); self.assertEquals("fizz", fizzbuzz(6)); def test_return_buzz(self): self.assertEquals("buzz", fizzbuzz(5)); self.assertEquals("buzz", fizzbuzz(10)); def test_return_fizzbuzz(self): self.assertEquals("fizzbuzz", fizzbuzz(15)); self.assertEquals("fizzbuzz", fizzbuzz(30)); def test_return_num(self): self.assertEquals("1", fizzbuzz(1)); self.assertEquals("2", fizzbuzz(2)); if __name__ == "__main__": unittest.main()
上の実行結果がこれ。
.... ---------------------------------------------------------------------- Ran 4 tests in 0.000s OK
見ての通りオールグリーンですよ!
fizzbuzzの定義はキモいですね!!
というかよくわかりませんね!!!
別の言語では?
とりあえずやってみたのはRubyとJavaScriptとJava。
xUnitはめんどいので端折りましたが、目視レベルで確認済み。
Javaは関数定義の時点で&&演算子はboolean型とString型で比較できませんよとコンパイラに怒られてアウトでした。
def fizzbuzz(num) return num % 15 == 0 && 'fizzbuzz' || num % 3 == 0 && 'fizz' || num % 5 == 0 && 'buzz' || num.to_s() end
function fizzbuzz(num){ return num % 5 == 0 && num % 3 == 0 && "fizzbuzz" || num % 3 == 0 && "fizz" || num % 5 == 0 && "buzz" || num.toString(); }
public static String fizzbuzz(int num) { return num % 3 == 0 && "fizz"; }
以上の事からダックタイピングできる言語はできて、演算子オーバーライドができる言語ではキモいfizzbuzzができそうですね。