How can one complete the FizzBuzz exercise in Codingbat with just a return statement?
The code that I last used to solve the problem was:
public String[] fizzBuzz(int start, int end) { String[] a = new String[end - start]; for(int i = start; i < end; i++) a[i - start] = i % 15 == 0 ? "FizzBuzz" : i % 3 == 0 ? "Fizz" : i % 5 == 0 ? "Buzz" : String.valueOf(i); return a; }
My goal is to have code that looks something like this:
public String[] fizzBuzz(int start, int end) { return foo; }
Problem
This is slightly more difficult version of the famous FizzBuzz problem which is sometimes given as a first problem for job interviews. (See also: FizzBuzz Code.) Consider the series of numbers beginning at start and running up to but not including end, so for example start=1 and end=5 gives the series 1, 2, 3, 4. Return a new
String[]
array containing the string form of these numbers, except for multiples of 3, use “Fizz” instead of the number, for multiples of 5 use “Buzz”, and for multiples of both 3 and 5 use “FizzBuzz”. In Java,String.valueOf(xxx)
will make the String form of an int or other type. This version is a little more complicated than the usual version since you have to allocate and index into an array instead of just printing, and we vary the start/end instead of just always doing 1..100.
Test Cases
fizzBuzz(1, 6) → ["1", "2", "Fizz", "4", "Buzz"] fizzBuzz(1, 8) → ["1", "2", "Fizz", "4", "Buzz", "Fizz", "7"] fizzBuzz(1, 11) → ["1", "2", "Fizz", "4", "Buzz", "Fizz", "7", "8", "Fizz", "Buzz"] fizzBuzz(1, 16) → ["1", "2", "Fizz", "4", "Buzz", "Fizz", "7", "8", "Fizz", "Buzz", "11", "Fizz", "13", "14", "FizzBuzz"] fizzBuzz(1, 4) → ["1", "2", "Fizz"] fizzBuzz(1, 2) → ["1"] fizzBuzz(50, 56) → ["Buzz", "Fizz", "52", "53", "Fizz", "Buzz"] fizzBuzz(15, 17) → ["FizzBuzz", "16"] fizzBuzz(30, 36) → ["FizzBuzz", "31", "32", "Fizz", "34", "Buzz"] fizzBuzz(1000, 1006) → ["Buzz", "1001", "Fizz", "1003", "1004", "FizzBuzz"] fizzBuzz(99, 102) → ["Fizz", "Buzz", "101"] fizzBuzz(14, 20) → ["14", "FizzBuzz", "16", "17", "Fizz", "19"]
Advertisement
Answer
The only way that I could imagine without any Java 8 features involves some ugly conversions of arrays to strings, and strings of arrays of strings to arrays of strings with some very … pragmatic regular expressions. But I guess the solution is not supposed to be pretty anyhow. It passes all the test cases, though, so it achieves all the goals that can be achieved with test-driven development…
Never write anything even remotely resembling this in real life!
import java.util.Arrays; public class OneLineFizzBuzz { public static void main(String[] args) { OneLineFizzBuzz f = new OneLineFizzBuzz(); String[] result = f.fizzBuzz(1000, 1006); System.out.println(Arrays.toString(result)); check(f.fizzBuzz(1, 6), new String[]{"1", "2", "Fizz", "4", "Buzz"}); check(f.fizzBuzz(1, 8), new String[]{"1", "2", "Fizz", "4", "Buzz", "Fizz", "7"}); check(f.fizzBuzz(1, 11), new String[]{"1", "2", "Fizz", "4", "Buzz", "Fizz", "7", "8", "Fizz", "Buzz"}); check(f.fizzBuzz(1, 16), new String[]{"1", "2", "Fizz", "4", "Buzz", "Fizz", "7", "8", "Fizz", "Buzz", "11", "Fizz", "13", "14", "FizzBuzz"}); check(f.fizzBuzz(1, 4), new String[]{"1", "2", "Fizz"}); check(f.fizzBuzz(1, 2), new String[]{"1"}); check(f.fizzBuzz(50, 56), new String[]{"Buzz", "Fizz", "52", "53", "Fizz", "Buzz"}); check(f.fizzBuzz(15, 17), new String[]{"FizzBuzz", "16"}); check(f.fizzBuzz(30, 36), new String[]{"FizzBuzz", "31", "32", "Fizz", "34", "Buzz"}); check(f.fizzBuzz(1000, 1006), new String[]{"Buzz", "1001", "Fizz", "1003", "1004", "FizzBuzz"}); check(f.fizzBuzz(99, 102), new String[]{"Fizz", "Buzz", "101"}); check(f.fizzBuzz(14, 20), new String[]{"14", "FizzBuzz", "16", "17", "Fizz", "19"}); } private static void check(String[] fizzBuzz, String[] strings) { boolean passed = Arrays.equals(fizzBuzz, strings); System.out.println(Arrays.toString(fizzBuzz) + " passed? " + passed); if (!passed) { System.out.println("Whoopsie..."); } } public String[] fizzBuzz(int start, int end) { return (start == end ? "" : (start % 15 == 0 ? "FizzBuzz" : start % 3 == 0 ? "Fizz" : start % 5 == 0 ? "Buzz" : String.valueOf(start)) + Arrays.toString(fizzBuzz(start + 1, end))) .replaceAll("\]", "").split("\[|,\s*"); } }