All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fj.test.Rand Maven / Gradle / Ivy

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, F>> f;
  private final F, F>> g;

  private Rand(final F, F>> f, final F, F>> 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.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.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, F>>() {
      public F> f(final Option old) {
        return new F>() {
          public F f(final Integer from) {
            return new F() {
              public Integer f(final Integer to) {
                return f.f(some(seed)).f(from).f(to);
              }
            };
          }
        };
      }
    }, new F, F>>() {
      public F> f(final Option old) {
        return new F>() {
          public F f(final Double from) {
            return new F() {
              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, F>> f, final F, F>> g) {
    return new Rand(f, g);
  }


  private static final F fr = new F() {
    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(seed -> from -> to -> {
    final int min = min(from, to);
    final int max = max(from, to);
    final Random random = seed.map(fr).orSome(new Random());
    return (int) ((random.nextLong() & Long.MAX_VALUE) % (1L + max - min)) + min;
  }, seed -> from -> to -> {
    final double min = min(from, to);
    final double max = max(from, to);
    final Random random = seed.map(fr).orSome(new Random());
    return random.nextDouble() * (max - min) + min;
  });
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy