patternjavaModerate
Short Java FizzBuzz using recursion and parameters
Viewed 0 times
recursionshortjavafizzbuzzusingandparameters
Problem
public void fizzbuzz(int count, int max, String fizzer) {
fizzer += (count % 3 == 0) ? "fizz":"";
fizzer += (count % 5 == 0) ? "buzz":"";
fizzer += (count % 3 != 0 && count % 5 != 0) ? count:"";
if (count != max) {
fizzer += "\n";
fizzbuzz(count+1,max,fizzer);
} else {
System.out.println(fizzer);
}
}
fizzbuzz(1,30,"");The code is performing fizzbuzz over the range
count to max. No variables are initialized within the method.I'd love to get rid of
max, and instead take only two arguments for the method (String fizzer and int count), but how can I? I can do it backwards (i.e. working down until reaching the trivial case count == 0 and then stop), but is there a way to go from 1 to n with only one argument?Solution
Recursion is usually not a favoured strategy in Java due to concerns about stack overflow and function call efficiency. However, we can still review FizzBuzz as an exercise in recursive programming.
The first observation I have is that recursive solutions usually start by checking for the base case first. I recommend that you stick to that pattern. As a bonus, checking for
Another typical feature of recursive solutions is that they avoid mutation and reassignment. When you recurse, previous values of your variables will already be kept on the stack for you, and that is generally sufficient to solve most problems. In your case, you've used
You've used three ternary conditionals. If you reorder them, you can avoid concatenating
Since this is a pure function, it should probably be declared
Finally, note that the resulting string is already terminated by
You asked about reducing the number of parameters. The first parameter I would eliminate is not
Once you've done that, you can eliminate one more parameter by making it left-recursive instead of right-recursive.
The first observation I have is that recursive solutions usually start by checking for the base case first. I recommend that you stick to that pattern. As a bonus, checking for
count > max will prevent infinite recursion if the function is accidentally called with the count and max parameters reversed.Another typical feature of recursive solutions is that they avoid mutation and reassignment. When you recurse, previous values of your variables will already be kept on the stack for you, and that is generally sufficient to solve most problems. In your case, you've used
+=, whereas you should be able to use just +.You've used three ternary conditionals. If you reorder them, you can avoid concatenating
+= "fizz" followed by += "buzz".Since this is a pure function, it should probably be declared
static, so that you don't have to instantiate an object just to call the code.Finally, note that the resulting string is already terminated by
\n, so perhaps you should call System.out.print() rather than .println().public void fizzbuzz(int count, int max, String accumulator) {
// Check for the base case
if (count > max) {
System.out.print(accumulator);
return;
}
// ... then proceed to the recursive cases.
//
// The first case below would be better written as (count % 15 == 0),
// but I've kept it as (count % 3 == 0 && count % 5 == 0) for easier
// comparison with your original code.
String fizzer = (count % 3 == 0 && count % 5 == 0) ? "fizzbuzz\n" :
(count % 3 == 0) ? "fizz\n" :
(count % 5 == 0) ? "buzz\n" : count + "\n";
fizzbuzz(count + 1, max, accumulator + fizzer);
}You asked about reducing the number of parameters. The first parameter I would eliminate is not
count or max, but the accumulator. You could change it into a return value instead, and it would be more natural. The caller would have to be responsible for printing the result — and I would also consider that an improvement, since it keeps the calculation and the output routines separate.public static String fizzbuzz(int count, int max) {
if (count > max) {
return "";
}
String fizzer = (count % 15 == 0) ? "fizzbuzz\n" :
(count % 3 == 0) ? "fizz\n" :
(count % 5 == 0) ? "buzz\n" :
count + "\n";
return fizzer + fizzbuzz(count + 1, max);
}
public static void main(String[] args) {
System.out.print(fizzbuzz(1, 30));
}Once you've done that, you can eliminate one more parameter by making it left-recursive instead of right-recursive.
public static String fizzbuzz(int n) {
if (n <= 0) {
return "";
}
String fizzer = (n % 15 == 0) ? "fizzbuzz\n" :
(n % 3 == 0) ? "fizz\n" :
(n % 5 == 0) ? "buzz\n" :
n + "\n";
return fizzbuzz(n - 1) + fizzer;
}
public static void main(String[] args) {
System.out.print(fizzbuzz(30));
}Code Snippets
public void fizzbuzz(int count, int max, String accumulator) {
// Check for the base case
if (count > max) {
System.out.print(accumulator);
return;
}
// ... then proceed to the recursive cases.
//
// The first case below would be better written as (count % 15 == 0),
// but I've kept it as (count % 3 == 0 && count % 5 == 0) for easier
// comparison with your original code.
String fizzer = (count % 3 == 0 && count % 5 == 0) ? "fizzbuzz\n" :
(count % 3 == 0) ? "fizz\n" :
(count % 5 == 0) ? "buzz\n" : count + "\n";
fizzbuzz(count + 1, max, accumulator + fizzer);
}public static String fizzbuzz(int count, int max) {
if (count > max) {
return "";
}
String fizzer = (count % 15 == 0) ? "fizzbuzz\n" :
(count % 3 == 0) ? "fizz\n" :
(count % 5 == 0) ? "buzz\n" :
count + "\n";
return fizzer + fizzbuzz(count + 1, max);
}
public static void main(String[] args) {
System.out.print(fizzbuzz(1, 30));
}public static String fizzbuzz(int n) {
if (n <= 0) {
return "";
}
String fizzer = (n % 15 == 0) ? "fizzbuzz\n" :
(n % 3 == 0) ? "fizz\n" :
(n % 5 == 0) ? "buzz\n" :
n + "\n";
return fizzbuzz(n - 1) + fizzer;
}
public static void main(String[] args) {
System.out.print(fizzbuzz(30));
}Context
StackExchange Code Review Q#47755, answer score: 16
Revisions (0)
No revisions yet.