Javaで三項演算子/再帰/StaticInitializerを使ったFizzBuzzを試してみた

会社で、FizzBuzzなら三項演算子使わなきゃね、と言われたのがきっかけ。
三項演算子は知ってはいたけど、ほとんど使ったことがなかった。
そこで、いろんなFizzBuzzを作ってみた。

普通のFizzBuzz

public class FizzBuzz{
  public static void main(String args[]){
    for(int i=1; i<=100; i++){
      if(i%15 == 0){
        System.out.println("FizzBuzz");
      }else if(i%5 == 0){
        System.out.println("Buzz");
      }else if(i%3 == 0){
        System.out.println("Fizz");
      }else{
        System.out.println(i);
      }
    }
  }
}

なんのひねりもない。

三項演算子を使ったFizzBuzz

public class FizzBuzz3{
  public static void main(String args[]){
    for(int i=1; i<=100; i++){
      System.out.println( i%15 == 0 ? "FizzBuzz" : i%5 == 0 ? "Buzz" : i%3 == 0 ? "Fizz" : i);
    }
  }
}

美しい三項演算子の書き方がわからない。

再帰を使ったFizzBuzz

public class FizzBuzzRecursion{
  public static void main(String args[]){
    rec(1,100);
  }
  public static void rec(int i, int max){
    if(i%15 == 0){
      System.out.println("FizzBuzz");
    }else if(i%5 == 0){
      System.out.println("Buzz");
    }else if(i%3 == 0){
      System.out.println("Fizz");
    }else{
      System.out.println(i);
    }
    if(i < max){
      rec(i+1,max);
    }
  }
}

<追記:2008/03/20> ↑再帰呼び出しのメソッド名のtypoを直した><
普通の再帰だ。
mainメソッドでも再帰はできるのでやってみる。
これはどう書く?orgで知ったんだけど、今日はなぜかサーバに繋がらなかったので、頑張って書いたさ。

public class FizzBuzzRecursionMain{
  public static void main(String args[]){
    
    int i   = Integer.parseInt(args[0]);
    int max = Integer.parseInt(args[1]);
    
    if(i%15 == 0){
      System.out.println("FizzBuzz");
    }else if(i%5 == 0){
      System.out.println("Buzz");
    }else if(i%3 == 0){
      System.out.println("Fizz");
    }else{
      System.out.println(i);
    }
    
    if(i < max){
      main(new String[]{Integer.toString(i+1),arg[1]});
    }
  }
}

こんなの普通思いつかないと思う。

StaticInitializerを使ったFizzBuzz

class FizzBuzzStatic{
  static{
    for(int i=1; i<=100; i++){
      if(i%15 == 0){
        System.out.println("FizzBuzz");
      }else if(i%5 == 0){
        System.out.println("Buzz");
      }else if(i%3 == 0){
        System.out.println("Fizz");
      }else{
        System.out.println(i);
      }
    }
    System.exit(0);
  }
}

public修飾子も省略できる。
StaticInitializerって、どんなときに使えばいいんだろう。
まともな用途があまり思いつかない。

きっとJavaではいちばん短いFizzBuzz

class FizzBuzzMin{
  static{
    for(int i=1; i<101; i++){
      System.out.println( i%15 == 0 ? "FizzBuzz" : i%5 == 0 ? "Buzz" : i%3 == 0 ? "Fizz" : i);
    }
  System.exit(0);
  }
}

↑が原型で、↓がきっとJavaでは世界一短いFizzBuzz

class A{static{for(int i=1;i<=100;i++){System.out.println(i%15==0?"FizzBuzz":i%5==0?"Buzz":i%3==0?"Fizz":i);}System.exit(0);}}

127byteになった。これよりも短くできるのかな。
そして↓はそのワンライナー

echo "class A{static{for(int i=1;i<101;i++){System.out.println(i%15==0?\"FizzBuzz\":i%5==0?\"Buzz\":i%3==0?\"Fizz\":i);}System.exit(0);}}">A.java;javac A.java;java A

これで166byte。シェルの部分はなんとなくもう少し改善できそうな気がするなぁ。
System.exit(0)をはずしてもいいんだけど、やっぱりエラーで終了というはなんとも言えないので・・・。


今日はFizzBuzzに3時間近く費やした・・・。
知らないことがけっこう多かった。
FizzBuzzだけでもこんなに勉強になる。


とりあえずGoogleJavaワンライナーと言えば僕がいちばんだ!