Class ReverseWrapper

All Implemented Interfaces:
Externalizable, Serializable, RandomGenerator

public class ReverseWrapper extends EnhancedRandom
A wrapper around a different EnhancedRandom object that runs it in reverse, calling EnhancedRandom.previousLong() instead anywhere nextLong() would be called. This can be useful to reverse a sequence of calls made to the wrapped generator earlier; the reversed calls have to happen in reverse order to undo an operation such as a shuffle, typically. Calling previousLong() is typically not as fast as nextLong(), but usually not by any large degree.
See Also:
  • Field Details

  • Constructor Details

    • ReverseWrapper

      public ReverseWrapper()
      Creates a ReverseWrapper that wraps a DistinctRandom with a random seed.
    • ReverseWrapper

      public ReverseWrapper(long seed)
      Creates a ReverseWrapper that wraps a DistinctRandom created with DistinctRandom(long).
      Parameters:
      seed - the seed that will be used for the wrapped DistinctRandom
    • ReverseWrapper

      public ReverseWrapper(EnhancedRandom toWrap)
      This does not copy toWrap, and uses a reference as-is, so this can be useful to reverse some series of calls made earlier to toWrap in a forward direction.
      Parameters:
      toWrap - a non-null EnhancedRandom, preferably not also a wrapper
    • ReverseWrapper

      public ReverseWrapper(ReverseWrapper other)
      The copy constructor.
      Parameters:
      other - a non-null ReverseWrapper; its wrapped EnhancedRandom must also be non-null.
  • Method Details

    • getWrapped

      public EnhancedRandom getWrapped()
    • setWrapped

      public void setWrapped(EnhancedRandom wrapped)
    • getStateCount

      public int getStateCount()
      Gets the number of possible state variables that can be selected with getSelectedState(int) or setSelectedState(int, long). This defaults to returning 0, making no state variable available for reading or writing. An implementation that has only one long state, like DistinctRandom generator, should return 1. A generator that permits setting two different long values, like LaserRandom, should return 2. Much larger values are possible for types like the Mersenne Twister or some CMWC generators.
      Overrides:
      getStateCount in class EnhancedRandom
      Returns:
      the non-negative number of selections possible for state variables
    • getTag

      public String getTag()
      Gets the tag used to identify this type of EnhancedRandom, as a String. This tag should be unique, and for uniformity purposes, all tags used in this library are 4 characters long. User-defined tags should have a different length.
      Specified by:
      getTag in class EnhancedRandom
      Returns:
      a unique String identifier for this type of EnhancedRandom; usually 4 chars long.
    • setSeed

      public void setSeed(long seed)
      Sets the seed of this random number generator using a single long seed. This should behave exactly the same as if a new object of this type was created with the constructor that takes a single long value. This does not necessarily assign the state variable(s) of the implementation with the exact contents of seed, so getSelectedState(int) should not be expected to return seed after this, though it may. If this implementation has more than one long of state, then the expectation is that none of those state variables will be exactly equal to seed (almost all the time).
      Specified by:
      setSeed in class EnhancedRandom
      Parameters:
      seed - the initial seed
    • getSelectedState

      public long getSelectedState(int selection)
      Gets a selected state value from this EnhancedRandom. The number of possible selections is up to the implementing class, and is accessible via getStateCount(), but negative values for selection are typically not tolerated. This should return the exact value of the selected state, assuming it is implemented. The default implementation throws an UnsupportedOperationException, and implementors only have to allow reading the state if they choose to implement this differently. If this method is intended to be used, getStateCount() must also be implemented.
      Overrides:
      getSelectedState in class EnhancedRandom
      Parameters:
      selection - used to select which state variable to get; generally non-negative
      Returns:
      the exact value of the selected state
    • setSelectedState

      public void setSelectedState(int selection, long value)
      Sets a selected state value to the given long value. The number of possible selections is up to the implementing class, but negative values for selection are typically not tolerated. Implementors are permitted to change value if it is not valid, but they should not alter it if it is valid. The public implementation calls setSeed(long) with value, which doesn't need changing if the generator has one state that is set verbatim by setSeed(). Otherwise, this method should be implemented when getSelectedState(int) is and the state is allowed to be set by users. Having accurate ways to get and set the full state of a random number generator makes it much easier to serialize and deserialize that class.
      Overrides:
      setSelectedState in class EnhancedRandom
      Parameters:
      selection - used to select which state variable to set; generally non-negative
      value - the exact value to use for the selected state, if valid
    • setState

      public void setState(long state)
      Sets each state variable to the given state. If getStateCount() is 1, then this should set the whole state to the given value using setSelectedState(int, long). If getStateCount() is more than 1, then all states will be set in the same way (using setSelectedState(), all to state).
      Overrides:
      setState in class EnhancedRandom
      Parameters:
      state - the long value to use for each state variable
    • setState

      public void setState(long stateA, long stateB)
      Sets each state variable to either stateA or stateB, alternating. This uses setSelectedState(int, long) to set the values. If there is one state variable (getStateCount() is 1), then this only sets that state variable to stateA. If there are two state variables, the first is set to stateA, and the second to stateB. If there are more, it reuses stateA, then stateB, then stateA, and so on until all variables are set.
      Overrides:
      setState in class EnhancedRandom
      Parameters:
      stateA - the long value to use for states at index 0, 2, 4, 6...
      stateB - the long value to use for states at index 1, 3, 5, 7...
    • setState

      public void setState(long stateA, long stateB, long stateC)
      Sets each state variable to stateA, stateB, or stateC, alternating. This uses setSelectedState(int, long) to set the values. If there is one state variable (getStateCount() is 1), then this only sets that state variable to stateA. If there are two state variables, the first is set to stateA, and the second to stateB. With three state variables, the first is set to stateA, the second to stateB, and the third to stateC. If there are more, it reuses stateA, then stateB, then stateC, then stateA, and so on until all variables are set.
      Overrides:
      setState in class EnhancedRandom
      Parameters:
      stateA - the long value to use for states at index 0, 3, 6, 9...
      stateB - the long value to use for states at index 1, 4, 7, 10...
      stateC - the long value to use for states at index 2, 5, 8, 11...
    • setState

      public void setState(long stateA, long stateB, long stateC, long stateD)
      Sets each state variable to stateA, stateB, stateC, or stateD, alternating. This uses setSelectedState(int, long) to set the values. If there is one state variable (getStateCount() is 1), then this only sets that state variable to stateA. If there are two state variables, the first is set to stateA, and the second to stateB. With three state variables, the first is set to stateA, the second to stateB, and the third to stateC. With four state variables, the first is set to stateA, the second to stateB, the third to stateC, and the fourth to stateD. If there are more, it reuses stateA, then stateB, then stateC, then stateD, then stateA, and so on until all variables are set.
      Overrides:
      setState in class EnhancedRandom
      Parameters:
      stateA - the long value to use for states at index 0, 4, 8, 12...
      stateB - the long value to use for states at index 1, 5, 9, 13...
      stateC - the long value to use for states at index 2, 6, 10, 14...
      stateD - the long value to use for states at index 3, 7, 11, 15...
    • setState

      public void setState(long stateA, long stateB, long stateC, long stateD, long stateE)
      Sets each state variable to stateA, stateB, stateC, or stateD, alternating. This uses setSelectedState(int, long) to set the values. If there is one state variable (getStateCount() is 1), then this only sets that state variable to stateA. If there are two state variables, the first is set to stateA, and the second to stateB. With three state variables, the first is set to stateA, the second to stateB, and the third to stateC. With four state variables, the first is set to stateA, the second to stateB, the third to stateC, and the fourth to stateD. If there are more, it reuses stateA, then stateB, then stateC, then stateD, then stateA, and so on until all variables are set.
      Overrides:
      setState in class EnhancedRandom
      Parameters:
      stateA - the long value to use for states at index 0, 5, 10, 15...
      stateB - the long value to use for states at index 1, 6, 11, 16...
      stateC - the long value to use for states at index 2, 7, 12, 17...
      stateD - the long value to use for states at index 3, 8, 13, 18...
      stateE - the long value to use for states at index 4, 9, 14, 19...
    • setState

      public void setState(long... states)
      Sets all state variables to alternating values chosen from states. If states is empty, then this does nothing, and leaves the current generator unchanged. This works for generators with any getStateCount(), but may allocate an array if states is used as a varargs (you can pass an existing array without needing to allocate). This uses setSelectedState(int, long) to change the states.
      Overrides:
      setState in class EnhancedRandom
      Parameters:
      states - an array or varargs of long values to use as states
    • nextLong

      public long nextLong()
      Returns the previous pseudorandom, uniformly distributed long value from the wrapped random number generator's sequence. The general contract of nextLong is that one long value is pseudorandomly generated and returned.
      Specified by:
      nextLong in interface RandomGenerator
      Specified by:
      nextLong in class EnhancedRandom
      Returns:
      the previous pseudorandom, uniformly distributed long value from the wrapped random number generator's sequence
    • nextInt

      public int nextInt()
      Returns the previous pseudorandom, uniformly distributed int value from the wrapped random number generator's sequence. The general contract of nextInt is that one int value is pseudorandomly generated and returned. All 232 possible int values are produced with (approximately) equal probability.
      Specified by:
      nextInt in interface RandomGenerator
      Overrides:
      nextInt in class EnhancedRandom
      Returns:
      the previous pseudorandom, uniformly distributed int value from the wrapped random number generator's sequence
    • previousLong

      public long previousLong()
      Delegates to the EnhancedRandom.nextLong() method of the wrapped generator; this is the counterpart to how nextLong() here delegates to the EnhancedRandom.previousLong() method of the wrapped generator.
      Overrides:
      previousLong in class EnhancedRandom
      Returns:
      the number that wrapped.nextLong() would produce
    • previousInt

      public int previousInt()
      Delegates to the EnhancedRandom.nextInt() method of the wrapped generator; this is the counterpart to how nextInt() here delegates to the EnhancedRandom.previousInt() ()} method of the wrapped generator.
      Overrides:
      previousInt in class EnhancedRandom
      Returns:
      the number that wrapped.nextLong() would produce
    • skip

      public long skip(long advance)
      Delegates to the EnhancedRandom.skip(long) method if the wrapped generator, but passes it -advance instead of advance without changes. This makes it skip in the reverse direction.
      Overrides:
      skip in class EnhancedRandom
      Parameters:
      advance - Number of future generations to skip over; can be negative to backtrack, 0 gets the most-recently-generated number
      Returns:
      the random long generated after skipping forward or backwards by advance numbers
    • shuffle

      public void shuffle(long[] items, int offset, int length)
      Shuffles a section of the given array in-place pseudo-randomly, using this to determine how to shuffle. Similarly to how nextLong() uses the wrapped generator's EnhancedRandom.previousLong(), this shuffles in reverse order. This allows you to shuffle an array using one of the wrapped generator's shuffle() methods, then later undo that shuffle by using a ReverseWrapper's shuffle method.
      Overrides:
      shuffle in class EnhancedRandom
      Parameters:
      items - an array of some reference type; must be non-null but may contain null items
      offset - the index of the first element of the array that can be shuffled
      length - the length of the section to shuffle
    • shuffle

      public void shuffle(byte[] items, int offset, int length)
      Shuffles a section of the given array in-place pseudo-randomly, using this to determine how to shuffle. Similarly to how nextLong() uses the wrapped generator's EnhancedRandom.previousLong(), this shuffles in reverse order. This allows you to shuffle an array using one of the wrapped generator's shuffle() methods, then later undo that shuffle by using a ReverseWrapper's shuffle method.
      Overrides:
      shuffle in class EnhancedRandom
      Parameters:
      items - an array of some reference type; must be non-null but may contain null items
      offset - the index of the first element of the array that can be shuffled
      length - the length of the section to shuffle
    • shuffle

      public void shuffle(int[] items, int offset, int length)
      Shuffles a section of the given array in-place pseudo-randomly, using this to determine how to shuffle. Similarly to how nextLong() uses the wrapped generator's EnhancedRandom.previousLong(), this shuffles in reverse order. This allows you to shuffle an array using one of the wrapped generator's shuffle() methods, then later undo that shuffle by using a ReverseWrapper's shuffle method.
      Overrides:
      shuffle in class EnhancedRandom
      Parameters:
      items - an array of some reference type; must be non-null but may contain null items
      offset - the index of the first element of the array that can be shuffled
      length - the length of the section to shuffle
    • shuffle

      public void shuffle(short[] items, int offset, int length)
      Shuffles a section of the given array in-place pseudo-randomly, using this to determine how to shuffle. Similarly to how nextLong() uses the wrapped generator's EnhancedRandom.previousLong(), this shuffles in reverse order. This allows you to shuffle an array using one of the wrapped generator's shuffle() methods, then later undo that shuffle by using a ReverseWrapper's shuffle method.
      Overrides:
      shuffle in class EnhancedRandom
      Parameters:
      items - an array of some reference type; must be non-null but may contain null items
      offset - the index of the first element of the array that can be shuffled
      length - the length of the section to shuffle
    • shuffle

      public void shuffle(float[] items, int offset, int length)
      Shuffles a section of the given array in-place pseudo-randomly, using this to determine how to shuffle. Similarly to how nextLong() uses the wrapped generator's EnhancedRandom.previousLong(), this shuffles in reverse order. This allows you to shuffle an array using one of the wrapped generator's shuffle() methods, then later undo that shuffle by using a ReverseWrapper's shuffle method.
      Overrides:
      shuffle in class EnhancedRandom
      Parameters:
      items - an array of some reference type; must be non-null but may contain null items
      offset - the index of the first element of the array that can be shuffled
      length - the length of the section to shuffle
    • shuffle

      public void shuffle(double[] items, int offset, int length)
      Shuffles a section of the given array in-place pseudo-randomly, using this to determine how to shuffle. Similarly to how nextLong() uses the wrapped generator's EnhancedRandom.previousLong(), this shuffles in reverse order. This allows you to shuffle an array using one of the wrapped generator's shuffle() methods, then later undo that shuffle by using a ReverseWrapper's shuffle method.
      Overrides:
      shuffle in class EnhancedRandom
      Parameters:
      items - an array of some reference type; must be non-null but may contain null items
      offset - the index of the first element of the array that can be shuffled
      length - the length of the section to shuffle
    • shuffle

      public void shuffle(boolean[] items, int offset, int length)
      Shuffles a section of the given array in-place pseudo-randomly, using this to determine how to shuffle. Similarly to how nextLong() uses the wrapped generator's EnhancedRandom.previousLong(), this shuffles in reverse order. This allows you to shuffle an array using one of the wrapped generator's shuffle() methods, then later undo that shuffle by using a ReverseWrapper's shuffle method.
      Overrides:
      shuffle in class EnhancedRandom
      Parameters:
      items - an array of some reference type; must be non-null but may contain null items
      offset - the index of the first element of the array that can be shuffled
      length - the length of the section to shuffle
    • shuffle

      public void shuffle(char[] items, int offset, int length)
      Shuffles a section of the given array in-place pseudo-randomly, using this to determine how to shuffle. Similarly to how nextLong() uses the wrapped generator's EnhancedRandom.previousLong(), this shuffles in reverse order. This allows you to shuffle an array using one of the wrapped generator's shuffle() methods, then later undo that shuffle by using a ReverseWrapper's shuffle method.
      Overrides:
      shuffle in class EnhancedRandom
      Parameters:
      items - an array of some reference type; must be non-null but may contain null items
      offset - the index of the first element of the array that can be shuffled
      length - the length of the section to shuffle
    • shuffle

      public <T> void shuffle(T[] items, int offset, int length)
      Shuffles a section of the given array in-place pseudo-randomly, using this to determine how to shuffle. Similarly to how nextLong() uses the wrapped generator's EnhancedRandom.previousLong(), this shuffles in reverse order. This allows you to shuffle an array using one of the wrapped generator's shuffle() methods, then later undo that shuffle by using a ReverseWrapper's shuffle method.
      Overrides:
      shuffle in class EnhancedRandom
      Parameters:
      items - an array of some reference type; must be non-null but may contain null items
      offset - the index of the first element of the array that can be shuffled
      length - the length of the section to shuffle
    • shuffle

      public void shuffle(int[] items)
      Shuffles the given array in-place pseudo-randomly, using this to determine how to shuffle.
      Overrides:
      shuffle in class EnhancedRandom
      Parameters:
      items - an int array; must be non-null
    • shuffle

      public void shuffle(long[] items)
      Shuffles the given array in-place pseudo-randomly, using this to determine how to shuffle.
      Overrides:
      shuffle in class EnhancedRandom
      Parameters:
      items - a long array; must be non-null
    • shuffle

      public void shuffle(float[] items)
      Shuffles the given array in-place pseudo-randomly, using this to determine how to shuffle.
      Overrides:
      shuffle in class EnhancedRandom
      Parameters:
      items - a float array; must be non-null
    • shuffle

      public void shuffle(char[] items)
      Shuffles the given array in-place pseudo-randomly, using this to determine how to shuffle.
      Overrides:
      shuffle in class EnhancedRandom
      Parameters:
      items - a char array; must be non-null
    • shuffle

      public void shuffle(byte[] items)
      Shuffles the given array in-place pseudo-randomly, using this to determine how to shuffle.
      Overrides:
      shuffle in class EnhancedRandom
      Parameters:
      items - a byte array; must be non-null
    • shuffle

      public void shuffle(double[] items)
      Shuffles the given array in-place pseudo-randomly, using this to determine how to shuffle.
      Overrides:
      shuffle in class EnhancedRandom
      Parameters:
      items - a double array; must be non-null
    • shuffle

      public void shuffle(short[] items)
      Shuffles the given array in-place pseudo-randomly, using this to determine how to shuffle.
      Overrides:
      shuffle in class EnhancedRandom
      Parameters:
      items - a short array; must be non-null
    • shuffle

      public void shuffle(boolean[] items)
      Shuffles the given array in-place pseudo-randomly, using this to determine how to shuffle.
      Overrides:
      shuffle in class EnhancedRandom
      Parameters:
      items - a boolean array; must be non-null
    • shuffle

      public <T> void shuffle(T[] items)
      Shuffles the given array in-place pseudo-randomly, using this to determine how to shuffle.
      Overrides:
      shuffle in class EnhancedRandom
      Parameters:
      items - an array of some reference type; must be non-null but may contain null items
    • shuffle

      public <T> void shuffle(List<T> items)
      Shuffles the given List in-place pseudo-randomly, using this to determine how to shuffle.
      Overrides:
      shuffle in class EnhancedRandom
      Parameters:
      items - a List of some type T; must be non-null but may contain null items
    • shuffle

      public <T> void shuffle(List<T> items, int offset, int length)
      Shuffles a section of the given List in-place pseudo-randomly, using this to determine how to shuffle.
      Overrides:
      shuffle in class EnhancedRandom
      Parameters:
      items - a List of some type T; must be non-null but may contain null items
      offset - the index of the first element of the array that can be shuffled
      length - the length of the section to shuffle
    • copy

      public ReverseWrapper copy()
      Creates a new EnhancedRandom with identical states to this one, so if the same EnhancedRandom methods are called on this object and its copy (in the same order), the same outputs will be produced. This is not guaranteed to copy the inherited state of any parent class, so if you call methods that are only implemented by a superclass (like Random) and not this one, the results may differ.
      Specified by:
      copy in class EnhancedRandom
      Returns:
      a deep copy of this EnhancedRandom.
    • stringSerialize

      public String stringSerialize(com.github.tommyettinger.digital.Base base)
      Serializes the current state of this EnhancedRandom to a String that can be used by EnhancedRandom.stringDeserialize(String) to load this state at another time.
      Overrides:
      stringSerialize in class EnhancedRandom
      Parameters:
      base - which Base to use, from the "digital" library, such as Base.BASE10
      Returns:
      a String storing all data from the EnhancedRandom part of this generator
    • stringDeserialize

      public ReverseWrapper stringDeserialize(String data, com.github.tommyettinger.digital.Base base)
      Given a String in the format produced by stringSerialize(Base), and the same Base used by the serialization, this will attempt to set this EnhancedRandom object to match the state in the serialized data. This only works if this EnhancedRandom is the same implementation that was serialized, and also needs the Bases to be identical. Returns this EnhancedRandom, after possibly changing its state.
      Overrides:
      stringDeserialize in class EnhancedRandom
      Parameters:
      data - a String probably produced by stringSerialize(Base)
      base - which Base to use, from the "digital" library, such as Base.BASE10
      Returns:
      this, after setting its state
    • equals

      public boolean equals(Object o)
      Overrides:
      equals in class Object
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class Object
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • readExternal

      public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
      The object implements the readExternal method to restore its contents by calling the methods of DataInput for primitive types and readObject for objects, strings and arrays. The readExternal method must read the values in the same sequence and with the same types as were written by writeExternal.
      Specified by:
      readExternal in interface Externalizable
      Overrides:
      readExternal in class EnhancedRandom
      Parameters:
      in - the stream to read data from in order to restore the object
      Throws:
      IOException - if I/O errors occur
      ClassNotFoundException
    • writeExternal

      public void writeExternal(ObjectOutput out) throws IOException
      Needs the type of wrapped registered.
      Specified by:
      writeExternal in interface Externalizable
      Overrides:
      writeExternal in class EnhancedRandom
      Parameters:
      out - the stream to write the object to
      Throws:
      IOException - Includes any I/O exceptions that may occur