Skip to content

Instantly share code, notes, and snippets.

@mazurkin
Last active February 11, 2025 14:47
Show Gist options
  • Save mazurkin/ad34b41a534dbcc975669116a00be366 to your computer and use it in GitHub Desktop.
Save mazurkin/ad34b41a534dbcc975669116a00be366 to your computer and use it in GitHub Desktop.
FizzBuzz made with Java exceptions
package fizzbuzz;
package com.pulsepoint.datascience.avails;
import java.io.EOFException;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.LongAdder;
import java.util.function.Function;
public class FizzBuzz {
private static final ThreadFactory DAEMON_FACTORY = r -> {
Thread thread = new Thread(r);
thread.setDaemon(true);
thread.setName("FizzBuzz");
return thread;
};
public static void main(String[] arguments) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(2, DAEMON_FACTORY);
executor.submit(FizzBuzz::process);
executor.shutdown();
if (!executor.awaitTermination(3, TimeUnit.SECONDS)) {
throw new TimeoutException("For some unknown reason the fizzbuzz algorithm has never finished");
}
}
private static void process() {
LongAdder adder = new LongAdder();
while (true) {
try {
fizzbuzz(adder);
} catch (IOException e) {
Arrays.stream(e.getSuppressed())
.map(Throwable::getMessage)
.forEach(System.out::println);
System.out.println(e.getMessage());
}
}
}
private static void fizzbuzz(LongAdder adder) throws IOException {
List<Exception> suppressed = new ArrayList<>();
for (int i = 1; true; i++) {
adder.increment();
try {
fizzbuzz(new BigInteger(adder.toString()));
Thread.sleep(0, 1);
CompletableFuture<Boolean> future = fizz(adder);
CompletableFuture.allOf(future).join();
buzz(adder);
job(adder.longValue());
} catch (InterruptedException e) {
break;
} catch (Exception e) {
suppressed.add(e);
}
}
IOException e = new FileNotFoundException("fizzbuzz");
suppressed.forEach(e::addSuppressed);
throw e;
}
private static void fizzbuzz(BigInteger trial) throws InterruptedException {
try {
fizz(trial).join();
} catch (Exception e1) {
try {
buzz(trial);
} catch (Exception e2) {
Thread.currentThread().interrupt();
}
}
}
private static CompletableFuture<Boolean> fizz(Number trial) {
if (trial.longValue() % 3 == 0) {
panic(EOFException::new, "fizz");
return CompletableFuture.completedFuture(false);
} else {
return CompletableFuture.completedFuture(true);
}
}
private static void buzz(Number trial) {
String token = trial.toString();
if (token.charAt(token.length() - 1) == '5' || token.charAt(token.length() - 1) == '0') {
throw new ArrayIndexOutOfBoundsException("buzz");
}
}
private static void job(long trial) {
if (ThreadLocalRandom.current().nextDouble() < 1.0) {
throw new IllegalArgumentException(Long.toString(trial));
}
}
private static <E extends Exception> void panic(Function<String, ? extends Exception> mapper, String msg) throws E {
throw (E) mapper.apply(msg);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment