package com.jfixby.lambda.examples;

import com.jfixby.cmns.api.err.Err;
import com.jfixby.cmns.api.lambda.Lambda;
import com.jfixby.cmns.api.lambda.λFunction;
import com.jfixby.cmns.api.log.L;
import com.jfixby.cmns.desktop.DesktopAssembler;

public class FibonacciExample {

	/*
	 * Fibonacci λ-function
	 */
	public static λFunction<Integer, Long> FIBONACCI = setupExpression();

	static final λFunction<Integer, Long> setupExpression() {
		return k -> {
			if (k < 0) {
				Err.reportError("k < 0");
			}
			if (k == 1) {
				return 1L;
			}
			if (k == 0) {
				return 0L;
			}
			final long result = FIBONACCI.val(k - 1) + FIBONACCI.val(k - 2);
			if (result < 0) {
				Err.reportError("Integer overflow");
			}
			return result;
		};
	}

	public static void main(String[] args) {
		DesktopAssembler.setup();

		/*
		 * λ-function with Memoization: stores the results of expensive function
		 * calls and returns the cached result when the same inputs occur again.
		 */
		FIBONACCI = Lambda.cache(FIBONACCI);

		for (int i = 0; i < 10; i++) {
			L.d("FIBONACCI(" + i + ")", FIBONACCI.val(i));
		}

	}

}

@@ -30,16 +30,46 @@
 mples;%0A%0A
+import java.math.BigInteger;%0A%0A
 import c
@@ -351,32 +351,35 @@
 tatic %CE%BBFunction%3C
+Big
 Integer, Long%3E F
@@ -371,20 +371,26 @@
 nteger, 
-Long
+BigInteger
 %3E FIBONA
@@ -439,16 +439,19 @@
 unction%3C
+Big
 Integer,
@@ -455,12 +455,18 @@
 er, 
-Long
+BigInteger
 %3E se
@@ -502,21 +502,72 @@
 -%3E %7B%0A%09%09%09
-if (k
+L.d(%22computing%22, k);%0A%09%09%09if (k.compareTo(BigInteger.ZERO)
  %3C 0) %7B%0A
@@ -613,13 +613,39 @@
 f (k
+.compareTo(BigInteger.ONE)
  == 
-1
+0
 ) %7B%0A
@@ -659,10 +659,22 @@
 urn 
-1L
+BigInteger.ONE
 ;%0A%09%09
@@ -688,50 +688,191 @@
 f (k
- == 0) %7B%0A%09%09%09%09return 0L;%0A%09%09%09%7D%0A%09%09%09final long
+.compareTo(BigInteger.ZERO) == 0) %7B%0A%09%09%09%09return BigInteger.ZERO;%0A%09%09%09%7D%0A%09%09%09BigInteger m1 = k.subtract(BigInteger.ONE);%0A%09%09%09BigInteger m2 = m1.subtract(BigInteger.ONE);%0A%09%09%09final BigInteger
  res
@@ -895,17 +895,16 @@
 val(
-k - 1) + 
+m1).add(
 FIBO
@@ -917,13 +917,11 @@
 val(
-k - 2
+m2)
 );%0A%09
@@ -932,16 +932,43 @@
  (result
+.compareTo(BigInteger.ZERO)
  %3C 0) %7B%0A
@@ -1013,16 +1013,45 @@
 );%0A%09%09%09%7D%0A
+%09%09%09// L.d(%22result%22, result);%0A
 %09%09%09retur
@@ -1140,16 +1140,175 @@
 tup();%0A%0A
+%09%09BigInteger input_value = new BigInteger(%2210%22);%0A%0A%09%09// No memoization: O(n%5E2) operations%0A%09%09L.d(%22FIBONACCI(%22 + input_value + %22)%22, FIBONACCI.val(input_value));%0A%0A
 %09%09/*%0A%09%09 
@@ -1454,16 +1454,37 @@
  again.%0A
+%09%09 * O(n) operations%0A
 %09%09 */%0A%09%09
@@ -1524,43 +1524,8 @@
 I);%0A
-%0A%09%09for (int i = 0; i %3C 10; i++) %7B%0A%09
 %09%09L.
@@ -1542,16 +1542,26 @@
 CI(%22 + i
+nput_value
  + %22)%22, 
@@ -1579,15 +1579,21 @@
 al(i
-));%0A%09%09%7D
+nput_value));
 %0A%0A%09%7D

switch to BigInteger