Skip to content

Instantly share code, notes, and snippets.

@line-o
Last active May 5, 2021 06:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save line-o/c232dc9e5728094fba67e8b37fb64497 to your computer and use it in GitHub Desktop.
Save line-o/c232dc9e5728094fba67e8b37fb64497 to your computer and use it in GitHub Desktop.
dicey - use randomness with comfort
xquery version "3.1";
declare namespace dicey="http://line-o.de/ns/dicey";
declare function dicey:sequence ($n as xs:integer,
$generator as map(xs:string, item())) as item()* {
fold-left(
1 to $n,
map { "sequence": (), "generator": $generator},
dicey:reducer#2
)?sequence
};
declare function dicey:reducer ($accu as map(*), $counter as xs:integer) {
map {
"sequence": ($accu?sequence, $accu?generator?number),
"generator": $accu?generator?next()
}
};
declare function dicey:ranged-random ($min as xs:decimal, $max as xs:decimal,
$generator as map(xs:string, item())) {
map {
"number": ($generator?number * ($max + $min)) - $min,
"next": function () {
dicey:ranged-random($min, $max,
$generator?next())
}
}
};
declare function dicey:ranged-random-integer ($min as xs:integer, $max as xs:integer,
$generator as map(xs:string, item())) {
map {
"number": xs:integer(round($generator?number * ($max - $min)) + $min),
"next": function () {
dicey:ranged-random-integer($min, $max,
$generator?next())
}
}
};
declare function dicey:random-from ($sequence as item()*,
$generator as map(xs:string, item())) {
let $random-index := xs:integer($generator?number * (count($sequence))) + 1
return map {
"number": $sequence[$random-index], (: not necessarily a number :)
"next": function () {
dicey:random-from($sequence,
$generator?next())
}
}
};
declare function dicey:n-integers-from-to ($n as xs:integer, $min as xs:integer, $max as xs:integer) {
dicey:sequence($n,
dicey:ranged-random-integer($min, $max,
random-number-generator()))
};
declare function dicey:random-from-characters ($n as xs:integer, $characters as xs:string) as xs:string {
dicey:sequence($n,
dicey:random-from(string-to-codepoints($characters),
random-number-generator()))
=> for-each(codepoints-to-string(?))
=> string-join()
};
declare function dicey:d6() {
dicey:ranged-random-integer(1, 6,
random-number-generator())
};
(: throw a dice :)
dicey:sequence(1, dicey:d6()),
(: throw three dice in a row :)
array{dicey:sequence(3, dicey:d6())},
(: one in a million :)
dicey:n-integers-from-to(1, 1, 1000000),
(: string with ten random small latin characters :)
dicey:random-from-characters(10, "abcdefghijklmnopqrstuvwxyz"),
(: pick something at random :)
dicey:random-from((
map {
"name": "alice",
"id": dicey:n-integers-from-to(1, 1, 1000000)
},
map {
"name": "bob",
"id": dicey:n-integers-from-to(1, 1, 1000000)
}
),
random-number-generator())?number
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment