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

add getLoop
author tatsuki
date Fri, 20 Mar 2015 21:04:03 +0900
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:fe80c1edf1be
1 package fj.test;
2
3 import fj.F;
4 import fj.data.Option;
5 import static fj.data.Option.some;
6
7 import static java.lang.Math.max;
8 import static java.lang.Math.min;
9 import java.util.Random;
10
11 /**
12 * A random number generator.
13 *
14 * @version %build.number%
15 */
16 public final class Rand {
17 private final F<Option<Long>, F<Integer, F<Integer, Integer>>> f;
18 private final F<Option<Long>, F<Double, F<Double, Double>>> g;
19
20 private Rand(final F<Option<Long>, F<Integer, F<Integer, Integer>>> f, final F<Option<Long>, F<Double, F<Double, Double>>> g) {
21 this.f = f;
22 this.g = g;
23 }
24
25 /**
26 * Randomly chooses a value between the given range (inclusive).
27 *
28 * @param seed The seed to use for random generation.
29 * @param from The minimum value to choose.
30 * @param to The maximum value to choose.
31 * @return A random value in the given range.
32 */
33 public int choose(final long seed, final int from, final int to) {
34 return f.f(some(seed)).f(from).f(to);
35 }
36
37 /**
38 * Randomly chooses a value between the given range (inclusive).
39 *
40 * @param from The minimum value to choose.
41 * @param to The maximum value to choose.
42 * @return A random value in the given range.
43 */
44 public int choose(final int from, final int to) {
45 return f.f(Option.<Long>none()).f(from).f(to);
46 }
47
48 /**
49 * Randomly chooses a value between the given range (inclusive).
50 *
51 * @param seed The seed to use for random generation.
52 * @param from The minimum value to choose.
53 * @param to The maximum value to choose.
54 * @return A random value in the given range.
55 */
56 public double choose(final long seed, final double from, final double to) {
57 return g.f(some(seed)).f(from).f(to);
58 }
59
60 /**
61 * Randomly chooses a value between the given range (inclusive).
62 *
63 * @param from The minimum value to choose.
64 * @param to The maximum value to choose.
65 * @return A random value in the given range.
66 */
67 public double choose(final double from, final double to) {
68 return g.f(Option.<Long>none()).f(from).f(to);
69 }
70
71 /**
72 * Gives this random generator a new seed.
73 *
74 * @param seed The seed of the new random generator.
75 * @return A random generator with the given seed.
76 */
77 public Rand reseed(final long seed) {
78 return new Rand(new F<Option<Long>, F<Integer, F<Integer, Integer>>>() {
79 public F<Integer, F<Integer, Integer>> f(final Option<Long> old) {
80 return new F<Integer, F<Integer, Integer>>() {
81 public F<Integer, Integer> f(final Integer from) {
82 return new F<Integer, Integer>() {
83 public Integer f(final Integer to) {
84 return f.f(some(seed)).f(from).f(to);
85 }
86 };
87 }
88 };
89 }
90 }, new F<Option<Long>, F<Double, F<Double, Double>>>() {
91 public F<Double, F<Double, Double>> f(final Option<Long> old) {
92 return new F<Double, F<Double, Double>>() {
93 public F<Double, Double> f(final Double from) {
94 return new F<Double, Double>() {
95 public Double f(final Double to) {
96 return g.f(some(seed)).f(from).f(to);
97 }
98 };
99 }
100 };
101 }
102 });
103 }
104
105 /**
106 * Constructs a random generator from the given functions that supply a range to produce a
107 * result.
108 *
109 * @param f The integer random generator.
110 * @param g The floating-point random generator.
111 * @return A random generator from the given functions that supply a range to produce a result.
112 */
113 public static Rand rand(final F<Option<Long>, F<Integer, F<Integer, Integer>>> f, final F<Option<Long>, F<Double, F<Double, Double>>> g) {
114 return new Rand(f, g);
115 }
116
117
118 private static final F<Long, Random> fr = new F<Long, Random>() {
119 public Random f(final Long x) {
120 return new Random(x);
121 }
122 };
123
124 /**
125 * A standard random generator that uses {@link Random}.
126 */
127 public static final Rand standard = new Rand(new F<Option<Long>, F<Integer, F<Integer, Integer>>>() {
128 public F<Integer, F<Integer, Integer>> f(final Option<Long> seed) {
129 return new F<Integer, F<Integer, Integer>>() {
130 public F<Integer, Integer> f(final Integer from) {
131 return new F<Integer, Integer>() {
132 public Integer f(final Integer to) {
133 final int f = min(from, to);
134 final int t = max(from, to);
135 return f + seed.map(fr).orSome(new Random()).nextInt(t - f + 1);
136 }
137 };
138 }
139 };
140 }
141 }, new F<Option<Long>, F<Double, F<Double, Double>>>() {
142 public F<Double, F<Double, Double>> f(final Option<Long> seed) {
143 return new F<Double, F<Double, Double>>() {
144 public F<Double, Double> f(final Double from) {
145 return new F<Double, Double>() {
146 public Double f(final Double to) {
147 final double f = min(from, to);
148 final double t = max(from, to);
149 return seed.map(fr).orSome(new Random()).nextDouble() * (t - f) + f;
150 }
151 };
152 }
153 };
154 }
155 });
156 }