I tried to make FizzBuzz that is uselessly flexible

I tried to make the famous problem FizzBuzz that many programmers go through into an extremely flexible implementation in vain.

--Policy - Java11 --Active use of standard library --Finally it will be like a Builder Pattern

General solution

It will be shorter if you devise various things, but is it like this if the answer appears in a textbook?

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 % 3 == 0) {
                System.out.println("Fizz");
            } else if (i % 5 == 0) {
                System.out.println("Buzz");
            } else {
                System.out.println(i);
            }
        }
    }
}

output (combined in one line for easy viewing)

1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz ...

Demon remodeling started

Externalize pairs such as "3: Fizz" and "5: Buzz"

--Save in Map format --Judge each number and combine character strings with Stream

Map<Integer, String> map = new HashMap<>();
map.put(3, "Fizz");
map.put(5, "Buzz");

for (int i = 1; i <= 100; i++) {
    final int current = i; //Will disappear after this
    String result = map.entrySet().stream()
            .filter(v -> current % v.getKey() == 0)
            .map(Entry::getValue)
            .reduce("", (left, right) -> left + right);
    System.out.println(result.isBlank() ? i : result);
}

Separated into separate methods

--Separated into methods that return results as a list ――By the way, you can customize the start and end values.

public static List<String> fizzBuzz(int start, int end, Map<Integer, String> map) {
    return IntStream.rangeClosed(start, end).mapToObj(i -> {
        String result = map.entrySet().stream()
                .filter(v -> i % v.getKey() == 0)
                .map(Entry::getValue)
                .reduce("", (left, right) -> left + right);
        return result.isBlank() ? String.valueOf(i) : result;
    }).collect(Collectors.toList());
}

public static void main(String[] args) {
    Map<Integer, String> map = new HashMap<>();
    map.put(3, "Fizz");
    map.put(5, "Buzz");

    fizzBuzz(1, 100, map).forEach(System.out::println);
}

Make it look like a Builder pattern

--In general, the build method in the Builder pattern should return an independent class, but here it returns List \ <String >. ――If you do it properly, maybe you will divide it into two classes, "FizzBuzzBuilder" and "FizzBuzz". --javadoc is omitted

import java.util.*;
import java.util.Map.Entry;
import java.util.stream.*;

public class FizzBuzz {
    private Map<Integer, String> map = new HashMap<>();
    private int start = 1;
    private int end = 100;

    public List<String> build() {
        return IntStream.rangeClosed(start, end).mapToObj(i -> {
            String result = map.entrySet().stream()
                    .filter(v -> i % v.getKey() == 0)
                    .map(Entry::getValue)
                    .reduce("", (left, right) -> left + right);
            return result.isBlank() ? String.valueOf(i) : result;
        }).collect(Collectors.toList());
    }

    public FizzBuzz addPair(int value, String text) {
        map.put(value, text);
        return this;
    }

    public FizzBuzz start(int start) {
        this.start = start;
        return this;
    }

    public FizzBuzz end(int end) {
        this.end = end;
        return this;
    }

    public static void main(String[] args) {
        new FizzBuzz()
                .start(1)
                .end(20)
                .addPair(3, "Fizz")
                .addPair(5, "Buzz")
                .build()
                .forEach(System.out::println);
    }
}

Test run

――Because it's a big deal, we tested with disjoint 3, 5, 11, 13 --Since the least common multiple is 2145, output around 2130 to 2150.

new FizzBuzz()
        .start(2130)
        .end(2150)
        .addPair(3, "Fizz")
        .addPair(5, "Buzz")
        .addPair(11, "Foo")
        .addPair(13, "Bar")
        .build()
        .forEach(System.out::println);

result

FizzBuzz
2131
Bar
Fizz
Foo
Buzz
Fizz
2137
2138
Fizz
Buzz
2141
Fizz
2143
2144
FizzBuzzFooBar
2146
2147
Fizz
2149
Buzz

Bonus: JavaScript version

This is what happens when someone who is not familiar with the JavaScript paradigm creates it It seems to be different from what the main job makes, so it is just for reference

(() => {
    class FizzBuzz {
        constructor() {
            this._from = 1;
            this._to = 100;
            this._pair = [];
        }
        build() {
            const convert = i => this._pair
                .filter(divisor => i % divisor.value == 0)
                .reduce((left, right) => left + right.text, "") || i;
            return [...Array(this._to - this._from + 1).keys()]
                .map(i => i + this._from)
                .map(convert);
        }
        addPair(value, text) {
            this._pair.push({value: value, text: text});
            return this;
        }
        from(from) {
            this._from = from;
            return this;
        }
        to(to) {
            this._to = to;
            return this;
        }
    };
    new FizzBuzz()
        .from(2130)
        .to(2150)
        .addPair(3, "Fizz")
        .addPair(5, "Buzz")
        .addPair(11, "Foo")
        .addPair(13, "Bar")
        .build()
        .forEach(result => console.log(result));
})();


Recommended Posts

I tried to make FizzBuzz that is uselessly flexible
What is Docker? I tried to summarize
I tried to make Numeron which is not good in Ruby
I tried FizzBuzz.
I tried to make a Web API that connects to DB with Quarkus
[Introduction to Java] I tried to summarize the knowledge that I think is essential
I tried to make Basic authentication with Java
I tried to make a login function in Java
I tried to make a program that searches for the target class from the process that is overloaded with Java
I tried the FizzBuzz problem
I tried to verify yum-cron
I tried to make an application in 3 months from inexperienced
I tried to make Venn diagram an easy-to-understand GIF animation
I tried to verify this and that of Spring @ Transactional
I tried using Hotwire to make Rails 6.1 scaffold a SPA
I tried to make Java Optional and guard clause coexist
I tried to make a client of RESAS-API in Java
I tried to make an app that allows you to post and chat by genre ~ App overview ~
[Java] I tried to make a rock-paper-scissors game that beginners can run on the console.
I tried to summarize the words that I often see in docker-compose.yml
I tried to summarize iOS 14 support
I tried to implement flexible OR mapping with MyBatis Dynamic SQL
[Unity] I tried to make a native plug-in UniNWPathMonitor using NWPathMonitor
I tried to interact with Java
I tried to explain the method
Since the Rspec command is troublesome, I tried to make it possible to execute Rspec with one Rake command
I tried to make an Android application with MVC now (Java)
I tried to understand how the rails method "link_to" is defined
I tried to make it an arbitrary URL using routing nesting
[Java] I tried to make a maze by the digging method ♪
I tried to summarize Java learning (1)
Collatz number, Fibonacci number, triangular number I tried to make various sequence programs
How to identify the path that is easy to make a mistake
I tried to understand nil guard
I tried to summarize Java 8 now
I tried to chew C # (polymorphism: polymorphism)
I tried to explain Active Hash
I tried to make a group function (bulletin board) with Rails
I tried to make a parent class of a value object in Ruby
I tried to make a simple face recognition Android application using OpenCV
[Rails] I tried to implement a transaction that combines multiple DB processes
I tried to make an automatic backup with pleasanter + PostgreSQL + SSL + docker
[iOS] I tried to make a processing application like Instagram with Swift
I tried to make my own transfer guide using OpenTripPlanner and GTFS
I made a virtual currency arbitrage bot and tried to make money
[Java] I want to make it easier because it is troublesome to input System.out.println.
My memorandum that I want to make ValidationMessages.properties UTF8 in Spring Boot
I tried to make full use of the CPU core in Ruby
I tried to make a talk application in Java using AI "A3RT"
[Ruby] I tried to summarize the methods that frequently appear in paiza
[Ruby] I tried to summarize the methods that frequently appear in paiza ②
I tried to summarize the methods used
I tried to introduce CircleCI 2.0 to Rails app
I tried migrating Processing to VS Code
I want to make an ios.android app
I tried to summarize Java lambda expressions
I tried to get started with WebAssembly
I tried to solve AOJ's Binary Search
I tried to implement the Iterator pattern
I tried to summarize the Stream API
Write code that is difficult to test