Seven-sided dice from five-sided dice: Difference between revisions

m
 
(83 intermediate revisions by 35 users not shown)
Line 1:
{{task|Probability and statistics}}
 
Given an equal-probability generator of one of the integers 1 to 5
;Task:
as <code>dice5</code>; create <code>dice7</code> that generates a pseudo-random integer from
(Given an equal-probability generator of one of the integers 1 to 5
as <code>dice5</code>), &nbsp; create <code>dice7</code> that generates a pseudo-random integer from
1 to 7 in equal probability using only <code>dice5</code> as a source of random
numbers, &nbsp; and check the distribution for at least 1000000one million calls using the function created in &nbsp; [[Verify distribution uniformity/Naive|Simple Random Distribution Checker]].
 
 
'''Implementation suggestion:'''
Line 11 ⟶ 14:
 
<small>(Task adapted from an answer [http://stackoverflow.com/questions/90715/what-are-the-best-programming-puzzles-you-came-across here])</small>
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">F dice5()
R random:(1..5)
 
F dice7() -> Int
V r = dice5() + dice5() * 5 - 6
R I r < 21 {(r % 7) + 1} E dice7()
 
F distcheck(func, repeats, delta)
V bin = DefaultDict[Int, Int]()
L 1..repeats
bin[func()]++
V target = repeats I/ bin.len
V deltacount = Int(delta / 100.0 * target)
assert(all(bin.values().map(count -> abs(@target - count) < @deltacount)), ‘Bin distribution skewed from #. +/- #.: #.’.format(target, deltacount, sorted(bin.items()).map((key, count) -> (key, @target - count))))
print(bin)
 
distcheck(dice5, 1000000, 1)
distcheck(dice7, 1000000, 1)</syntaxhighlight>
 
{{out}}
<pre>
DefaultDict([1 = 199586, 2 = 200094, 3 = 198933, 4 = 200824, 5 = 200563])
DefaultDict([1 = 142478, 2 = 142846, 3 = 143056, 4 = 142894, 5 = 143052, 6 = 143147, 7 = 142527])
</pre>
 
=={{header|Ada}}==
The specification of a package Random_57:
<langsyntaxhighlight Adalang="ada">package Random_57 is
 
type Mod_7 is mod 7;
Line 23 ⟶ 55:
-- a simple implementation
 
end Random_57;</langsyntaxhighlight>
Implementation of Random_57:
<langsyntaxhighlight Adalang="ada"> with Ada.Numerics.Discrete_Random;
 
package body Random_57 is
Line 81 ⟶ 113:
begin
Rand_5.Reset(Gen);
end Random_57;</langsyntaxhighlight>
A main program, using the Random_57 package:
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO, Random_57;
 
procedure R57 is
Line 133 ⟶ 165:
Test( 1_000_000, Rand'Access, 0.02);
Test(10_000_000, Rand'Access, 0.01);
end R57;</langsyntaxhighlight>
{{out}}
A sample output:
<pre>
Sample Size: 10000
Line 166 ⟶ 198:
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d]}}
C's version using no multiplications, divisions, or mod operators:
<langsyntaxhighlight lang="algol68">PROC dice5 = INT:
1 + ENTIER (5*random);
 
Line 200 ⟶ 232:
distcheck(dice5, 1000000, 5);
distcheck(dice7, 1000000, 7)
)</langsyntaxhighlight>
{{out}}
Sample output:
<pre>
200598, 199852, 199939, 200602, 199009
Line 208 ⟶ 240:
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">dice5()
{ Random, v, 1, 5
Return, v
Line 218 ⟶ 250:
IfLess v, 21, Return, (v // 3) + 1
}
}</langsyntaxhighlight>
<pre>Distribution check:
 
Line 235 ⟶ 267:
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> MAXRND = 7
FOR r% = 2 TO 5
check% = FNdistcheck(FNdice7, 10^r%, 0.1)
Line 265 ⟶ 297:
IF bins%(i%)/(repet%/m%) < 1-delta s% += 1
NEXT
= s%</langsyntaxhighlight>
{{out}}
Output:
<pre>
Over 100 runs dice7 failed distribution check with 4 bin(s) out of range
Line 275 ⟶ 307:
 
=={{header|C}}==
<langsyntaxhighlight lang="c">int rand5()
{
int r, rand_max = RAND_MAX - (RAND_MAX % 5);
Line 294 ⟶ 326:
printf(check(rand7, 7, 1000000, .05) ? "flat\n" : "not flat\n");
return 0;
}</syntaxhighlight>
}</lang>output
{{out}}
<pre>
flat
flat
</pre>
 
=={{header|C sharp}}==
{{trans|Java}}
<syntaxhighlight lang="csharp">
using System;
 
public class SevenSidedDice
{
Random random = new Random();
static void Main(string[] args)
{
SevenSidedDice sevenDice = new SevenSidedDice();
Console.WriteLine("Random number from 1 to 7: "+ sevenDice.seven());
Console.Read();
}
int seven()
{
int v=21;
while(v>20)
v=five()+five()*5-6;
return 1+v%7;
}
int five()
{
return 1 + random.Next(5);
}
}</syntaxhighlight>
 
=={{header|C++}}==
This solution tries to minimize calls to the underlying d5 by reusing information from earlier calls.
<langsyntaxhighlight lang="cpp">template<typename F> class fivetoseven
{
public:
Line 350 ⟶ 413:
test_distribution(d5, 1000000, 0.001);
test_distribution(d7, 1000000, 0.001);
}</langsyntaxhighlight>
 
=={{header|Clojure}}==
Uses the verify function defined in [[Verify distribution uniformity/Naive#Clojure]]
<langsyntaxhighlight Clojurelang="clojure">(def dice5 #(rand-int 5))
 
(defn dice7 []
Line 368 ⟶ 431:
(doseq [n [100 1000 10000] [num count okay?] (verify dice7 n)]
(println "Saw" num count "times:"
(if okay? "that's" " not") "acceptable"))</langsyntaxhighlight>
 
<pre>Saw 0 10 times: not acceptable
Line 394 ⟶ 457:
=={{header|Common Lisp}}==
{{trans|C}}
<langsyntaxhighlight lang="lisp">(defun d5 ()
(1+ (random 5)))
 
Line 400 ⟶ 463:
(loop for d55 = (+ (* 5 (d5)) (d5) -6)
until (< d55 21)
finally (return (1+ (mod d55 7)))))</langsyntaxhighlight>
 
<pre>> (check-distribution 'd7 1000)
Line 416 ⟶ 479:
=={{header|D}}==
{{trans|C++}}
<langsyntaxhighlight lang="d">import std.random;
import verify_distribution_uniformity_naive: distCheck;
 
/// Generates a random number in [1, 5].
int dice5() /*pure nothrow*/ @safe {
return uniform(1, 6);
}
 
/// Naive, generates a random number in [1, 7] using dice5.
int fiveToSevenNaive() /*pure nothrow*/ @safe {
immutable int r = dice5() + dice5() * 5 - 6;
return (r < 21) ? (r % 7) + 1 : fiveToSevenNaive();
Line 434 ⟶ 497:
minimizing calls to dice5.
*/
int fiveToSevenSmart() @safe {
static int rem = 0, max = 1;
 
Line 457 ⟶ 520:
}
 
void main() /*@safe*/ {
enum int N = 400_000;
distCheck(&dice5, N, 1);
distCheck(&fiveToSevenNaive, N, 1);
distCheck(&fiveToSevenSmart, N, 1);
}</langsyntaxhighlight>
{{out}}
<pre>1 80365
Line 489 ⟶ 552:
{{trans|Common Lisp}}
{{improve|E|Write dice7 in a prettier fashion and use the distribution checker once it's been written.}}
<langsyntaxhighlight lang="e">def dice5() {
return entropy.nextInt(5) + 1
}
Line 497 ⟶ 560:
while ((d55 := 5 * dice5() + dice5() - 6) >= 21) {}
return d55 %% 7 + 1
}</langsyntaxhighlight>
<langsyntaxhighlight lang="e">def bins := ([0] * 7).diverge()
for x in 1..1000 {
bins[dice7() - 1] += 1
}
println(bins.snapshot())</langsyntaxhighlight>
 
=={{header|EasyLang}}==
<syntaxhighlight>
func dice5 .
return randint 5
.
func dice25 .
return (dice5 - 1) * 5 + dice5
.
func dice7a .
return dice25 mod1 7
.
func dice7b .
repeat
h = dice25
until h <= 21
.
return h mod1 7
.
numfmt 3 0
n = 1000000
len dist[] 7
#
proc checkdist . .
for i to len dist[]
h = dist[i] / n * 7
if abs (h - 1) > 0.01
bad = 1
.
dist[i] = 0
print h
.
if bad = 1
print "-> not uniform"
else
print "-> uniform"
.
.
#
for i to n
dist[dice7a] += 1
.
checkdist
#
print ""
for i to n
dist[dice7b] += 1
.
checkdist
</syntaxhighlight>
 
{{out}}
<pre>
1.122
1.118
1.121
1.117
0.840
0.842
0.840
-> not uniform
 
0.996
1.003
1.001
0.997
1.004
0.998
1.001
-> uniform
</pre>
 
=={{header|Elixir}}==
<syntaxhighlight lang="elixir">defmodule Dice do
def dice5, do: :rand.uniform( 5 )
def dice7 do
dice7_from_dice5
end
defp dice7_from_dice5 do
d55 = 5*dice5 + dice5 - 6 # 0..24
if d55 < 21, do: rem( d55, 7 ) + 1,
else: dice7_from_dice5
end
end
 
fun5 = fn -> Dice.dice5 end
IO.inspect VerifyDistribution.naive( fun5, 1000000, 3 )
fun7 = fn -> Dice.dice7 end
IO.inspect VerifyDistribution.naive( fun7, 1000000, 3 )</syntaxhighlight>
 
{{out}}
<pre>
:ok
:ok
</pre>
 
=={{header|Erlang}}==
<syntaxhighlight lang="erlang">
-module( dice ).
 
-export( [dice5/0, dice7/0, task/0] ).
 
dice5() -> random:uniform( 5 ).
 
dice7() ->
dice7_small_enough( dice5() * 5 + dice5() - 6 ). % 0 - 24
 
task() ->
verify_distribution_uniformity:naive( fun dice7/0, 1000000, 1 ).
 
 
 
dice7_small_enough( N ) when N < 21 -> N div 3 + 1;
dice7_small_enough( _N ) -> dice7().
</syntaxhighlight>
 
{{out}}
<pre>
76> dice:task().
ok
</pre>
 
=={{header|Factor}}==
<syntaxhighlight lang="factor">USING: kernel random sequences assocs locals sorting prettyprint
math math.functions math.statistics math.vectors math.ranges ;
IN: rosetta-code.dice7
 
! Output a random integer 1..5.
: dice5 ( -- x )
5 [1,b] random
;
 
! Output a random integer 1..7 using dice5 as randomness source.
: dice7 ( -- x )
0 [ dup 21 < ] [ drop dice5 5 * dice5 + 6 - ] do until
7 rem 1 +
;
 
! Roll the die by calling the quotation the given number of times and return
! an array with roll results.
! Sample call: 1000 [ dice7 ] roll
: roll ( times quot: ( -- x ) -- array )
[ call( -- x ) ] curry replicate
;
 
! Input array contains outcomes of a number of die throws. Each die result is
! an integer in the range 1..X. Calculate and return the number of each
! of the results in the array so that in the first position of the result
! there is the number of ones in the input array, in the second position
! of the result there is the number of twos in the input array, etc.
: count-dice-outcomes ( X array -- array )
histogram
swap [1,b] [ over [ 0 or ] change-at ] each
sort-keys values
;
 
! Verify distribution uniformity/Naive. Delta is the acceptable deviation
! from the ideal number of items in each bucket, expressed as a fraction of
! the total count. Sides is the number of die sides. Die-func is a word that
! produces a random number on stack in the range [1..sides], times is the
! number of times to call it.
! Sample call: 0.02 7 [ dice7 ] 100000 verify
:: verify ( delta sides die-func: ( -- random ) times -- )
sides
times die-func roll
count-dice-outcomes
dup .
times sides / :> ideal-count
ideal-count v-n vabs
times v/n
delta [ < ] curry all?
[ "Random enough" . ] [ "Not random enough" . ] if
;
 
 
! Call verify with 1, 10, 100, ... 1000000 rolls of 7-sided die.
: verify-all ( -- )
{ 1 10 100 1000 10000 100000 1000000 }
[| times | 0.02 7 [ dice7 ] times verify ] each
;</syntaxhighlight>
 
{{out}}
<pre>USE: rosetta-code.dice7 verify-all
{ 0 0 0 1 0 0 0 }
"Not random enough"
{ 0 2 3 1 1 1 2 }
"Not random enough"
{ 17 12 15 11 13 13 19 }
"Not random enough"
{ 140 130 141 148 143 155 143 }
"Random enough"
{ 1457 1373 1427 1433 1443 1382 1485 }
"Random enough"
{ 14225 14320 14216 14326 14415 14084 14414 }
"Random enough"
{ 142599 141910 142524 143029 143353 142696 143889 }
"Random enough"</pre>
 
=={{header|Forth}}==
{{works with|GNU Forth}}
<syntaxhighlight lang="forth">require random.fs
 
: d5 5 random 1+ ;
: discard? 5 = swap 1 > and ;
: d7
begin d5 d5 2dup discard? while 2drop repeat
1- 5 * + 1- 7 mod 1+ ;</syntaxhighlight>
{{out}}
<pre>cr ' d7 1000000 7 1 check-distribution .
lower bound = 141429 upper bound = 144285
1 : 143241 ok
2 : 142397 ok
3 : 143522 ok
4 : 142909 ok
5 : 142001 ok
6 : 142844 ok
7 : 143086 ok
-1</pre>
 
=={{header|Fortran}}==
{{works with|Fortran|95 and later}}
<langsyntaxhighlight lang="fortran">module rand_mod
implicit none
 
Line 542 ⟶ 825:
call distcheck(rand7, samples, 0.001)
 
end program</langsyntaxhighlight>
{{out}}
Output
<pre>Distribution Uniform
 
Line 553 ⟶ 836:
Distribution potentially skewed for bucket 6 Expected: 142857 Actual: 142163
Distribution potentially skewed for bucket 7 Expected: 142857 Actual: 142513</pre>
 
 
=={{header|FreeBASIC}}==
{{trans|Liberty BASIC}}
<syntaxhighlight lang="freebasic">
Function dice5() As Integer
Return Int(Rnd * 5) + 1
End Function
 
Function dice7() As Integer
Dim As Integer temp
Do
temp = dice5() * 5 + dice5() -6
Loop Until temp < 21
Return (temp Mod 7) +1
End Function
 
Dim Shared As Ulongint n = 1000000
Print "Testing "; n; " times"
If Not(distCheck(n, 0.05)) Then Print "Test failed" Else Print "Test passed"
Sleep
</syntaxhighlight>
{{out}}
<pre>
Igual que la entrada de Liberty BASIC.
</pre>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 610 ⟶ 919:
max, flatEnough = distCheck(dice7, 7, calls, 500)
fmt.Println("Max delta:", max, "Flat enough:", flatEnough)
}</langsyntaxhighlight>
{{out}}
Output:
<pre>
Max delta: 356.1428571428696 Flat enough: true
Line 618 ⟶ 927:
 
=={{header|Groovy}}==
<langsyntaxhighlight lang="groovy">random = new Random()
 
int rand5() {
Line 630 ⟶ 939:
}
(raw % 7) + 1
}</langsyntaxhighlight>
Test:
<langsyntaxhighlight lang="groovy">def test = {
(1..6). each {
def counts = [0g, 0g, 0g, 0g, 0g, 0g, 0g]
Line 657 ⟶ 966:
=============="""
test(it)
}</langsyntaxhighlight>
{{out}}
Output:
<pre style="height:30ex;overflow:scroll;">TRIAL #1
==============
Line 767 ⟶ 1,076:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">import System.Random
import Data.List
 
Line 775 ⟶ 1,084:
let d7 = 5*d51+d52-6
if d7 > 20 then sevenFrom5Dice
else return $ 1 + d7 `mod` 7</langsyntaxhighlight>
{{out}}
Output:
<langsyntaxhighlight lang="haskell">*Main> replicateM 10 sevenFrom5Dice
[2,3,1,1,6,2,5,6,5,3]</langsyntaxhighlight>
Test:
<langsyntaxhighlight lang="haskell">*Main> mapM_ print .sort =<< distribCheck sevenFrom5Dice 1000000 3
(1,(142759,True))
(2,(143078,True))
Line 787 ⟶ 1,096:
(5,(142896,True))
(6,(143028,True))
(7,(143130,True))</langsyntaxhighlight>
 
=={{header|Icon}} and {{header|Unicon}}==
{{trans|Ruby}}
Uses <code>verify_uniform</code> from [[Simple_Random_Distribution_Checker#Icon_and_Unicon|here]].
<syntaxhighlight lang="icon">
<lang Icon>
$include "distribution-checker.icn"
 
Line 808 ⟶ 1,117:
else write ("skewed")
end
</syntaxhighlight>
</lang>
 
{{out}}
Output:
<pre>
5 142870
Line 824 ⟶ 1,133:
=={{header|J}}==
The first step is to create 7-sided dice rolls from 5-sided dice rolls (<code>rollD5</code>):
<langsyntaxhighlight lang="j">rollD5=: [: >: ] ?@$ 5: NB. makes a y shape array of 5s, "rolls" the array and increments.
roll2xD5=: [: rollD5 2 ,~ */ NB. rolls D5 twice for each desired D7 roll (y rows, 2 cols)
toBase10=: 5 #. <: NB. decrements and converts rows from base 5 to 10
Line 830 ⟶ 1,139:
groupin3s=: [: >. >: % 3: NB. increments, divides by 3 and takes ceiling
 
getD7=: groupin3s@keepGood@toBase10@roll2xD5</langsyntaxhighlight>
Here are a couple of variations on the theme that achieve the same result:
<langsyntaxhighlight lang="j">getD7b=: 0 8 -.~ 3 >.@%~ 5 #. [: <:@rollD5 2 ,~ ]
getD7c=: [: (#~ 7&>:) 3 >.@%~ [: 5&#.&.:<:@rollD5 ] , 2:</langsyntaxhighlight>
The trouble is that we probably don't have enough D7 rolls yet because we compressed out any double D5 rolls that evaluated to 21 or more. So we need to accumulate some more D7 rolls until we have enough. J has two types of verb definition - tacit (arguments not referenced) and explicit (more conventional function definitions) illustrated below:
 
Here's an explicit definition that accumulates rolls from <code>getD7</code>:
<langsyntaxhighlight lang="j">rollD7x=: monad define
n=. */y NB. product of vector y is total number of D7 rolls required
rolls=. '' NB. initialize empty noun rolls
while. n > #resrolls do. NB. checks if if enough D7 rolls accumulated
rolls=. rolls, getD7 >. 0.75 * n NB. calcs 3/4 of required rolls and accumulates getD7 rolls
end.
y $ rolls NB. shape the result according to the vector y
)</langsyntaxhighlight>
Here's a tacit definition that does the same thing:
<langsyntaxhighlight lang="j">getNumRolls=: [: >. 0.75 * */@[ NB. calc approx 3/4 of the required rolls
accumD7Rolls=: ] , getD7@getNumRolls NB. accumulates getD7 rolls
isNotEnough=: */@[ > #@] NB. checks if enough D7 rolls accumulated
 
rollD7t=: ] $ (accumD7Rolls ^: isNotEnough ^:_)&''</langsyntaxhighlight>
The <code>verb1 ^: verb2 ^:_</code> construct repeats <code>x verb1 y</code> while <code>x verb2 y</code> is true. It is like saying "Repeat accumD7Rolls while isNotEnough".
 
Example usage:
<langsyntaxhighlight lang="j"> rollD7t 10 NB. 10 rolls of D7
6 4 5 1 4 2 4 5 2 5
rollD7t 2 5 NB. 2 by 5 array of D7 rolls
Line 872 ⟶ 1,181:
1
($@rollD7x -: $@rollD7t) 2 3 5
1</langsyntaxhighlight>
 
=={{header|Java}}==
{{trans|Python}}
<langsyntaxhighlight Javalang="java">import java.util.Random;
public class SevenSidedDice
{
Line 896 ⟶ 1,205:
return 1+rnd.nextInt(5);
}
}</langsyntaxhighlight>
 
=={{header|JavaScript}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="javascript">function dice5()
{
return 1 + Math.floor(5 * Math.random());
Line 917 ⟶ 1,226:
distcheck(dice5, 1000000);
print();
distcheck(dice7, 1000000);</langsyntaxhighlight>
{{out}}
output
<pre>1 199792
2 200425
Line 932 ⟶ 1,241:
6 142648
7 142619 </pre>
 
=={{header|jq}}==
{{works with|jq}}
'''Also works with gojq, the Go implementation of jq.'''
 
In this entry, the results for both a low-entropy and a
high-entropy 5-sided die are shown. The former uses the computer's
clock as a not-very-good PRNG, and the latter uses /dev/random in accordance
with the following invocation:
<syntaxhighlight lang=sh>
#!/bin/bash
< /dev/random tr -cd '0-9' | fold -w 1 | jq -Mcnr -f dice.jq
</syntaxhighlight>
The results employ a two-tailed χ2-test at the 95% confidence level
according to which we are entitled to reject the null hypothesis of
uniform randomness if the χ2 statistic is less than 1.69 or greater
than 16.013, assuming the number of trials is large enough.
See https://www.itl.nist.gov/div898/handbook/eda/section3/eda3674.htm
 
'''dice.jq'''
<syntaxhighlight lang=jq>
# Output: a PRN in range(0;$n) where $n is .
def prn:
if . == 1 then 0
else . as $n
| (($n-1)|tostring|length) as $w
| [limit($w; inputs)] | join("") | tonumber
| if . < $n then . else ($n | prn) end
end;
 
# Emit a stream of [value, frequency] pairs
def histogram(stream):
reduce stream as $s ({};
($s|type) as $t
| (if $t == "string" then $s else ($s|tojson) end) as $y
| .[$t][$y][0] = $s
| .[$t][$y][1] += 1 )
| .[][] ;
 
# sum of squares
def ss(s): reduce s as $x (0; . + ($x * $x));
 
def chiSquared($expected):
debug # show the actual frequencies
| ss( .[] - $expected ) / $expected;
 
# The high-entropy 5-sided die
def dice5: 1 + (5|prn);
 
# The low-entropy 5-sided die
def pseudo_dice5:
def r: (now * 100000 | floor) % 10;
null | until(. and (. < 5); r) | 1 + . ;
 
# The formal argument dice5 should behave like a 5-sided dice:
def dice7(dice5):
1 + ([limit(7; repeat(dice5))]|add % 7) ;
 
# Issue a report on the results of a sequence of $n trials using the specified dice
def report(dice; $n):
1.69 as $lower
| 16.013 as $upper
| [histogram( limit($n; repeat(dice)) ) | last]
| chiSquared($n/7) as $x2
| "The χ2 statistic for a trial of \($n) virtual tosses is \($x2).",
"Using a two-sided χ2-test with seven degrees of freedom (\($lower), \($upper)), it is reasonable to conclude that",
(if $x2 < $lower then "this is lower than would be expected for a fair die."
elif $x2 > $upper then "this is higher than would be expected for a fair die."
else "this is consistent with the die being fair."
end) ;
 
def report($n):
"Low-entropy die results:",
report(dice7(pseudo_dice5); $n),
"",
"High-entropy die results:",
report(dice7(dice5); $n) ;
 
report(70)
</syntaxhighlight>
{{output}}
<pre>
Low-entropy die results:
["DEBUG:",[19,14,6,18,7,5,1]]
The χ2 statistic for a trial of 70 virtual tosses is 29.2.
Using a two-sided χ2-test with seven degrees of freedom (1.69, 16.013), it is reasonable to conclude that
this is higher than would be expected for a fair die.
 
High-entropy die results:
["DEBUG:",[9,11,9,10,15,11,5]]
The χ2 statistic for a trial of 70 virtual tosses is 5.4.
Using a two-sided χ2-test with seven degrees of freedom (1.69, 16.013), it is reasonable to conclude that
this is consistent with the die being fair.
</pre>
'''Results for 1,000,000 trials:'''
<pre>
Low-entropy die results:
["DEBUG:",[41440,57949,15946,44821,117168,339337,383339]]
The χ2 statistic for a trial of 1000000 virtual tosses is 982157.0011039999.
Using a two-sided χ2-test with seven degrees of freedom (1.69, 16.013), it is reasonable to conclude that
this is higher than would be expected for a fair die.
 
High-entropy die results:
["DEBUG:",[142860,143087,142213,142065,143359,143494,142922]]
The χ2 statistic for a trial of 1000000 virtual tosses is 12.298347999999999.
Using a two-sided χ2-test with seven degrees of freedom (1.69, 16.013), it is reasonable to conclude that
this is consistent with the die being fair.
</pre>
 
=={{header|Julia}}==
 
<syntaxhighlight lang="julia">
using Random: seed!
seed!(1234) # for reproducibility
 
dice5() = rand(1:5)
 
function dice7()
while true
a = dice5()
b = dice5()
c = a + 5(b - 1)
if c <= 21
return mod1(c, 7)
end
end
end
 
rolls = (dice7() for i in 1:100000)
roll_counts = Dict{Int,Int}()
for roll in rolls
roll_counts[roll] = get(roll_counts, roll, 0) + 1
end
foreach(println, sort(roll_counts))
 
</syntaxhighlight>
 
Output:
<pre>
1 => 14530
2 => 13872
3 => 14422
4 => 14425
5 => 14323
6 => 14315
7 => 14113
</pre>
 
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.1.3
 
import java.util.Random
 
val r = Random()
 
fun dice5() = 1 + r.nextInt(5)
 
fun dice7(): Int {
while (true) {
val t = (dice5() - 1) * 5 + dice5() - 1
if (t >= 21) continue
return 1 + t / 3
}
}
 
fun checkDist(gen: () -> Int, nRepeats: Int, tolerance: Double = 0.5) {
val occurs = mutableMapOf<Int, Int>()
for (i in 1..nRepeats) {
val d = gen()
if (occurs.containsKey(d))
occurs[d] = occurs[d]!! + 1
else
occurs.put(d, 1)
}
val expected = (nRepeats.toDouble()/ occurs.size).toInt()
val maxError = (expected * tolerance / 100.0).toInt()
println("Repetitions = $nRepeats, Expected = $expected")
println("Tolerance = $tolerance%, Max Error = $maxError\n")
println("Integer Occurrences Error Acceptable")
val f = " %d %5d %5d %s"
var allAcceptable = true
for ((k,v) in occurs.toSortedMap()) {
val error = Math.abs(v - expected)
val acceptable = if (error <= maxError) "Yes" else "No"
if (acceptable == "No") allAcceptable = false
println(f.format(k, v, error, acceptable))
}
println("\nAcceptable overall: ${if (allAcceptable) "Yes" else "No"}")
}
 
fun main(args: Array<String>) {
checkDist(::dice7, 1_400_000)
}</syntaxhighlight>
 
Sample output:
<pre>
Repetitions = 1400000, Expected = 200000
Tolerance = 0.5%, Max Error = 1000
 
Integer Occurrences Error Acceptable
1 199285 715 Yes
2 200247 247 Yes
3 199709 291 Yes
4 199983 17 Yes
5 199990 10 Yes
6 200664 664 Yes
7 200122 122 Yes
 
Acceptable overall: Yes
</pre>
 
=={{header|Liberty BASIC}}==
<syntaxhighlight lang="lb">
n=1000000 '1000000 would take several minutes
print "Testing ";n;" times"
if not(check(n, 0.05)) then print "Test failed" else print "Test passed"
end
 
'function check(n, delta) is defined at
'http://rosettacode.org/wiki/Verify_distribution_uniformity/Naive#Liberty_BASIC
 
function GENERATOR()
'GENERATOR = int(rnd(0)*10) '0..9
'GENERATOR = 1+int(rnd(0)*5) '1..5: dice5
 
'dice7()
do
temp =dice5() *5 +dice5() -6
loop until temp <21
GENERATOR =( temp mod 7) +1
 
end function
 
function dice5()
dice5=1+int(rnd(0)*5) '1..5: dice5
end function
</syntaxhighlight>
{{Out}}
<pre>
Testing 1000000 times
minVal Expected maxVal
135714 142857 150000
Bucket Counter pass/fail
1 143310
2 143500
3 143040
4 145185
5 140998
6 142610
7 141357
Test passed
</pre>
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">dice5 = function() return math.random(5) end
 
function dice7()
Line 940 ⟶ 1,501:
if x > 20 then return dice7() end
return x%7 + 1
end</langsyntaxhighlight>
 
=={{header|MathematicaM2000 Interpreter}}==
We make a stack object (is reference type) and pass it as a closure to dice7 lambda function. For each dice7 we pop the top value of stack, and we add a fresh dice5 (random(1,5)) as last value of stack, so stack used as FIFO. Each time z has the sum of 7 random values.
<lang Mathematica>sevenFrom5Dice := (tmp$ = 5*RandomInteger[{1, 5}] + RandomInteger[{1, 5}] - 6;
 
If [tmp$ < 21, 1 + Mod[tmp$ , 7], sevenFrom5Dice])</lang>
We check for uniform numbers using +-5% from expected value.
<syntaxhighlight lang="m2000 interpreter">
Module CheckIt {
Def long i, calls, max, min
s=stack:=random(1,5),random(1,5), random(1,5), random(1,5), random(1,5), random(1,5), random(1,5)
z=0: for i=1 to 7 { z+=stackitem(s, i)}
dice7=lambda z, s -> {
=((z-1) mod 7)+1 : stack s {z-=Number : data random(1,5): z+=Stackitem(7)}
}
Dim count(1 to 7)=0& ' long type
calls=700000
p=0.05
IsUniform=lambda max=calls/7*(1+p), min=calls/7*(1-p) (a)->{
if len(a)=0 then =false : exit
=false
m=each(a)
while m
if array(m)<min or array(m)>max then break
end while
=true
}
For i=1 to calls {count(dice7())++}
max=count()#max()
expected=calls div 7
min=count()#min()
for i=1 to 7
document doc$=format$("{0}{1::-7}",i,count(i))+{
}
Next i
doc$=format$("min={0} expected={1} max={2}", min, expected, max)+{
}+format$("Verify Uniform:{0}", if$(IsUniform(count())->"uniform", "skewed"))+{
}
Print
report doc$
clipboard doc$
}
CheckIt
</syntaxhighlight>
 
{{out}}
<pre style="height:30ex;overflow:scroll">
1 9865
2 10109
3 9868
4 9961
5 9936
6 9922
7 10339
min=9865 expected=10000 max=10339
Verify Uniform:uniform
 
 
1 100214
2 100336
3 100049
4 99505
5 99951
6 99729
7 100216
min=99505 expected=100000 max=100336
Verify Uniform:uniform
</pre >
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">sevenFrom5Dice := (tmp$ = 5*RandomInteger[{1, 5}] + RandomInteger[{1, 5}] - 6;
If [tmp$ < 21, 1 + Mod[tmp$ , 7], sevenFrom5Dice])</syntaxhighlight>
<pre>CheckDistribution[sevenFrom5Dice, 1000000, 5]
->Expected: 142857., Generated :{142206,142590,142650,142693,142730,143475,143656}
->"Flat"</pre>
 
=={{header|Nim}}==
We use the distribution checker from task [[Simple Random Distribution Checker#Nim|Simple Random Distribution Checker]].
<syntaxhighlight lang="nim">import random, tables
 
 
proc dice5(): int = rand(1..5)
 
 
proc dice7(): int =
while true:
let val = 5 * dice5() + dice5() - 6
if val < 21:
return val div 3 + 1
 
 
proc checkDist(f: proc(): int; repeat: Positive; tolerance: float) =
 
var counts: CountTable[int]
for _ in 1..repeat:
counts.inc f()
 
let expected = (repeat / counts.len).toInt # Rounded to nearest.
let allowedDelta = (expected.toFloat * tolerance / 100).toInt
var maxDelta = 0
for val, count in counts.pairs:
let d = abs(count - expected)
if d > maxDelta: maxDelta = d
 
let status = if maxDelta <= allowedDelta: "passed" else: "failed"
echo "Checking ", repeat, " values with a tolerance of ", tolerance, "%."
echo "Random generator ", status, " the uniformity test."
echo "Max delta encountered = ", maxDelta, " Allowed delta = ", allowedDelta
 
 
when isMainModule:
import random
randomize()
checkDist(dice7, 1_000_000, 0.5)</syntaxhighlight>
 
{{out}}
<pre>Checking 1000000 values with a tolerance of 0.5%.
Random generator passed the uniformity test.
Max delta encountered = 552 Allowed delta = 714</pre>
 
=={{header|OCaml}}==
<langsyntaxhighlight lang="ocaml">let dice5() = 1 + Random.int 5 ;;
 
let dice7 =
Line 966 ⟶ 1,637:
in
aux
;;</langsyntaxhighlight>
 
=={{header|PARI/GP}}==
<langsyntaxhighlight lang="parigp">dice5()=random(5)+1;
 
dice7()={
Line 975 ⟶ 1,646:
while((t=dice5()*5+dice5()) > 21,);
(t+2)\3
};</langsyntaxhighlight>
 
=={{header|Perl 6Pascal}}==
A console application in Free Pascal, created with the Lazarus IDE.
{{works with|Rakudo Star|2010.09}}
Since rakudo is still pretty slow, we've done some interesting bits of optimization.
We factor out the range object construction so that it doesn't have to be recreated each time, and we sneakily <em>subtract</em> the 1's from the 5's, which takes us back to 0 based without having to subtract 6.
<lang perl6>my $d5 = 1..5;
sub d5() { $d5.roll; } # 1d5
 
The algorithm suggested in the task description requires on average 50/21 (about 2.38) calls to Dice5 for each call to Dice7. See the link in the VBA solution for a discussion on how to reduce this ratio. It cannot be made less than log_5(7) = 1.209062. The algorithm below is based on Rex Kerr's solution, and requires about 1.2185 calls to Dice5 per call to Dice7. Runtime is about 60% of that for the suggested simple algorithm.
sub d7() {
my $flat = 21;
$flat = 5 * d5() - d5() until $flat < 21;
$flat % 7 + 1;
}</lang>
Here's the test. We use a C-style for loop, except it's named <code>loop</code>, because it's currently faster than the other loops--and, er, doesn't segfault the GC on a million iterations...
<lang perl6>my @dist;
my $n = 1_000_000;
my $expect = $n / 7;
 
A chi-squared test can be carried out with the help of statistical tables, and is preferred here to an arbitrary "naive" test.
loop ($_ = $n; $n; --$n) { @dist[d7()]++; }
<syntaxhighlight lang="pascal">
unit UConverter;
(*
Defines a converter object to output uniformly distributed random integers 1..7,
given a source of uniformly distributed random integers 1..5.
*)
interface
 
type
say "Expect\t",$expect.fmt("%.3f");
TFace5 = 1..5;
for @dist.kv -> $i, $v {
TFace7 = 1..7;
say "$i\t$v\t" ~ (($v - $expect)/$expect*100).fmt("%+.2f%%") if $v;
TDice5 = function() : TFace5;
}</lang>
 
And the output:
type TConverter = class( TObject)
<pre>Expect 142857.143
private
1 142835 -0.02%
fDigitBuf: array [0..19] of integer; // holds digits in base 7
2 143021 +0.11%
fBufCount, fBufPtr : integer;
3 142771 -0.06%
fDice5 : TDice5; // passed-in generator for integers 1..5
4 142706 -0.11%
fNrDice5 : int64; // diagnostics, counts calls to fDice5
5 143258 +0.28%
public
6 142485 -0.26%
constructor Create( aDice5 : TDice5);
7 142924 +0.05%</pre>
procedure Reset();
function Dice7() : TFace7;
property NrDice5 : int64 read fNrDice5;
end;
 
implementation
 
constructor TConverter.Create( aDice5 : TDice5);
begin
inherited Create();
fDice5 := aDice5;
self.Reset();
end;
 
procedure TConverter.Reset();
begin
fBufCount := 0;
fBufPtr := 0;
fNrDice5 := 0;
end;
 
function TConverter.Dice7() : TFace7;
var
digit_holder, temp : int64;
j : integer;
begin
if fBufPtr = fBufCount then begin // if no more in buffer
fBufCount := 0;
fBufPtr := 0;
repeat // first time through will usually be enough
// Use supplied fDice5 to generate random 23-digit integer in base 5.
digit_holder := 0;
for j := 0 to 22 do begin
digit_holder := 5*digit_holder + fDice5() - 1;
inc( fNrDice5);
end;
// Convert to 20-digit number in base 7. (A simultaneous DivMod
// procedure would be neater, but isn't available for int64.)
for j := 0 to 19 do begin
temp := digit_holder div 7;
fDigitBuf[j] := digit_holder - 7*temp;
digit_holder := temp;
end;
// Maximum possible is 5^23 - 1, which is 10214646460315315132 in base 7.
// If leading digit in base 7 is 0 then low 19 digits are random.
// Else number begins with 100, 101, or 102; and if with
// 100 or 101 then low 17 digits are random. And so on.
if fDigitBuf[19] = 0 then fBufCount := 19
else if fDigitBuf[17] < 2 then fBufCount := 17
else if fDigitBuf[16] = 0 then fBufCount := 16;
// We could go on but that will do.
until fBufCount > 0;
end; // if no more in buffer
result := fDigitBuf[fBufPtr] + 1;
inc( fBufPtr);
end;
end.
 
program Dice_SevenFromFive;
(*
Demonstrates use of the UConverter unit.
*)
{$mode objfpc}{$H+}
uses
SysUtils, UConverter;
 
function Dice5() : UConverter.TFace5;
begin
result := Random(5) + 1; // Random(5) returns 0..4
end;
 
// Percentage points of the chi-squared distribution, 6 degrees of freedom.
// From New Cambridge Statistical Tables, 2nd edn, pp. 40-41.
const
CHI_SQ_6df_95pc = 1.635;
CHI_SQ_6df_05pc = 12.59;
 
// Main routine
var
nrThrows, j, k : integer;
nrFaces : array [1..7] of integer;
X2, expected, diff : double;
conv : UConverter.TConverter;
begin
conv := UConverter.TConverter.Create( @Dice5);
WriteLn( 'Enter 0 throws to quit');
repeat
WriteLn(''); Write( 'Number of throws (0 to quit): ');
ReadLn( nrThrows);
if nrThrows = 0 then begin
conv.Free();
exit;
end;
conv.Reset(); // clears count of calls to Dice5
for k := 1 to 7 do nrFaces[k] := 0;
for j := 1 to nrThrows do begin
k := conv.Dice7();
inc( nrFaces[k]);
end;
WriteLn('');
WriteLn( SysUtils.Format( 'Number of throws = %10d', [nrThrows]));
WriteLn( SysUtils.Format( 'Calls to Dice5 = %10d', [conv.NrDice5]));
for k := 1 to 7 do
WriteLn( SysUtils.Format( ' Number of %d''s = %10d', [k, nrFaces[k]]));
 
// Calculation of chi-squared
expected := nrThrows/7.0;
X2 := 0.0;
for k := 1 to 7 do begin
diff := nrFaces[k] - expected;
X2 := X2 + diff*diff/expected;
end;
WriteLn( SysUtils.Format( 'X^2 = %0.3f on 6 degrees of freedom', [X2]));
if X2 < CHI_SQ_6df_95pc then WriteLn( 'Too regular at 5% level')
else if X2 > CHI_SQ_6df_05pc then WriteLn( 'Too irregular at 5% level')
else WriteLn( 'Satisfactory at 5% level')
until false;
end.
</syntaxhighlight>
{{out}}
<pre>
Number of throws = 100000000
Calls to Dice5 = 121846341
Number of 1's = 14282807
Number of 2's = 14282277
Number of 3's = 14288393
Number of 4's = 14285486
Number of 5's = 14289379
Number of 6's = 14291053
Number of 7's = 14280605
X^2 = 6.687 on 6 degrees of freedom
Satisfactory at 5% level
</pre>
 
=={{header|Perl}}==
Using dice5 twice to generate numbers in the range 0 to 24. If we consider these modulo 8 and re-call if we get zero, we have eliminated 4 cases and created the necessary number in the range from 1 to 7.
<syntaxhighlight lang="perl">sub dice5 { 1+int rand(5) }
 
sub dice7 {
while(1) {
my $d7 = (5*dice5()+dice5()-6) % 8;
return $d7 if $d7;
}
}
 
my %count7;
my $n = 1000000;
$count7{dice7()}++ for 1..$n;
printf "%s: %5.2f%%\n", $_, 100*($count7{$_}/$n*7-1) for sort keys %count7;
</syntaxhighlight>
{{out}}
<pre>
1: 0.05%
2: 0.16%
3: -0.43%
4: 0.11%
5: 0.01%
6: -0.15%
7: 0.24%
</pre>
 
=={{header|Phix}}==
replace rand7() in [[Verify_distribution_uniformity/Naive#Phix]] with:
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">function</span> <span style="color: #000000;">dice5</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">return</span> <span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">dice7</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dice5</span><span style="color: #0000FF;">()*</span><span style="color: #000000;">5</span><span style="color: #0000FF;">+</span><span style="color: #000000;">dice5</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">3</span> <span style="color: #000080;font-style:italic;">-- ( ie 3..27, but )</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">r</span><span style="color: #0000FF;"><</span><span style="color: #000000;">24</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">/</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #000080;font-style:italic;">-- (only 3..23 useful)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
1000000 iterations: flat
</pre>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de dice5 ()
(rand 1 5) )
 
Line 1,017 ⟶ 1,862:
(use R
(until (> 21 (setq R (+ (* 5 (dice5)) (dice5) -6))))
(inc (% R 7)) ) )</langsyntaxhighlight>
{{out}}
Output:
<pre>: (let R NIL
(do 1000000 (accu 'R (dice7) 1))
Line 1,026 ⟶ 1,871:
=={{header|PureBasic}}==
{{trans|Lua}}
<langsyntaxhighlight PureBasiclang="purebasic">Procedure dice5()
ProcedureReturn Random(4) + 1
EndProcedure
Line 1,039 ⟶ 1,884:
ProcedureReturn x % 7 + 1
EndProcedure</langsyntaxhighlight>
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">from random import randint
 
def dice5():
Line 1,049 ⟶ 1,894:
def dice7():
r = dice5() + dice5() * 5 - 6
return (r % 7) + 1 if r < 21 else dice7()</langsyntaxhighlight>
Distribution check using [[Simple Random Distribution Checker#Python|Simple Random Distribution Checker]]:
<pre>>>> distcheck(dice5, 1000000, 1)
Line 1,056 ⟶ 1,901:
{1: 142853, 2: 142576, 3: 143067, 4: 142149, 5: 143189, 6: 143285, 7: 142881}
</pre>
=={{header|Quackery}}==
 
<syntaxhighlight lang="quackery"> [ 5 random 1+ ] is dice5 ( --> n )
=={{header|Racket}}==
<lang Racket>
#lang racket
(define (dice5) (add1 (random 5)))
 
[ dice5 5 *
(define (dice7)
dice5 + 6 -
(define res (+ (* 5 (dice5)) (dice5) -6))
[ table
(if (< res 21) (+ 1 (modulo res 7)) (dice7)))
0 0 0 0 1
</lang>
1 1 2 2 2
3 3 3 4 4
4 5 5 5 6
6 6 7 7 7 ]
dup 0 = iff
drop again ] is dice7 ( --> n )</syntaxhighlight>
 
{{out}}
Checking the uniformity using math library:
 
<code>distribution</code> is defined at [[Verify distribution uniformity/Naive#Quackery]].
<lang racket>
 
-> (require math/statistics)
<pre>/O> ' dice7 1000000 666 distribution
-> (samples->hash (for/list ([i 700000]) (dice7)))
...
'#hash((7 . 100392)
[ 143196 142815 143451 142716 142964 142300 142558 ]
(6 . 100285)
 
(5 . 99774)
Stack empty.</pre>
(4 . 100000)
(3 . 100000)
(2 . 99927)
(1 . 99622))
</lang>
 
=={{header|R}}==
5-sided die.
<langsyntaxhighlight lang="r">dice5 <- function(n=1) sample(5, n, replace=TRUE)</langsyntaxhighlight>
Simple but slow 7-sided die, using a while loop.
<langsyntaxhighlight lang="r">dice7.while <- function(n=1)
{
score <- numeric()
Line 1,095 ⟶ 1,940:
score
}
system.time(dice7.while(1e6)) # longer than 4 minutes</langsyntaxhighlight>
More complex, but much faster vectorised version.
<langsyntaxhighlight lang="r">dice7.vec <- function(n=1, checkLength=TRUE)
{
morethan2n <- 3 * n + 10 + (n %% 2) #need more than 2*n samples, because some are discarded
Line 1,114 ⟶ 1,959:
} else score
}
system.time(dice7.vec(1e6)) # ~1 sec</langsyntaxhighlight>
 
=={{header|REXXRacket}}==
<syntaxhighlight lang="racket">
<lang rexx>/*REXX program to simulate 7-sided die based on a 5-sided throw. */
#lang racket
parse arg trials sample . /*get arguments from command line*/
(define (dice5) (add1 (random 5)))
if trials=='' then trials=1 /*Not specified? Then use default*/
if sample=='' then sample=1000000 /* " " " " " */
 
(define (dice7)
do t=1 for trials /*performe the number of trials. */
(define res (+ (* 5 (dice5)) (dice5) -6))
die.=0; k=0
(if (< res 21) (+ 1 (modulo res 7)) (dice7)))
do until k==sample; r=5*random(1,5)+random(1,5)-6
</syntaxhighlight>
if r>20 then iterate
k=k+1; r=r//7+1; die.r=die.r+1
end /*until*/
expect=sample%7
say
say center('trial:'right(t,4) ' ' sample 'samples, expect='expect,79,'─')
say
 
Checking the uniformity using math library:
do j=1 for 7
say ' side' j "had " die.j ' occurences',
' difference from expected:'right(die.j-expect,length(sample))
end /*j*/
end /*t*/
/*stick a fork in it, we're done.*/</lang>
'''output''' when the input is specified as <tt>11</tt>:
<pre style="height:30ex;overflow:scroll">
─────────────────trial: 1 1000000 samples, expect=142857─────────────────
 
<syntaxhighlight lang="racket">
side 1 had 142879 occurences difference from expected: 22
-> (require math/statistics)
side 2 had 142980 occurences difference from expected: 123
-> (samples->hash (for/list ([i 700000]) (dice7)))
side 3 had 142366 occurences difference from expected: -491
'#hash((7 . 100392)
side 4 had 143129 occurences difference from expected: 272
(6 . 100285)
side 5 had 143316 occurences difference from expected: 459
(5 . 99774)
side 6 had 142742 occurences difference from expected: -115
(4 . 100000)
side 7 had 142588 occurences difference from expected: -269
(3 . 100000)
(2 . 99927)
(1 . 99622))
</syntaxhighlight>
 
=={{header|Raku}}==
─────────────────trial: 2 1000000 samples, expect=142857─────────────────
(formerly Perl 6)
{{works with|Rakudo|2018.03}}
 
<syntaxhighlight lang="raku" line>my $d5 = 1..5;
side 1 had 142583 occurences difference from expected: -274
sub d5() { $d5.roll; } # 1d5
side 2 had 142797 occurences difference from expected: -60
side 3 had 143093 occurences difference from expected: 236
side 4 had 142168 occurences difference from expected: -689
side 5 had 143203 occurences difference from expected: 346
side 6 had 143260 occurences difference from expected: 403
side 7 had 142896 occurences difference from expected: 39
 
sub d7() {
─────────────────trial: 3 1000000 samples, expect=142857─────────────────
my $flat = 21;
$flat = 5 * d5() - d5() until $flat < 21;
$flat % 7 + 1;
}
 
# Testing
side 1 had 143089 occurences difference from expected: 232
my @dist;
side 2 had 142815 occurences difference from expected: -42
my $n = 1_000_000;
side 3 had 142645 occurences difference from expected: -212
my $expect = $n / 7;
side 4 had 142959 occurences difference from expected: 102
side 5 had 142764 occurences difference from expected: -93
side 6 had 143205 occurences difference from expected: 348
side 7 had 142523 occurences difference from expected: -334
 
loop ($_ = $n; $n; --$n) { @dist[d7()]++; }
─────────────────trial: 4 1000000 samples, expect=142857─────────────────
 
say "Expect\t",$expect.fmt("%.3f");
side 1 had 142535 occurences difference from expected: -322
for @dist.kv -> $i, $v {
side 2 had 142316 occurences difference from expected: -541
say "$i\t$v\t" ~ (($v - $expect)/$expect*100).fmt("%+.2f%%") if $v;
side 3 had 143101 occurences difference from expected: 244
}</syntaxhighlight>
side 4 had 143159 occurences difference from expected: 302
{{out}}
side 5 had 143130 occurences difference from expected: 273
<pre>Expect 142857.143
side 6 had 142551 occurences difference from expected: -306
1 143088 +0.16%
side 7 had 143208 occurences difference from expected: 351
2 143598 +0.52%
3 141741 -0.78%
4 142832 -0.02%
5 143040 +0.13%
6 142988 +0.09%
7 142713 -0.10%
</pre>
 
=={{header|REXX}}==
<syntaxhighlight lang="rexx">/*REXX program simulates a 7─sided die based on a 5─sided throw for a number of trials. */
parse arg trials sample seed . /*obtain optional arguments from the CL*/
if trials=='' | trials="," then trials= 1 /*Not specified? Then use the default.*/
if sample=='' | sample="," then sample= 1000000 /* " " " " " " */
if datatype(seed, 'W') then call random ,,seed /*Integer? Then use it as a RAND seed.*/
L= length(trials) /* [↑] one million samples to be used.*/
 
do #=1 for trials; die.= 0 /*performs the number of desired trials*/
─────────────────trial: 5 1000000 samples, expect=142857─────────────────
k= 0
do until k==sample; r= 5 * random(1, 5) + random(1, 5) - 6
if r>20 then iterate
k= k + 1; r= r // 7 + 1; die.r= die.r + 1
end /*until*/
say
expect= sample % 7
say center('trial:' right(#, L) " " sample 'samples, expect' expect, 80, "─")
 
side 1 had 143335 occurences do j=1 for difference from expected: 4787
say ' side' 2 j "had " 142296 occurencesdie.j difference from expected: ' -561occurrences',
side 3 had 142500 occurences ' difference from expected:'right(die.j - expect, -357length(sample) )
side 4 had 142775 occurences end difference from expected: -82/*j*/
end /*#*/ /*stick a fork in it, we're all done. */</syntaxhighlight>
side 5 had 142581 occurences difference from expected: -276
{{out|output|text=&nbsp; when using the input of: &nbsp; &nbsp; <tt> 11 </tt>}}
side 6 had 143363 occurences difference from expected: 506
side 7 had 143150 occurences difference from expected: 293
 
<br>(Shown at five-sixth size.)
─────────────────trial: 6 1000000 samples, expect=142857─────────────────
 
<pre style="font-size:84%;height:71ex">
side 1 had 142593 occurences difference from expected: -264
──────────────────trial: 1 1000000 samples, expect 142857──────────────────
side 2 had 143012 occurences difference from expected: 155
side 31 had 142703142076 occurencesoccurrences difference from expected: -154781
side 42 had 143702143053 occurencesoccurrences difference from expected: 845196
side 53 had 142867142342 occurencesoccurrences difference from expected: 10-515
side 64 had 142158142633 occurencesoccurrences difference from expected: -699224
side 75 had 142965143024 occurencesoccurrences difference from expected: 108167
side 6 had 143827 occurrences difference from expected: 970
side 7 had 143045 occurrences difference from expected: 188
 
─────────────────trial──────────────────trial: 72 1000000 samples, expect=142857───────────────── 142857──────────────────
side 1 had 143470 occurrences difference from expected: 613
side 2 had 142998 occurrences difference from expected: 141
side 3 had 142654 occurrences difference from expected: -203
side 4 had 142545 occurrences difference from expected: -312
side 5 had 142452 occurrences difference from expected: -405
side 6 had 143144 occurrences difference from expected: 287
side 7 had 142737 occurrences difference from expected: -120
 
──────────────────trial: 3 1000000 samples, expect 142857──────────────────
side 1 had 143065 occurences difference from expected: 208
side 21 had 142892142773 occurencesoccurrences difference from expected: 35-84
side 32 had 142681143198 occurencesoccurrences difference from expected: -176 341
side 43 had 142637142296 occurencesoccurrences difference from expected: -220561
side 54 had 142563142804 occurencesoccurrences difference from expected: -29453
side 65 had 142934142897 occurencesoccurrences difference from expected: 7740
side 76 had 143228142382 occurencesoccurrences difference from expected: 371-475
side 7 had 143650 occurrences difference from expected: 793
 
─────────────────trial──────────────────trial: 84 1000000 samples, expect=142857───────────────── 142857──────────────────
side 1 had 143150 occurrences difference from expected: 293
side 2 had 142635 occurrences difference from expected: -222
side 3 had 142763 occurrences difference from expected: -94
side 4 had 142853 occurrences difference from expected: -4
side 5 had 143132 occurrences difference from expected: 275
side 6 had 142403 occurrences difference from expected: -454
side 7 had 143064 occurrences difference from expected: 207
 
──────────────────trial: 5 1000000 samples, expect 142857──────────────────
side 1 had 142745 occurences difference from expected: -112
side 21 had 142906143041 occurencesoccurrences difference from expected: 49184
side 32 had 142894142701 occurencesoccurrences difference from expected: 37-156
side 43 had 142976143416 occurencesoccurrences difference from expected: 119559
side 54 had 142265142097 occurencesoccurrences difference from expected: -592760
side 65 had 142909142451 occurencesoccurrences difference from expected: 52-406
side 76 had 143305143332 occurencesoccurrences difference from expected: 448475
side 7 had 142962 occurrences difference from expected: 105
 
─────────────────trial──────────────────trial: 96 1000000 samples, expect=142857───────────────── 142857──────────────────
side 1 had 142502 occurrences difference from expected: -355
side 2 had 142429 occurrences difference from expected: -428
side 3 had 143146 occurrences difference from expected: 289
side 4 had 142791 occurrences difference from expected: -66
side 5 had 143271 occurrences difference from expected: 414
side 6 had 143415 occurrences difference from expected: 558
side 7 had 142446 occurrences difference from expected: -411
 
──────────────────trial: 7 1000000 samples, expect 142857──────────────────
side 1 had 142320 occurences difference from expected: -537
side 21 had 142510142700 occurencesoccurrences difference from expected: -347157
side 32 had 142867142691 occurencesoccurrences difference from expected: 10-166
side 43 had 143711143067 occurencesoccurrences difference from expected: 854210
side 54 had 142732141562 occurencesoccurrences difference from expected: -1251295
side 65 had 143115143316 occurencesoccurrences difference from expected: 258459
side 76 had 142745143150 occurencesoccurrences difference from expected: -112 293
side 7 had 143514 occurrences difference from expected: 657
 
─────────────────trial──────────────────trial: 108 1000000 samples, expect=142857───────────────── 142857──────────────────
side 1 had 142362 occurrences difference from expected: -495
side 2 had 143298 occurrences difference from expected: 441
side 3 had 142639 occurrences difference from expected: -218
side 4 had 142811 occurrences difference from expected: -46
side 5 had 143275 occurrences difference from expected: 418
side 6 had 142765 occurrences difference from expected: -92
side 7 had 142850 occurrences difference from expected: -7
 
──────────────────trial: 9 1000000 samples, expect 142857──────────────────
side 1 had 142725 occurences difference from expected: -132
side 21 had 142865143508 occurencesoccurrences difference from expected: 8651
side 32 had 143076142650 occurencesoccurrences difference from expected: 219-207
side 43 had 142759142614 occurencesoccurrences difference from expected: -98243
side 54 had 142593142916 occurencesoccurrences difference from expected: -264 59
side 65 had 142750142944 occurencesoccurrences difference from expected: -107 87
side 76 had 143232143129 occurencesoccurrences difference from expected: 375272
side 7 had 142239 occurrences difference from expected: -618
 
──────────────────trial: 10 1000000 samples, expect 142857──────────────────
─────────────────trial: 11 1000000 samples, expect=142857─────────────────
side 1 had 142455 occurrences difference from expected: -402
side 2 had 143112 occurrences difference from expected: 255
side 3 had 143435 occurrences difference from expected: 578
side 4 had 142704 occurrences difference from expected: -153
side 5 had 142376 occurrences difference from expected: -481
side 6 had 142721 occurrences difference from expected: -136
side 7 had 143197 occurrences difference from expected: 340
 
──────────────────trial: 11 1000000 samples, expect 142857──────────────────
side 1 had 142825 occurences difference from expected: -32
side 21 had 142870142967 occurencesoccurrences difference from expected: 13110
side 32 had 142919142204 occurencesoccurrences difference from expected: 62-653
side 43 had 143098142993 occurencesoccurrences difference from expected: 241136
side 54 had 142627142797 occurencesoccurrences difference from expected: -23060
side 65 had 143163143081 occurencesoccurrences difference from expected: 306224
side 76 had 142498142711 occurencesoccurrences difference from expected: -359146
side 7 had 143247 occurrences difference from expected: 390
</pre>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
# Project : Seven-sided dice from five-sided dice
 
for n = 1 to 20
d = dice7()
see "" + d + " "
next
see nl
 
func dice7()
x = dice5() * 5 + dice5() - 6
if x > 20
return dice7()
ok
dc = x % 7 + 1
return dc
 
func dice5()
rnd = random(4) + 1
return rnd
</syntaxhighlight>
Output:
<pre>
7 6 3 5 2 2 7 1 2 7 3 7 4 4 4 2 3 2 6 1
</pre>
 
=={{header|RPL}}==
<code>UNIF?</code> is defined at [[Verify distribution uniformity/Naive#RPL|Verify distribution uniformity/Naive]]
{{works with|Halcyon Calc|4.2.7}}
≪ ≪ RAND 5 * CEIL ≫ → dice5
≪ '''WHILE'''
dice5 EVAL 5 *
dice5 EVAL 6 - +
DUP 21 ≥
'''REPEAT''' DROP '''END'''
7 MOD 1 +
≫ ≫ '<span style="color:blue">DICE7</span>' STO
 
≪ <span style="color:blue">DICE7</span> ≫ 100000 .1 <span style="color:blue">UNIF?</span>
{{out}}
<pre>
1: [ 14557 14245 14255 14400 14224 14151 14168 ]
</pre>
Watchdog timer limits the loop to 100,000 items.
 
=={{header|Ruby}}==
{{trans|Tcl}}
Uses <code>distcheck</code> from [[Simple_Random_Distribution_Checker#Ruby|here]].
<langsyntaxhighlight lang="ruby">require './distcheck.rb'
 
def d5
Line 1,263 ⟶ 2,205:
def d7
loop do
d55 = 5*d5() + d5() - 6
return (d55 % 7 + 1) if d55 < 21
end
Line 1,269 ⟶ 2,211:
 
distcheck(1_000_000) {d5}
distcheck(1_000_000) {d7}</langsyntaxhighlight>
 
{{out}}
output
<pre>1 200227
<pre>1 200478 2 199986 3 199582 4 199560 5 200394
2 200264
1 142371 2 142577 3 143328 4 143630 5 142553 6 142692 7 142849 </pre>
3 199777
4 199387
5 200345
1 143175
2 143031
3 142731
4 142716
5 142931
6 142605
7 142811</pre>
 
=={{header|Scala}}==
{{Out}}Best seen running in your browser either by [https://scalafiddle.io/sf/3RNtNEC/0 ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/Y5qSeW52QiC40l5vJCUMRA Scastie (remote JVM)].
<syntaxhighlight lang="scala">import scala.util.Random
 
object SevenSidedDice extends App {
private val rnd = new Random
 
private def seven = {
var v = 21
 
def five = 1 + rnd.nextInt(5)
 
while (v > 20) v = five + five * 5 - 6
1 + v % 7
}
 
println("Random number from 1 to 7: " + seven)
 
}</syntaxhighlight>
 
=={{header|Sidef}}==
{{trans|Perl}}
<syntaxhighlight lang="ruby">func dice5 { 1 + 5.rand.int }
 
func dice7 {
loop {
var d7 = ((5*dice5() + dice5() - 6) % 8);
d7 && return d7;
}
}
 
var count7 = Hash.new;
 
var n = 1e6;
n.times { count7{dice7()} := 0 ++ }
count7.keys.sort.each { |k|
printf("%s: %5.2f%%\n", k, 100*(count7{k}/n * 7 - 1));
}</syntaxhighlight>
{{out}}
<pre>1: -0.00%
2: 0.02%
3: 0.23%
4: 0.42%
5: -0.23%
6: -0.54%
7: 0.10%</pre>
 
=={{header|Tcl}}==
Any old D&D hand will know these as a D5 and a D7...
<langsyntaxhighlight lang="tcl">proc D5 {} {expr {1 + int(5 * rand())}}
 
proc D7 {} {
Line 1,286 ⟶ 2,285:
}
}
}</langsyntaxhighlight>
Checking:
<span class="sy0">%</span> distcheck D5 <span class="nu0">1000000</span>
Line 1,292 ⟶ 2,291:
<span class="sy0">%</span> distcheck D7 <span class="nu0">1000000</span>
1 143121 2 142383 3 143353 4 142811 5 142172 6 143291 7 142869
 
=={{header|VBA}}==
The original StackOverflow page doesn't exist any longer. Luckily [https://web.archive.org/web/20100730055051/http://stackoverflow.com:80/questions/137783/given-a-function-which-produces-a-random-integer-in-the-range-1-to-5-write-a-fun archive.org] exists.
<syntaxhighlight lang="vb">Private Function Test4DiscreteUniformDistribution(ObservationFrequencies() As Variant, Significance As Single) As Boolean
'Returns true if the observed frequencies pass the Pearson Chi-squared test at the required significance level.
Dim Total As Long, Ei As Long, i As Integer
Dim ChiSquared As Double, DegreesOfFreedom As Integer, p_value As Double
Debug.Print "[1] ""Data set:"" ";
For i = LBound(ObservationFrequencies) To UBound(ObservationFrequencies)
Total = Total + ObservationFrequencies(i)
Debug.Print ObservationFrequencies(i); " ";
Next i
DegreesOfFreedom = UBound(ObservationFrequencies) - LBound(ObservationFrequencies)
'This is exactly the number of different categories minus 1
Ei = Total / (DegreesOfFreedom + 1)
For i = LBound(ObservationFrequencies) To UBound(ObservationFrequencies)
ChiSquared = ChiSquared + (ObservationFrequencies(i) - Ei) ^ 2 / Ei
Next i
p_value = 1 - WorksheetFunction.ChiSq_Dist(ChiSquared, DegreesOfFreedom, True)
Debug.Print
Debug.Print "Chi-squared test for given frequencies"
Debug.Print "X-squared ="; Format(ChiSquared, "0.0000"); ", ";
Debug.Print "df ="; DegreesOfFreedom; ", ";
Debug.Print "p-value = "; Format(p_value, "0.0000")
Test4DiscreteUniformDistribution = p_value > Significance
End Function
Private Function Dice5() As Integer
Dice5 = Int(5 * Rnd + 1)
End Function
Private Function Dice7() As Integer
Dim i As Integer
Do
i = 5 * (Dice5 - 1) + Dice5
Loop While i > 21
Dice7 = i Mod 7 + 1
End Function
Sub TestDice7()
Dim i As Long, roll As Integer
Dim Bins(1 To 7) As Variant
For i = 1 To 1000000
roll = Dice7
Bins(roll) = Bins(roll) + 1
Next i
Debug.Print "[1] ""Uniform? "; Test4DiscreteUniformDistribution(Bins, 0.05); """"
End Sub</syntaxhighlight>
{{out}}<pre>[1] "Data set:" 142418 142898 142940 142573 143030 143139 143002
Chi-squared test for given frequencies
X-squared =2.8870, df = 6 , p-value = 0.8229
[1] "Uniform? True"
</pre>
 
=={{header|VBScript}}==
<langsyntaxhighlight lang="vb">Option Explicit
 
function dice5
Line 1,306 ⟶ 2,355:
loop until j < 21
dice7 = j mod 7 + 1
end function</langsyntaxhighlight>
 
=={{header|Verilog}}==
<syntaxhighlight lang="verilog">
 
///////////////////////////////////////////////////////////////////////////////
/// seven_sided_dice_tb : (testbench) ///
/// Check the distribution of the output of a seven sided dice circuit ///
///////////////////////////////////////////////////////////////////////////////
module seven_sided_dice_tb;
reg [31:0] freq[0:6];
reg clk;
wire [2:0] dice_face;
reg req;
wire valid_roll;
integer i;
initial begin
clk <= 0;
forever begin
#1;
clk <= ~clk;
end
end
initial begin
req <= 1'b1;
for(i = 0; i < 7; i = i + 1) begin
freq[i] <= 32'b0;
end
repeat(10) @(posedge clk);
repeat(7000000) begin
@(posedge clk);
while(~valid_roll) begin
@(posedge clk);
end
freq[dice_face] <= freq[dice_face] + 32'b1;
end
$display("********************************************");
$display("*** Seven sided dice distribution: ");
$display(" Theoretical distribution is an uniform ");
$display(" distribution with (1/7)-probability ");
$display(" for each possible outcome, ");
$display(" The experimental distribution is: ");
for(i = 0; i < 7; i = i + 1) begin
if(freq[i] < 32'd1_000_000) begin
$display("%d with probability 1/7 - (%d ppm)", i, (32'd1_000_000 - freq[i])/7);
end
else begin
$display("%d with probability 1/7 + (%d ppm)", i, (freq[i] - 32'd1_000_000)/7);
end
end
$finish;
end
 
seven_sided_dice DUT(
.clk(clk),
.req(req),
.valid_roll(valid_roll),
.dice_face(dice_face)
);
endmodule
///////////////////////////////////////////////////////////////////////////////
/// seven_sided_dice : ///
/// Synthsizeable module that using a 5 sided dice as a black box ///
/// is able to reproduce the outcomes if a 7-sided dice ///
///////////////////////////////////////////////////////////////////////////////
module seven_sided_dice(
input wire clk,
input wire req,
output reg valid_roll,
output reg [2:0] dice_face
);
wire [2:0] face1;
wire [2:0] face2;
reg [4:0] combination;
reg req_p1;
reg req_p2;
reg req_p3;
always @(posedge clk) begin
req_p1 <= req;
req_p2 <= req_p1;
end
always @(posedge clk) begin
if(req_p1) begin
combination <= face1 + face2 + {face2, 2'b00};
end
if(req_p2) begin
case(combination)
5'd0, 5'd1, 5'd2: {valid_roll, dice_face} <= {1'b1, 3'd0};
5'd3, 5'd4, 5'd5: {valid_roll, dice_face} <= {1'b1, 3'd1};
5'd6, 5'd7, 5'd8: {valid_roll, dice_face} <= {1'b1, 3'd2};
5'd9, 5'd10, 5'd11: {valid_roll, dice_face} <= {1'b1, 3'd3};
5'd12, 5'd13, 5'd14: {valid_roll, dice_face} <= {1'b1, 3'd4};
5'd15, 5'd16, 5'd17: {valid_roll, dice_face} <= {1'b1, 3'd5};
5'd18, 5'd19, 5'd20: {valid_roll, dice_face} <= {1'b1, 3'd6};
default: valid_roll <= 1'b0;
endcase
end
end
 
five_sided_dice dice1(
.clk(clk),
.req(req),
.dice_face(face1)
);
 
five_sided_dice dice2(
.clk(clk),
.req(req),
.dice_face(face2)
);
endmodule
 
///////////////////////////////////////////////////////////////////////////////
/// five_sided_dice : ///
/// A model of the five sided dice component ///
///////////////////////////////////////////////////////////////////////////////
module five_sided_dice(
input wire clk,
input wire req,
output reg [2:0] dice_face
);
always @(posedge clk) begin
if(req) begin
dice_face <= $urandom % 5;
end
end
endmodule
</syntaxhighlight>
 
Compiling with Icarus Verilog
<pre>
> iverilog seven-sided-dice.v -o seven-sided-dice
</pre>
Running the test
<pre>
> vvp seven-sided-dice
********************************************
*** Seven sided dice distribution:
Theoretical distribution is an uniform
distribution with (1/7)-probability
for each possible outcome,
The experimental distribution is:
0 with probability 1/7 + ( 67 ppm)
1 with probability 1/7 - ( 47 ppm)
2 with probability 1/7 + ( 92 ppm)
3 with probability 1/7 - ( 17 ppm)
4 with probability 1/7 - ( 36 ppm)
5 with probability 1/7 + ( 51 ppm)
6 with probability 1/7 - ( 109 ppm)
</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-sort}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "random" for Random
import "./sort" for Sort
import "./fmt" for Fmt
 
var r = Random.new()
 
var dice5 = Fn.new { r.int(1, 6) }
 
var dice7 = Fn.new {
while (true) {
var t = (dice5.call() - 1) * 5 + dice5.call() - 1
if (t < 21) return 1 + (t/3).floor
}
}
 
var checkDist = Fn.new { |gen, nRepeats, tolerance|
var occurs = {}
for (i in 1..nRepeats) {
var d = gen.call()
occurs[d] = occurs.containsKey(d) ? occurs[d] + 1 : 1
}
var expected = (nRepeats/occurs.count).floor
var maxError = (expected * tolerance / 100).floor
System.print("Repetitions = %(nRepeats), Expected = %(expected)")
System.print("Tolerance = %(tolerance)\%, Max Error = %(maxError)\n")
System.print("Integer Occurrences Error Acceptable")
var f = " $d $5d $5d $s"
var allAcceptable = true
var cmp = Fn.new { |me1, me2| (me1.key - me2.key).sign }
occurs = occurs.toList
Sort.insertion(occurs, cmp)
for (me in occurs) {
var k = me.key
var v = me.value
var error = (v - expected).abs
var acceptable = (error <= maxError) ? "Yes" : "No"
if (acceptable == "No") allAcceptable = false
Fmt.print(f, k, v, error, acceptable)
}
System.print("\nAcceptable overall: %(allAcceptable ? "Yes" : "No")")
}
 
checkDist.call(dice7, 1400000, 0.5)</syntaxhighlight>
 
{{out}}
<pre>
Repetitions = 1400000, Expected = 200000
Tolerance = 0.5%, Max Error = 1000
 
Integer Occurrences Error Acceptable
1 199744 256 Yes
2 199678 322 Yes
3 200254 254 Yes
4 199903 97 Yes
5 200080 80 Yes
6 200070 70 Yes
7 200271 271 Yes
 
Acceptable overall: Yes
</pre>
 
=={{header|zkl}}==
<syntaxhighlight lang="zkl">var die5=(1).random.fp(6); // [1..5]
fcn die7{ while((r:=5*die5() + die5())>=27){} r/3-1 }
 
fcn rtest(N){ //test spread over [0..9]
dist:=L(0,0,0,0,0,0,0,0,0,0);
do(N){ dist[die7()]+=1 }
sum:=dist.sum();
dist=dist.apply('wrap(n){ "%.2f%%".fmt(n.toFloat()/sum*100) }).println();
}
 
println("Looking for ",100.0/7,"%");
rtest(0d1_000_000);</syntaxhighlight>
{{out}}
<pre>
Looking for 14.2857%
L("0.00%","14.28%","14.36%","14.22%","14.26%","14.34%","14.33%","14.21%","0.00%","0.00%")
</pre>
2,058

edits