Skip to content

Instantly share code, notes, and snippets.

@RayStarkMC
Last active October 12, 2020 07:00
Show Gist options
  • Save RayStarkMC/4e86653cebbcf01261cd3a983663f2fe to your computer and use it in GitHub Desktop.
Save RayStarkMC/4e86653cebbcf01261cd3a983663f2fe to your computer and use it in GitHub Desktop.
FizzBuzzデモンストレーション
import raystark.fizzbuzz.FizzBuzzRule;
import raystark.fizzbuzz.FizzBuzzer;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
import static java.util.stream.Collectors.toList;
/**
* 自作したFizzBuzz生成システムを使ったFizzBuzzサンプル
*/
public class FizzBuzz {
public static void main(String[] args) {
/*
FizzBuzzは何らかの「コレクションから別のコレクションへの変換プロセス」の一種と考えることが出来る。
やっていることは整数のコレクションから文字列のコレクションへの変換。
FizzBuzzのルール
・3で割れたらFizz
・5で割れたらBuzz
・それら両方で割れる場合FizzBuzz
・いずれでも割れない場合整数をそのまま
・(追加ルール) 15の場合Huga
・(追加ルール) 30の場合Hoge
*/
//ルールのリストを作成 ルールには「割る数、対応する文字列」を渡す。
//リストの順番は条件の適用順になる 例えば15で割れる時にFizzBuzzではなくBuzzFizzと表示したい場合は
//5の条件を先に、3の条件を後にリストに追加すればいい。
var list = new ArrayList<FizzBuzzRule>();
list.add(FizzBuzzRule.of(3, "Fizz"));
list.add(FizzBuzzRule.of(5, "Buzz"));
//追加ルールのHuga, Hogeも追加。
list.add(FizzBuzzRule.of(15, "Huga"));
list.add(FizzBuzzRule.of(30, "Hoge"));
//変換規則のリストを渡してFizzBuzzerを作成。
var fizzbuzzer = new FizzBuzzer(list);
//変換する整数のリストを作成。
var range = range(0, 30);
//FizzBuzzerを用いてリストを変換する。
//FizzBuzzerは整数のリストとCollectorを受け取って整数のリストを文字列のリストへと変換する。
//Collectorの種類を変えることで任意の形で変換を施すことが出来る。
//例えば「変換結果をSetに詰めたい」「変換結果をコレクションではなく全ての文字列の連結として返したい」等
//でもFizzBuzz特化ならここはリストへの変換決め打ちでもよかったかもしれない(反省)
var fizzbuzzedList = fizzbuzzer.applyFizzBuzz(range, toList());
//FizzBuzzを施されたリストを出力
fizzbuzzedList.forEach(System.out::println);
}
private static List<Integer> range(int from, int to) {
return IntStream.rangeClosed(from, to).boxed().collect(toList());
}
}
import raystark.fizzbuzz.*;
import java.util.ArrayList;
import java.util.stream.IntStream;
import static java.util.stream.Collectors.toList;
public class SpecialFizzBuzz {
public static void main(String[] args) {
/*
ルール
・3で割れたらFizz
・5で割れたらBuzz
・15で割れたFizzBuzz
・その他の場合元の整数を文字列化
・ただし30で割れる場合も整数を文字列化
*/
//FizzBuzz変換の単位元 ""
final var SEED = FizzBuzzer.SEED;
/*
FizzBuzzerは通常のFizzBuzzのみ想定しているので文字列追加以外が出来ない。
よりFizzBuzzRuleの一般化ITransformRule、及びFizzBuzzerの一般化ReducingFizzBuzzerを使う。
各変換規則は変換時に「変換前の状態source」と「変換途中の状態value」を参照することが出来る
変換は累積的であるため、valueには直前までの全ての変換が施された状態である。
*/
var rules = new ArrayList<ITransformRule<Integer, String>>();
rules.add(FizzBuzzRule.of(3, "Fizz"));
rules.add(FizzBuzzRule.of(5, "Buzz"));
//30で割れる場合単位元に逆変換
//valueまでの変更を破棄してSEEDへと変換する
rules.add(new SourceBasedRule<>(source -> source%30 == 0, value -> SEED));
//ReducingFizzBuzzerの場合「空文字列の場合整数に変換」の部分を自動では行ってくれないので手動で実装する
rules.add(new ValueBasedRule<>(value -> value.equals(SEED), String::valueOf));
//ReducingFizzBuzzerは変換規則を順に適用する
//FizzBuzzerと違って受け取れる規則に制限はなく、一般のFizzBuzzに即さない規則を受け取る事も出来る
//ReducingFizzBuzzerを作成する場合は変換規則だけでなく変換の単位元SEEDを指定する必要がある
//今回はFizzBuzz変換(文字列の連結)の単位元なのでFizzBuzzer.SEEDを指定
var fizzbuzzer = new ReducingFizzBuzzer<>(rules, SEED);
var range = IntStream.rangeClosed(0, 60).boxed().collect(toList());
fizzbuzzer.applyFizzBuzz(range, toList()).forEach(System.out::println);
}
}
@RayStarkMC
Copy link
Author

FizzBuzzerの詳しい実装はこっちを見てね!!
https://github.com/RayStarkMC/GenericFizzBuzz

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment