The FizzBuzz: a branchless version with Java

Let dissect a Java program that implements the FizzBuzz problem with a branchless style, using a mix of bitwise operations, lambdas, and an optimized loop. Let's break it down step by step: Overview of FizzBuzz Rules Print numbers from 1 to 100. If a number is divisible by 3, print "Fizz". If a number is divisible by 5, print "Buzz". If a number is divisible by both 3 and 5, print "FizzBuzz". Otherwise, print the number itself. Code Breakdown 1. Defining an Interface for Lambda Expressions interface Provider { String value(int i); } An interface Provider is needed since generic array are not possible, so Function or other functional interface are non allowed. It has a single method value(int i), which will be implemented using lambda expressions. 2. Creating an Array of Provider Lambdas Provider [] provider = {i->String.valueOf(i),i->"",i->""}; This array holds three lambda expressions: i -> String.valueOf(i): Returns the number as a string. i -> "": Returns an empty string. i -> "": Another empty string (used later for Fizz/Buzz handling). 3. Defining Text Segments String [] textSegment = {"", "Fizz","FizzBuzz","Buzz"}; This array maps to different text outputs: textSegment[0] = "" (for numbers that aren't Fizz or Buzz) textSegment[1] = "Fizz" (for numbers divisible by 3) textSegment[2] = "FizzBuzz" (for numbers divisible by both 3 and 5) textSegment[3] = "Buzz" (for numbers divisible by 5) 4. Using StringBuilder for Efficient String Concatenation StringBuilder sb = new StringBuilder(3000); String newline = System.lineSeparator(); StringBuffer is used for efficient string concatenation. newline stores the platform-specific line separator. 5. Main Loop with Bitwise Operations for (int i = 1, a = 0, b = 0, providerIndex = 0, segmentIndex = 0; i > i % 15 - 1) & 1) ((i % 15) 2) { sb.append(textSegment[segmentIndex]) .append(provider[providerIndex].value(i)) .append(newline); } This loop iterates from i = 1 to 100 and performs the following calculations: (1) Calculating a - 5 Multiples a = ((528 >> i % 15 - 1) & 1)

Mar 22, 2025 - 20:52
 0
The FizzBuzz: a branchless version with Java

Let dissect a Java program that implements the FizzBuzz problem with a branchless style, using a mix of bitwise operations, lambdas, and an optimized loop. Let's break it down step by step:

Overview of FizzBuzz Rules

  • Print numbers from 1 to 100.
  • If a number is divisible by 3, print "Fizz".
  • If a number is divisible by 5, print "Buzz".
  • If a number is divisible by both 3 and 5, print "FizzBuzz".
  • Otherwise, print the number itself.

Code Breakdown

1. Defining an Interface for Lambda Expressions

interface Provider {
    String value(int i);
}
  • An interface Provider is needed since generic array are not possible, so Function or other functional interface are non allowed.
  • It has a single method value(int i), which will be implemented using lambda expressions.

2. Creating an Array of Provider Lambdas

Provider [] provider = {i->String.valueOf(i),i->"",i->""};
  • This array holds three lambda expressions:
    • i -> String.valueOf(i): Returns the number as a string.
    • i -> "": Returns an empty string.
    • i -> "": Another empty string (used later for Fizz/Buzz handling).

3. Defining Text Segments

String [] textSegment = {"", "Fizz","FizzBuzz","Buzz"};
  • This array maps to different text outputs:
    • textSegment[0] = "" (for numbers that aren't Fizz or Buzz)
    • textSegment[1] = "Fizz" (for numbers divisible by 3)
    • textSegment[2] = "FizzBuzz" (for numbers divisible by both 3 and 5)
    • textSegment[3] = "Buzz" (for numbers divisible by 5)

4. Using StringBuilder for Efficient String Concatenation

StringBuilder sb = new StringBuilder(3000);
String newline = System.lineSeparator();

  • StringBuffer is used for efficient string concatenation.
  • newline stores the platform-specific line separator.

5. Main Loop with Bitwise Operations

for (int i = 1, a = 0, b = 0, providerIndex = 0, segmentIndex = 0; 
     i <= 100; 
     i++,
     a = ((528 >> i % 15 - 1) & 1) << 2,
     b = ((-2128340926 >> ((i % 15) << 1)) & 3) << 2,
     providerIndex = (b - a) >> 2,
     segmentIndex = (a + b) >> 2)
{
    sb.append(textSegment[segmentIndex])
      .append(provider[providerIndex].value(i))
      .append(newline);
}

This loop iterates from i = 1 to 100 and performs the following calculations:

(1) Calculating a - 5 Multiples
a = ((528 >> i % 15 - 1) & 1) << 2
  • 528 (binary: 100001000010000) is a bitmask that identifies numbers divisible by 5.
  • (i % 15 - 1) is used to shift the bitmask.
  • & 1 extracts whether the bit is set.
  • << 2 makes sure that if it's Fizz, a is 4, otherwise a is 0.
(2) Calculating b - 3 and 15 Multiples
b = ((-2128340926 >> ((i % 15) << 1)) & 3) << 2
  • -2128340926 (binary: 100000010000001000000100000010) is a bitmask that identifies numbers divisible by 3 or 15.
  • ((i % 15) << 1) is used to shift the bitmask.
  • & 3 ensures only relevant bits are taken.
  • << 2 scales b properly.
(3) Determining providerIndex
providerIndex = (b - a) >> 2
  • providerIndex determines whether to print the number (provider[0]) or an empty string (provider[1] or provider[2]) since provides the values: 0,1,2.
(4) Determining segmentIndex
segmentIndex = (a + b) >> 2
  • segmentIndex selects the correct FizzBuzz text from textSegment since provides the values: 0,1,2,3.

6. Appending the Result

sb.append(textSegment[segmentIndex])
  .append(provider[providerIndex].value(i))
  .append(newline);
  • The correct Fizz/Buzz text (textSegment[segmentIndex]) is added.
  • The number (or an empty string) is determined by provider[providerIndex].
  • A newline is appended.

7. Printing the Final Output

System.out.println(sb);
  • The entire FizzBuzz output is printed at once.

Key Takeaways

  • Uses bitwise operations for efficient FizzBuzz checking.
  • Avoids multiple if-else conditions.
  • Optimizes string concatenation with StringBuilder.
  • Lambda functions simplify number/string selection.

There are more solutions about FizzBuzz, and maybe the code can be optimized further, but this code is funny and didactic enough to implement FizzBuzz in Java!