TheArchon
TheArchon

Reputation: 313

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.

Upvotes: 0

Views: 2955

Answers (6)

Abhishek Auti
Abhishek Auti

Reputation: 11

this program is applicable if array is given. public class FizzBuzz Program {

public static void main(String[] args) {
    int[] numbers={3,5,15,20,25,28};

    for(int i = 0; i< numbers.length; i++){

    if (numbers[i] % 3==0 && numbers[i] % 5 == 0){
        System.out.printf("FizzBuzz"+" ");
    }
    else if (numbers[i] %3 == 0){
        System.out.printf("Fizz"+" ");
    }
    else if (numbers[i] % 5 == 0){
        System.out.printf("Buzz"+" ");
    }
    else{
        System.out.println(numbers[i]);
    }

    }

}

}

Upvotes: 0

user7854415
user7854415

Reputation: 1

I know this question is old, but I ran into and saw it as a challenge.

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==(end-start)){
    return result;
  }
  result[index]="";
  if ((index+start)%3==0){
    result[index] += "Fizz";
  }
  if ((index+start)%5==0){
    result[index] += "Buzz";
  }
  if (result[index]==""){
    result[index]=String.valueOf(index+start);
  }
  return recurFizzBuzz(result, index+1, start, end);
}

Upvotes: 0

muradul mostafa
muradul mostafa

Reputation: 15

     public String[] fizzBuzz(int start, int end) {

    String[] a = new String[end - start];

    for (int i = start, j = 0; i <= end && j < a.length; i++, j++) {
                           //here i for given Start and end value.
                           // j for the index of new array a[].
        if (i % 15 == 0) {
            //check gigen value i is multiple of both 3 and 5.that's 15.
            a[j] = String.valueOf("FizzBuzz");

        } else if (i % 3 == 0) {

            a[j] = String.valueOf("Fizz");

        } else if (i % 5 == 0) {

            a[j] = String.valueOf("Buzz");

        } else {

            a[j] = String.valueOf(i);
        }
    }

    return a;

}

Upvotes: 0

DUUUDE123
DUUUDE123

Reputation: 166

Here is my version of the shortened code:

public void fizzBuzz(int[] array, String[] output, int start, int end, int i)
{
    if(array[i] % 3 == 0 && array[i] % 5 == 0)
    {
        output[i] = "FizzBuzz";
    }
    else if(array[i] % 3 == 0)
    {
        output[i] = "Fizz";
    }
    else if (array[i] % 5 == 0)
    {
        output[i] = "Buzz";
    }
    else
    {
        output[i] = array[i];
    }
    i++;
    if(i >= end)
    {
        // return array for numbers and output
        return output;
    }
    else fizzBuzz(array, output, end, i);
}

public void printFizzBuzz()
{
    final int TOTAL = 50;
    String[] fizzBuzz = new String[TOTAL];
    int[] nums = new int[TOTAL];

    for (int i = 0; i < TOTAL; i++)
        nums[i] = i;

    fizzBuzz = fizzBuzz(nums, "", TOTAL - 1, 0);

    for (int i = 0; i < TOTAL; i++)
        System.out.println(fizzBuzz[i]);
}

Upvotes: 1

Elliott Frisch
Elliott Frisch

Reputation: 201437

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]

Upvotes: 2

C.B.
C.B.

Reputation: 8326

Regarding changing your algorithm and data structure along with a helper method could go a long way.

public Deque<String> fizzBuzz(int start, int end) {
    Deque<String> stack = new ArrayDeque<String>();
    recurFizzBuzz(stack, start, end);
    return stack;
}

public void recurFizzBuzz(Deque<String> result, int start, int end){
    result.push(determineEntry(end));
    if(start == end) {
         return;
    }
    recurFizzBuzz(result, start, end - 1);
}

public String determineEntry(int value) {
    if (value % 15 == 0) {
        return "FizzBuzz";
    }
    if (value % 5 == 0) {
        return "Buzz";
    }
    if (value % 3 == 0) {
        return "Fizz";
    }
    return Integer.toString(value);
}

Upvotes: 1

Related Questions