LoginSignup
9
6

More than 5 years have passed since last update.

最短であってほしい Julia の FizzBuzz

Last updated at Posted at 2019-02-27

科学技術計算で最近流行りの Julia。FizzBuzz で練習しました。使用バージョンは 1.1.0。

普通のやつ (131 byte)

for i in 1:100
    if i % 3 == 0 && i % 5 == 0
        println("FizzBuzz")
    elseif i % 3 == 0
        println("Fizz")
    elseif i % 5 == 0
        println("Buzz")
    else
        println(i)
    end
end

余計な空白をなくして長さを計算すると137 byte

文字列結合パターン(92 byte)

 Fizz も Buzz も2回ずつ登場しているのが8byteの無駄です。println文も一度で良いでしょう。そこで,最終的に出力する文字列のために変数を1つ用意することにした黄金パターン。この方針で短くしていきます。

for i in 1:100
    s = ""
    if i % 3 == 0
        s = "Fizz"
    end
    if i % 5 == 0
        s *= "Buzz"
    end
        println(s == "" ? i : s)
end

if 文なし (87 byte)

 if 文は end で結ぶ必要があるので無駄です。Julia には三項演算子があるのでそちらを用います。しかし,実は三項演算子のスペースが削れない関係で,そこまで短くできない……

for i in 1:100
    s  = i % 3 == 0 ? "Fizz" : ""
    s *= i % 5 == 0 ? "Buzz" : ""
    println(s == "" ? i : s)
end

代入は一回で(82 byte)

 三項演算子を用いた代入が2回あるのが無駄に見えます。要は,Fizz・Buzz のあるなしを区別できれば良いので,文字列の繰り返しや結合を駆使します。
 Julia では,多くの言語と少し変わって,文字列の結合は*1,繰り返しは^を使います。

for i in 1:100
    println((s = "Fizz"^((2 - i % 3) ÷ 2) * "Buzz"^((4 - i % 5) ÷ 4))=="" ? i : s)
end

 文字列の繰り返しを1回にしたり0回にしたりすることで Fizz, Buzz の出力をコントロールしている感じです。Julia の ÷ は整数へと切り捨てる割り算になります(Python3 の //相当)。

最後の切り詰め(69 byte)

 Julia に詳しい人たちにアドバイスをもらい,

  • for の代わりに ブロードキャストを使った繰り返し(mapを使うよりも短い)。
  • x=...==""の部分をx=...>""とする
  • (2 - i % 3) ÷ 2の部分で,インデックスを1ずらすことによりi % 3 ÷ 2でできるように

という工夫の結果,69 byteまで短縮しました。

(i->println((x="Fizz"^(i%3÷2)*"Buzz"^(i%5÷4))>"" ? x : i+1)).(0:99)

最後に

ゴルフ向きの Perl には敵わないとしても,Python3 で 49 byte とか出ているみたいなので,せめて 60 台には載せたかったです。みなさまのご協力お待ちしております。

9
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6