Skip to content

Instantly share code, notes, and snippets.

@rakeshopensource
Last active June 25, 2019 09:01
Show Gist options
  • Save rakeshopensource/93e6ec6b02560887a6088110cc5df877 to your computer and use it in GitHub Desktop.
Save rakeshopensource/93e6ec6b02560887a6088110cc5df877 to your computer and use it in GitHub Desktop.
Factorial with Java8 Stream API
import java.math.BigInteger;
import java.util.stream.Stream;
@FunctionalInterface
interface Call<T> {
Call<T> apply();
default boolean isComplete() {
return false;
}
default T result() {
throw new Error("not implemented");
}
default T invoke() {
return Stream.iterate(this, Call::apply)
.filter(Call::isComplete)
.findFirst()
.get()
.result();
}
}
class Calls {
public static BigInteger decrement(final BigInteger number) {
return number.subtract(BigInteger.ONE);
}
public static BigInteger multiply(
final BigInteger first, final BigInteger second) {
return first.multiply(second);
}
public static BigInteger fact(BigInteger number) {
return factorial(BigInteger.ONE, number).invoke();
}
public static Call<BigInteger> factorial(final BigInteger factorial, final BigInteger number) {
if (number.equals(BigInteger.ONE))
return done(factorial);
else
return call(() -> factorial(multiply(factorial, number), decrement(number)));
}
public static <T> Call<T> call(final Call<T> nextCall) {
return nextCall;
}
public static <T> Call<T> done(final T value) {
return new Call<T>() {
@Override
public boolean isComplete() {
return true;
}
@Override
public T result() {
return value;
}
@Override
public Call<T> apply() {
throw new Error("not implemented");
}
};
}
}
public class Factorial {
public static void main(String[] args) {
System.out.println("Factorial : " + Calls.fact(new BigInteger("100")));
}
}
@rakeshopensource
Copy link
Author

Initial commit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment