Monday, February 03, 2014

Because Java 8, because Lambda, and because job security.

package java8.test;

import java.util.Arrays;
import java.util.function.BinaryOperator;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;

public class Main {
 
 interface IDuo<A, B, R> {
  R apply(A n, B g);
 }

 interface ITrio<A, B, C, R> {
  R apply(A n, B p, C g);
 }

 interface IQuad<A, B, C, D, R> {
  R apply(A n, B a, C b, D g);
 }
 
 interface IFI extends IDuo<Integer, IFI, Integer> {} 
 interface IIFI extends ITrio<Integer, Integer, IIFI, Integer> {}
 interface IIIFI extends IQuad<Integer, Integer, Integer, IIIFI, Integer> {}
 
 static UnaryOperator<Integer> predecessor = n -> n - 1;
 static Predicate<Integer> isZero = n -> n == 0;
 static BinaryOperator<Integer> add = (a, b) -> a + b;
 static BinaryOperator<String> concat = (a, b) -> a + b; 
 static BinaryOperator<Integer> multiply = (a, b) -> a * b;
 
 static IFI factorial = (n, g) -> isZero.test(n) ? 1 : multiply.apply(n,g.apply(predecessor.apply(n), g));
 static IIFI tailFactorial = (n, p, g) -> isZero.test(n) ? p : g.apply(predecessor.apply(n), multiply.apply(n, p), g);
 static IIIFI fibonacci = (n, a, b, g) -> isZero.test(n) ? a : g.apply(predecessor.apply(n), b, add.apply(a,b), g);

 public static void main(String[] args) {  
  Arrays.asList(args)
    .stream()
    .map(Integer::decode)
    .map(n -> String.format(
       Arrays.asList("factorial(%d) = %d",
            "tailFactorial(%d) = %d", 
            "fibonacci(%d) = %d")
            .stream()
            .reduce("",
              (a, b) -> Arrays.asList(a,
                      (a.isEmpty() ? a : System.getProperty("line.separator")),
                      b).stream().reduce("", concat)), 
       n, factorial.apply(n, factorial), 
       n, tailFactorial.apply(n, 1, tailFactorial), 
       n, fibonacci.apply(n, 0, 1, fibonacci)))
    .forEach(System.out::println);
 }
}

Because Java 8 and because Lambda

package java8.test;

import java.util.Arrays;

public class Main {

 interface Duo {
  int apply(int n, Duo g);
 }

 interface Trio {
  int apply(int n, int prod, Trio g);
 }

 interface Quad {
  int apply(int n, int a, int b, Quad g);
 }

 static Duo factorial = (n, g) -> n > 0 ? n * g.apply(n - 1, g) : 1;
 static Trio tailFactorial = (n, p, g) -> n == 0 ? p : g.apply(n - 1, n * p, g);
 static Quad fibonacci = (n, a, b, g) -> n == 0 ? a : g.apply(n - 1, b, a + b, g);

 public static void main(String[] args) {  
  Arrays.asList(args)
    .stream()
    .map(Integer::decode)
    .map(n -> String.format(
       Arrays.asList("factorial(%d) = %d",
            "tailFactorial(%d) = %d", 
            "fibonacci(%d) = %d")
            .stream()
            .reduce("",
              (a, b) -> a
                  + (a.isEmpty() ? a : System.getProperty("line.separator"))
                  + b), 
       n, factorial.apply(n, factorial), 
       n, tailFactorial.apply(n, 1, tailFactorial), 
       n, fibonacci.apply(n, 0, 1, fibonacci)))
    .forEach(System.out::println);
 }
}