diff src/main/java/fj/test/Rand.java @ 0:fe80c1edf1be

add getLoop
author tatsuki
date Fri, 20 Mar 2015 21:04:03 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/fj/test/Rand.java	Fri Mar 20 21:04:03 2015 +0900
@@ -0,0 +1,156 @@
+package fj.test;
+
+import fj.F;
+import fj.data.Option;
+import static fj.data.Option.some;
+
+import static java.lang.Math.max;
+import static java.lang.Math.min;
+import java.util.Random;
+
+/**
+ * A random number generator.
+ *
+ * @version %build.number%
+ */
+public final class Rand {
+  private final F<Option<Long>, F<Integer, F<Integer, Integer>>> f;
+  private final F<Option<Long>, F<Double, F<Double, Double>>> g;
+
+  private Rand(final F<Option<Long>, F<Integer, F<Integer, Integer>>> f, final F<Option<Long>, F<Double, F<Double, Double>>> g) {
+    this.f = f;
+    this.g = g;
+  }
+
+  /**
+   * Randomly chooses a value between the given range (inclusive).
+   *
+   * @param seed The seed to use for random generation.
+   * @param from The minimum value to choose.
+   * @param to   The maximum value to choose.
+   * @return A random value in the given range.
+   */
+  public int choose(final long seed, final int from, final int to) {
+    return f.f(some(seed)).f(from).f(to);
+  }
+
+  /**
+   * Randomly chooses a value between the given range (inclusive).
+   *
+   * @param from The minimum value to choose.
+   * @param to   The maximum value to choose.
+   * @return A random value in the given range.
+   */
+  public int choose(final int from, final int to) {
+    return f.f(Option.<Long>none()).f(from).f(to);
+  }
+
+  /**
+   * Randomly chooses a value between the given range (inclusive).
+   *
+   * @param seed The seed to use for random generation.
+   * @param from The minimum value to choose.
+   * @param to   The maximum value to choose.
+   * @return A random value in the given range.
+   */
+  public double choose(final long seed, final double from, final double to) {
+    return g.f(some(seed)).f(from).f(to);
+  }
+
+  /**
+   * Randomly chooses a value between the given range (inclusive).
+   *
+   * @param from The minimum value to choose.
+   * @param to   The maximum value to choose.
+   * @return A random value in the given range.
+   */
+  public double choose(final double from, final double to) {
+    return g.f(Option.<Long>none()).f(from).f(to);
+  }
+
+  /**
+   * Gives this random generator a new seed.
+   *
+   * @param seed The seed of the new random generator.
+   * @return A random generator with the given seed.
+   */
+  public Rand reseed(final long seed) {
+    return new Rand(new F<Option<Long>, F<Integer, F<Integer, Integer>>>() {
+      public F<Integer, F<Integer, Integer>> f(final Option<Long> old) {
+        return new F<Integer, F<Integer, Integer>>() {
+          public F<Integer, Integer> f(final Integer from) {
+            return new F<Integer, Integer>() {
+              public Integer f(final Integer to) {
+                return f.f(some(seed)).f(from).f(to);
+              }
+            };
+          }
+        };
+      }
+    }, new F<Option<Long>, F<Double, F<Double, Double>>>() {
+      public F<Double, F<Double, Double>> f(final Option<Long> old) {
+        return new F<Double, F<Double, Double>>() {
+          public F<Double, Double> f(final Double from) {
+            return new F<Double, Double>() {
+              public Double f(final Double to) {
+                return g.f(some(seed)).f(from).f(to);
+              }
+            };
+          }
+        };
+      }
+    });
+  }
+
+  /**
+   * Constructs a random generator from the given functions that supply a range to produce a
+   * result.
+   *
+   * @param f The integer random generator.
+   * @param g The floating-point random generator.
+   * @return A random generator from the given functions that supply a range to produce a result.
+   */
+  public static Rand rand(final F<Option<Long>, F<Integer, F<Integer, Integer>>> f, final F<Option<Long>, F<Double, F<Double, Double>>> g) {
+    return new Rand(f, g);
+  }
+
+
+  private static final F<Long, Random> fr = new F<Long, Random>() {
+    public Random f(final Long x) {
+      return new Random(x);
+    }
+  };
+
+  /**
+   * A standard random generator that uses {@link Random}.
+   */
+  public static final Rand standard = new Rand(new F<Option<Long>, F<Integer, F<Integer, Integer>>>() {
+    public F<Integer, F<Integer, Integer>> f(final Option<Long> seed) {
+      return new F<Integer, F<Integer, Integer>>() {
+        public F<Integer, Integer> f(final Integer from) {
+          return new F<Integer, Integer>() {
+            public Integer f(final Integer to) {
+              final int f = min(from, to);
+              final int t = max(from, to);
+              return f + seed.map(fr).orSome(new Random()).nextInt(t - f + 1);
+            }
+          };
+        }
+      };
+    }
+  }, new F<Option<Long>, F<Double, F<Double, Double>>>() {
+    public F<Double, F<Double, Double>> f(final Option<Long> seed) {
+      return new F<Double, F<Double, Double>>() {
+        public F<Double, Double> f(final Double from) {
+          return new F<Double, Double>() {
+            public Double f(final Double to) {
+              final double f = min(from, to);
+              final double t = max(from, to);
+              return seed.map(fr).orSome(new Random()).nextDouble() * (t - f) + f;
+            }
+          };
+        }
+      };
+    }
+  });
+}