FizzBuzzをJavaでやってみる

有名なFizzBuzz問題というのを解いたことがなかったのでやってみた。

1から100までの数をプリントするプログラムを書け。ただし3の倍数のときは数の代わりに「Fizz」と,5の倍数のときは「Buzz」とプリントし,3と5両方の倍数の場合には「FizzBuzz」とプリントすること。

ただ目的を達するだけではつまらないので、より汎用化した記述にしてみた。

public class FizzBuzzMaker {
    
    //このフィールドに対となる数値と文字列を格納しておく
    Map<Integer, String> table = new LinkedHashMap<Integer, String>();
    
    void addRecord(Integer i, String s){
        table.put(i, s);
    }
    
    //数値を文字列に変換する際はtableを見る
    String generateString(int i){
        StringBuilder sb = new StringBuilder();
        Set<Integer> keys = table.keySet();
        for (Integer key : keys) {
            if(i % key == 0) sb.append(table.get(key));
        }
        if(sb.length() == 0) sb.append(i);
        
        return sb.toString();
    }
    
    public static void main(String[] args) {
        FizzBuzzMaker fizzBuzzMaker = new FizzBuzzMaker();
        //数値と文字列を指定
        fizzBuzzMaker.addRecord(3, "Fizz");
        fizzBuzzMaker.addRecord(5, "Buzz");

        for (int i = 1; i <= 100; i++) {
            System.out.println(fizzBizzMaker.generateString(i));
        }
    }
    
}

この問題には、3とか5の特定の数値に限らず一つ共通化できるロジックがある。それは指定した数値の倍数だった場合、指定した数値の対となる文字列を出力するという点。その部分を汎用化すると上のような記述になった。

オブジェクトのフィールド"table" に数値と対になる文字列を格納し、判定をする際はそのテーブルを見て文字列に変換する形になる。

こうしておけば、仮に「7の倍数が来たときに"Kazz" という文字列を表示する。3と7の倍数の場合は"FizzKazz", 5と7の倍数の場合は"BuzzKazz", 3と5と7の倍数の場合は"FizzBuzzKazz" を表示する」とかいう条件が増えても、レコードを一つ追加するだけで対応できる。

    public static void main(String[] args) {
        FizzBuzzMaker fizzBuzzMaker = new FizzBuzzMaker();
        fizzBuzzMaker.addRecord(3, "Fizz");
        fizzBuzzMaker.addRecord(5, "Buzz");
        fizzBuzzMaker.addRecord(7, "Kazz");    //追加

        for (int i = 1; i <= 105; i++) {
            System.out.println(fizzBizzMaker.generateString(i));
        }
    }

出力結果

1
2
Fizz
4
Buzz
Fizz
Kazz
8
Fizz
Buzz
11
Fizz
13
Kazz
FizzBuzz
16
17
Fizz
19
Buzz
FizzKazz
22
23
Fizz
Buzz
26
Fizz
Kazz
29
FizzBuzz
31
32
Fizz
34
BuzzKazz
Fizz
37
38
Fizz
Buzz
41
FizzKazz
43
44
FizzBuzz
46
47
Fizz
Kazz
Buzz
Fizz
52
53
Fizz
Buzz
Kazz
Fizz
58
59
FizzBuzz
61
62
FizzKazz
64
Buzz
Fizz
67
68
Fizz
BuzzKazz
71
Fizz
73
74
FizzBuzz
76
Kazz
Fizz
79
Buzz
Fizz
82
83
FizzKazz
Buzz
86
Fizz
88
89
FizzBuzz
Kazz
92
Fizz
94
Buzz
Fizz
97
Kazz
Fizz
Buzz
101
Fizz
103
104
FizzBuzzKazz

FizzBuzzKazzは105まで出てこなかった。。