package kata;

import java.util.*;

/**
 * Enhancement of https://www.geeksforgeeks.org/maximum-product-subarray/
 *
 * <p>Given an array of floating point numbers, find the maximum product of
 * a continuous subarray. Forget about infinite or NaN. Assume the array has
 * at least one element.
 */
public class MaximumProductSubarray {
  static double maximumProductSubarray(double[] ar) {
    double maxSoFar = -Double.MAX_VALUE;
    Double posMaxSoFar = null;
    Double negMaxSoFar = null;

    for (double d : ar) {
      if (d > 0) {
        posMaxSoFar = multiWithNullable(posMaxSoFar, d);
        if (negMaxSoFar != null) {
          negMaxSoFar *= d;
        }
      } else if (d == 0) {
        posMaxSoFar = null;
        negMaxSoFar = null;
        maxSoFar = Math.max(maxSoFar, 0);
        continue;
      } else {
        if (negMaxSoFar != null) {
          posMaxSoFar = negMaxSoFar * d;
          negMaxSoFar = d;
        } else {
          if (posMaxSoFar == null) {
            negMaxSoFar = d;
          } else {
            negMaxSoFar = posMaxSoFar * d;
          }
          posMaxSoFar = null;
        }
      }

      if (posMaxSoFar != null) {
        maxSoFar = Math.max(maxSoFar, posMaxSoFar);
      }
      if (posMaxSoFar != null && posMaxSoFar < 1) {
        posMaxSoFar = null;
      }
      if (negMaxSoFar != null && negMaxSoFar > -1) {
        negMaxSoFar = null;
      }
    }

    // edge case, only one negative number
    if (maxSoFar == -Double.MAX_VALUE) {
      return ar[0];
    }

    return maxSoFar;
  }

  static double multiWithNullable(Double d1, double d2) {
    if (d1 == null) {
      return d2;
    }
    return d1 * d2;
  }

  public static void main(String args[]) {
    runSample(new double[]{2, 2.3, 4, 0.1, 3, 4});  // 22.08
    runSample(new double[]{2.3, 4, 0.1, 3, 4});  // 12
    runSample(new double[]{-2, 2.3, 4, 0.1, 3, 4}); // 12
    runSample(new double[]{3, 4, -3, 5, 0.1});  // 12
    runSample(new double[]{3, 4, -3, 5, 0.1, -0.9}); // 16.2
    runSample(new double[]{0, -1, 0, 0.5, 0.3}); // 0.5
    runSample(new double[]{-3, 0, -4}); // 0
    runSample(new double[]{-3, -2, -4}); // 8
    runSample(new double[]{-3}); // -3
    runSample(new double[]{3, 0.1, 0.2, 4}); // 4
    runSample(new double[]{0.5, 0.3}); // 0.5
  }

  static void runSample(double[] ar) {
    System.out.printf("%s = %s\n", Arrays.toString(ar), maximumProductSubarray(ar));
  }
}

@@ -848,32 +848,71 @@
 oFar != null) %7B%0A
+          if (posMaxSoFar == null) %7B%0A  
           posMax
@@ -938,32 +938,34 @@
  * d;%0A          
+  
 negMaxSoFar = d;
@@ -957,32 +957,198 @@
 egMaxSoFar = d;%0A
+          %7D else %7B%0A            double tmpNeg = negMaxSoFar;%0A            negMaxSoFar = Math.min(posMaxSoFar * d, d);%0A            posMaxSoFar = tmpNeg * d;%0A          %7D%0A
         %7D else %7B
@@ -1522,97 +1522,8 @@
   %7D%0A
-      if (negMaxSoFar != null && negMaxSoFar %3E -1) %7B%0A        negMaxSoFar = null;%0A      %7D%0A
     
@@ -2404,16 +2404,117 @@
  // 0.5%0A
+    runSample(new double%5B%5D%7B-0.5, -0.3%7D); // 0.15%0A    runSample(new double%5B%5D%7B-2, 10, -3, -4%7D); // 120%0A
   %7D%0A%0A  s

fix bugs