generated from edjCase/motoko-library-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Gekctek
committed
Oct 23, 2023
1 parent
143c9d7
commit 5462b88
Showing
5 changed files
with
178 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,11 @@ | ||
[dependencies] | ||
base = "0.8.7" | ||
base = "0.9.6" | ||
|
||
[package] | ||
name = "" | ||
name = "random" | ||
version = "0.1.0" | ||
description = "A library for " | ||
repository = "https://github.com/edjcase/motoko_" | ||
description = "A library for random helper funtions" | ||
repository = "https://github.com/edjcase/motoko_random" | ||
|
||
[dev-dependencies] | ||
test = "1.0.1" | ||
test = "1.0.1" |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
import Random "mo:base/Random"; | ||
import Debug "mo:base/Debug"; | ||
import Int "mo:base/Int"; | ||
import Nat8 "mo:base/Nat8"; | ||
import Array "mo:base/Array"; | ||
import Iter "mo:base/Iter"; | ||
import Buffer "mo:base/Buffer"; | ||
|
||
module Module { | ||
public type RandomBinomialGenerator = { | ||
binomial : (Nat8) -> ?Nat8; | ||
}; | ||
public type RandomByteGenerator = { | ||
byte : () -> ?Nat8; | ||
}; | ||
public type RandomRangeGenerator = { | ||
range : (Nat8) -> ?Nat; | ||
}; | ||
public type RandomCoinGenerator = { | ||
coin : () -> ?Bool; | ||
}; | ||
public type RandomNumberGenerator = RandomBinomialGenerator and RandomByteGenerator and RandomRangeGenerator and RandomCoinGenerator; | ||
|
||
public func fromSeed(seed : Blob) : FiniteX { | ||
FiniteX(seed); | ||
}; | ||
|
||
public func randomInt(random : RandomRangeGenerator, min : Int, max : Int) : ?Int { | ||
if (min > max) { | ||
Debug.trap("Min cannot be larger than max"); | ||
}; | ||
let range : Nat = Int.abs(max - min) + 1; | ||
|
||
var bitsNeeded : Nat = 0; | ||
var temp : Nat = range; | ||
while (temp > 0) { | ||
temp := temp / 2; | ||
bitsNeeded += 1; | ||
}; | ||
|
||
let ?randVal = random.range(Nat8.fromNat(bitsNeeded)) else return null; | ||
let randInt = min + (randVal % range); | ||
?randInt; | ||
}; | ||
|
||
public func randomNat(random : RandomRangeGenerator, min : Nat, max : Nat) : ?Nat { | ||
let ?randInt = randomInt(random, min, max) else return null; | ||
?Int.abs(randInt); | ||
}; | ||
|
||
public func shuffleArray<T>(random : RandomRangeGenerator, array : [T]) : ?[T] { | ||
let arraySize = array.size(); | ||
if (arraySize == 0) { | ||
return ?array; | ||
}; | ||
let shuffledArray = Buffer.fromArray<T>(array); | ||
Buffer.reverse(shuffledArray); | ||
var i : Nat = arraySize; | ||
for (item in shuffledArray.vals()) { | ||
i -= 1; | ||
let ?randIdx = randomNat(random, 0, i) else return null; | ||
let temp = shuffledArray.get(i); | ||
shuffledArray.put(i, shuffledArray.get(randIdx)); | ||
shuffledArray.put(randIdx, temp); | ||
}; | ||
return ?Buffer.toArray(shuffledArray); | ||
}; | ||
|
||
public class FiniteX(seed : Blob) { | ||
let random : RandomNumberGenerator = Random.Finite(seed); | ||
|
||
public func byte() : ?Nat8 { | ||
random.byte(); | ||
}; | ||
|
||
public func bool() : ?Bool { | ||
random.coin(); | ||
}; | ||
|
||
public func int(min : Int, max : Int) : ?Int { | ||
Module.randomInt(random, min, max); | ||
}; | ||
|
||
public func nat(min : Nat, max : Nat) : ?Nat { | ||
Module.randomNat(random, min, max); | ||
}; | ||
|
||
public func shuffleArray<T>(array : [T]) : ?[T] { | ||
Module.shuffleArray<T>(random, array); | ||
}; | ||
|
||
public func randomElement<T>(array : [T]) : ?T { | ||
let ?i = nat(0, array.size() - 1) else return null; | ||
?array.get(i); | ||
}; | ||
}; | ||
}; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import Iter "mo:base/Iter"; | ||
import { test } "mo:test"; | ||
import Debug "mo:base/Debug"; | ||
import Int "mo:base/Int"; | ||
import RandomX "../src/RandomX"; | ||
|
||
let assertEqualInt = func(expected : Int, actual : ?Int) : () { | ||
if (actual != ?expected) { | ||
switch (actual) { | ||
case (null) Debug.trap("Expected " # Int.toText(expected) # ", but ran out of entropy."); | ||
case (?i) Debug.trap("Expected " # Int.toText(expected) # ", got " # Int.toText(i)); | ||
}; | ||
}; | ||
}; | ||
|
||
test( | ||
"int", | ||
func() { | ||
let testCases : [{ seed : Blob; expected : Int; min : Int; max : Int }] = [ | ||
{ | ||
seed = "\A1\B2\C3\D4\E5\F6\10\11\12\13\14\15\16\17\18\19\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27"; | ||
expected = 1; | ||
min = 0; | ||
max = 10; | ||
}, | ||
{ | ||
seed = "\A1\B2\C8\D4\E5\F6\10\11\12\13\14\15\16\17\18\19\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27"; | ||
expected = -3; | ||
min = -4; | ||
max = 5; | ||
}, | ||
{ | ||
seed = "\A1\B2\C8\D4\E5\F6\10\11\12\13\14\15\16\17\18\19\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27"; | ||
expected = 711156982585303; | ||
min = -1; | ||
max = 1_000_000_000_000_000; | ||
}, | ||
]; | ||
for (testCase in Iter.fromArray(testCases)) { | ||
let rand = RandomX.fromSeed(testCase.seed); | ||
let randInt = rand.int(testCase.min, testCase.max); | ||
assertEqualInt(testCase.expected, randInt); | ||
}; | ||
}, | ||
); | ||
|
||
test( | ||
"nat", | ||
func() { | ||
let testCases : [{ seed : Blob; expected : Nat; min : Nat; max : Nat }] = [ | ||
{ | ||
seed = "\A1\B2\C3\D4\E5\F6\10\11\12\13\14\15\16\17\18\19\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27"; | ||
expected = 1; | ||
min = 0; | ||
max = 10; | ||
}, | ||
{ | ||
seed = "\A1\B2\C8\D4\E5\F6\10\11\12\13\14\15\16\17\18\19\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27"; | ||
expected = 2; | ||
min = 1; | ||
max = 5; | ||
}, | ||
{ | ||
seed = "\A1\B2\C8\D4\E5\F6\10\11\12\13\14\15\16\17\18\19\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27\1A\1B\1C\1D\1E\1F\20\21\22\23\24\25\26\27"; | ||
expected = 711156982685303; | ||
min = 99999; | ||
max = 1_000_000_000_000_000; | ||
}, | ||
]; | ||
for (testCase in Iter.fromArray(testCases)) { | ||
let rand = RandomX.fromSeed(testCase.seed); | ||
let randInt = rand.nat(testCase.min, testCase.max); | ||
assertEqualInt(testCase.expected, randInt); | ||
}; | ||
}, | ||
); |