Last active
May 5, 2021 06:28
-
-
Save line-o/c232dc9e5728094fba67e8b37fb64497 to your computer and use it in GitHub Desktop.
dicey - use randomness with comfort
This file contains hidden or 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
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