Advertisement
Guest User

Intermission, the Sequel - Java Solution

a guest
Aug 10th, 2014
241
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.18 KB | None | 0 0
  1. import java.io.IOException;
  2. import java.math.BigDecimal;
  3. import java.util.HashMap;
  4. import java.util.Map;
  5.  
  6. import com.google.auto.value.AutoValue;
  7. import com.google.common.base.Preconditions;
  8. import com.google.common.collect.Maps;
  9.  
  10. public class Brilliant {
  11.  
  12.     @AutoValue
  13.     abstract static class PArgs {
  14.         public static PArgs make(int N, int k, int q) {
  15.             return new AutoValue_Brilliant_PArgs(N, k, q);
  16.         }
  17.         public abstract int N();
  18.         public abstract int k();
  19.         public abstract int q();
  20.     }
  21.  
  22.     private static final Map<PArgs, BigDecimal> PCACHE = new HashMap<>();
  23.     private static final BigDecimal TAILS = new BigDecimal("0.01");
  24.     private static final BigDecimal HEADS = BigDecimal.ONE.subtract(TAILS);
  25.  
  26.     // P of at least k consecutive heads, and at most q tails in exactly N flips
  27.     private static BigDecimal P(int N, int k, int q) {
  28.         Preconditions.checkArgument(N >= 0);
  29.         Preconditions.checkArgument(k >= 0);
  30.         Preconditions.checkArgument(q >= 0);
  31.         PArgs args = PArgs.make(N, k, q);
  32.         if (PCACHE.containsKey(args)) return PCACHE.get(args);
  33.  
  34.         BigDecimal ret;
  35.         if (N == 0) {
  36.             ret = (k == 0) ? BigDecimal.ONE : BigDecimal.ZERO;
  37.         } else if (N == k) {
  38.             ret = HEADS.pow(N);
  39.         } else if (q == 0) {
  40.             ret = (N < k) ? BigDecimal.ZERO : HEADS.pow(N);
  41.         } else if (k == 0) {
  42.             ret = HEADS.multiply(P(N-1, 0, q)).add(TAILS.multiply(P(N-1, 0, q-1)));
  43.         } else if (N < k) {
  44.             ret = BigDecimal.ZERO;
  45.         } else {
  46.             ret = TAILS.multiply(P(N-1, k, q-1)).add(HEADS.multiply(P(N-1, k, q)));
  47.  
  48.             // Opposite case:  Got max k-1 or less consecutive heads in N-k-1 coins, with at most q-1 tails
  49.             // Then, got tails, and then k heads consecutively
  50.             BigDecimal pOther = P(N-k-1, 0, q-1).subtract(P(N-k-1, k, q-1));
  51.             Preconditions.checkArgument(pOther.compareTo(BigDecimal.ZERO) >= 0);
  52.             ret = ret.add(pOther.multiply(TAILS).multiply(HEADS.pow(k)));
  53.         }
  54.  
  55.         PCACHE.put(args, ret);
  56.         return ret;
  57.     }
  58.  
  59.     private static BigDecimal exact(int N, int k, int q) {
  60.         BigDecimal exactK1 = P(N, k, q).subtract(P(N, k+1, q));
  61.         if (q > 0) {
  62.             BigDecimal exactK2 = P(N, k, q-1).subtract(P(N, k+1, q-1));
  63.             return exactK1.subtract(exactK2);
  64.         } else {
  65.             return exactK1;
  66.         }
  67.     }
  68.  
  69.     @AutoValue
  70.     abstract static class MArgs {
  71.         public static MArgs make(int rows, int atMost) {
  72.             return new AutoValue_Brilliant_MArgs(rows, atMost);
  73.         }
  74.         public abstract int rows();
  75.         public abstract int atMost();
  76.     }
  77.  
  78.     private static BigDecimal atMost(BigDecimal[] numInconv, Map<MArgs, BigDecimal> cache, int rows, int atMost) {
  79.         MArgs args = MArgs.make(rows, atMost);
  80.         if (cache.containsKey(args)) return cache.get(args);
  81.  
  82.         int C = numInconv.length - 1;
  83.         BigDecimal ret;
  84.         if (rows == 0) {
  85.             ret = BigDecimal.ONE;
  86.         } else {
  87.             ret = BigDecimal.ZERO;
  88.             for (int x = 0; x <= Math.min(C, atMost); x++) {
  89.                 ret = ret.add(numInconv[x].multiply(atMost(numInconv, cache, rows-1, atMost-x)));
  90.             }
  91.         }
  92.  
  93.         cache.put(args, ret);
  94.         return ret;
  95.     }
  96.  
  97.     // private static final int N = 1_000_000;
  98.     public static void main(String[] args) throws NumberFormatException, IOException {
  99.         int c = 1;
  100.         while (true) {
  101.             BigDecimal[] pInconv = new BigDecimal[c+1];
  102.             for (int i = 0; i < c+1; i++) pInconv[i] = BigDecimal.ZERO;
  103.  
  104.             for (int k = 0; k <= c; k++) for (int q = 0; q <= c - k; q++) {
  105.                 BigDecimal p = exact(c, k, q);
  106.  
  107.                 int numInconv = c - k - q;
  108.                 pInconv[numInconv] = pInconv[numInconv].add(p);
  109.             }
  110.             System.out.println(c + ": " + (1 - atMost(pInconv, Maps.newHashMap(), 25, (25*c)/10).doubleValue()));
  111.  
  112.             try { Thread.sleep(400); } catch (InterruptedException ignore) {}
  113.             c++;
  114.         }
  115.     }
  116.  
  117. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement