WIll WIll - 3 months ago 19
Java Question

How to do fizzBuzz in Java, Recursively And Efficiently at the same time

PS:This a problem where recursion is typically stupid to do.

Note that this is not homework, I know that this really stupid to do recursion on, but for the sake of sharpening my recursion skills I completed the following problem:

CodingBat code practice
Java > Array-2 > fizzBuzz
prev | next | chance


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
. 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.

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"}


And my LONG Recursive Solution Code:

public String[] fizzBuzz(int start, int end) {
return recurFizzBuzz(new String[end - start], 0, start, end);
}

public String[] recurFizzBuzz(String[] result, int index, int start, int end){
if(index == result.length - 1
&& start == end - 1
&& start % 15 == 0){
//mod 15, MOD 3 AND MOD 5
result[result.length - 1] = "FizzBuzz";
return result;
}
else if(index == result.length - 1
&& start == end - 1
&& start % 3 == 0){
result[result.length - 1] = "Fizz";
return result;
}
else if(index == result.length - 1
&& start == end - 1
&& start % 5 == 0){
result[result.length - 1] = "Buzz";
return result;
}
else if(index == result.length - 1
&& start == end - 1
&& start % 3 != 0
&& start % 5 != 0){
result[result.length - 1] = "" + start;
return result;
}
if(index < result.length - 1
&& start < end - 1
&& start % 15 == 0){
result[index] = "FizzBuzz";
}
else if(index < result.length - 1
&& start < end - 1
&& start % 3 == 0){
result[index] = "Fizz";
}
else if(index < result.length - 1
&& start < end - 1
&& start % 5 == 0){
result[index] = "Buzz";
}
else if(index < result.length - 1
&& start < end - 1
&& start % 3 != 0
&& start % 5 != 0){
result[index] = Integer.toString(start);
}
return recurFizzBuzz(result, index + 1, start + 1, end);
}


The code above passes all the tests, but I'm unable to figure out how to shorten the code. Also I had to return a String[] array because that is what coding bat wanted, to return a String[] array, I honestly would've printed instead, but coding bat doesn't except static or exceptions.

Answer

I would recommend making the recursive function private static as well as adding the terminating condition at the top and then initialize the value at the current index (by testing fizz-buzziness of the index) before returning like

private static String[] recurFizzBuzz(String[] result, int index,
        int start, int end) {
    if (index > result.length) {
        return result;
    }
    if (index % 15 == 0) {
        result[index - 1] = "FizzBuzz";
    } else if (index % 3 == 0) {
        result[index - 1] = "Fizz";
    } else if (index % 5 == 0) {
        result[index - 1] = "Buzz";
    } else {
        result[index - 1] = Integer.toString(index);
    }
    return recurFizzBuzz(result, index + 1, start, end);
}

And your initial index is start like

public static String[] fizzBuzz(int start, int end) {
    return recurFizzBuzz(new String[1 + end - start], start, start, end);
}

That allows a main like

public static void main(String[] args) {
    int start = 1;
    int end = 30;
    System.out.println(Arrays.toString(fizzBuzz(start, end)));
}

Then you can see the output is (formatted for the screen)

[1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 1
    4, FizzBuzz, 16, 17, Fizz, 19, Buzz, Fizz, 22, 23, Fizz, 
    Buzz, 26, Fizz, 28, 29, FizzBuzz]