Probabilistic choice: Difference between revisions
Added Easylang
(Added AppleScript.) |
(Added Easylang) |
||
(20 intermediate revisions by 13 users not shown) | |||
Line 19:
=={{header|Ada}}==
<
with Ada.Text_IO; use Ada.Text_IO;
Line 52:
end if;
end loop;
end Random_Distribution;</
Sample output:
<pre>
Line 72:
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny]}}
{{wont work 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] - due to extensive use of FORMATted transput}}
<
MODE LREAL = LONG REAL;
Line 143:
FOR i FROM LWB items TO UPB items DO printf(($f(real repr)" "$, prob count OF items[i]/trials)) OD;
printf($l$)
)</
Sample output:
<pre>
Line 155:
AppleScript does have a <tt>random number</tt> command, but this is located in the StandardAdditions OSAX and invoking it a million times can take quite a while. Since Mac OS X 10.11, it's been possible to use the randomising features of the system's "GameplayKit" framework, which are faster to access.
<
use framework "Foundation"
use framework "GameplayKit"
Line 216:
end task
task()</
{{output}}
<
{|item|:aleph, probability:0.2, actual:0.20033}, ¬
{|item|:beth, probability:0.166666666667, actual:0.166744}, ¬
Line 228:
{|item|:zayin, probability:0.090909090909, actual:0.090721}, ¬
{|item|:heth, probability:0.063455988456, actual:0.063817} ¬
}"</
=={{header|Arturo}}==
<syntaxhighlight lang="rebol">nofTrials: 10000
probabilities: #[
aleph: to :rational [1 5]
beth: to :rational [1 6]
gimel: to :rational [1 7]
daleth: to :rational [1 8]
he: to :rational [1 9]
waw: to :rational [1 10]
zayin: to :rational [1 11]
heth: to :rational [1759 27720]
]
samples: #[]
loop 1..nofTrials 'x [
z: random 0.0 1.0
loop probabilities [item,prob][
if? z < prob [
unless key? samples item -> samples\[item]: 0
samples\[item]: samples\[item] + 1
break
]
else [
z: z - prob
]
]
]
[s1, s2]: 0.0
print [pad.right "Item" 10 pad "Target" 10 pad "Tesults" 10 pad "Differences" 15]
print repeat "-" 50
loop probabilities [item,prob][
r: samples\[item] // nofTrials
s1: s1 + r*100
s2: s2 + prob*100
print [
pad.right item 10
pad to :string prob 10
pad to :string round.to:4 r 10
pad to :string round.to:4 to :floating 100*1-r//prob 13 "%"
]
]
print repeat "-" 50
print [
pad.right "Total:" 10
pad to :string to :floating s2 10
pad to :string s1 10
]</syntaxhighlight>
{{out}}
<pre>Item Target Tesults Differences
--------------------------------------------------
aleph 1/5 0.1954 2.3 %
beth 1/6 0.1654 0.76 %
gimel 1/7 0.1397 2.21 %
daleth 1/8 0.1234 1.28 %
he 1/9 0.112 -0.8 %
waw 1/10 0.1032 -3.2 %
zayin 1/11 0.0946 -4.06 %
heth 1759/27720 0.0663 -4.4819 %
--------------------------------------------------
Total: 100.0 100.0</pre>
=={{header|AutoHotkey}}==
contributed by Laszlo on the ahk [http://www.autohotkey.com/forum/post-276279.html#276279 forum]
<
s2 := "beth", p2 := 1/6.0
s3 := "gimel", p3 := 1/7.0
Line 270 ⟶ 338:
heth 0.063456 0.063342
---------------------------
*/</
=={{header|AWK}}==
<
BEGIN {
Line 346 ⟶ 414:
counts[sym] = 0;
}
</syntaxhighlight>
Example output:
Line 364 ⟶ 432:
Rounding off makes the results look perfect.
=={{header|BASIC256}}==
{{trans|FreeBASIC}}
<syntaxhighlight lang="basic256">dim letters$ = {"aleph", "beth", "gimel", "daleth", "he", "waw", "zayin", "heth"}
dim actual(8) fill 0 ## all zero by default
dim probs = {1/5.0, 1/6.0, 1/7.0, 1/8.0, 1/9.0, 1/10.0, 1/11.0, 0}
dim cumProbs(8)
cumProbs[0] = probs[0]
for i = 1 to 6
cumProbs[i] = cumProbs[i - 1] + probs[i]
next i
cumProbs[7] = 1.0
probs[7] = 1.0 - cumProbs[6]
n = 1000000
sum = 0.0
for i = 1 to n
rnd = rand ## random number where 0 <= rand < 1
begin case
case rnd <= cumProbs[0]
actual[0] += 1
case rnd <= cumProbs[1]
actual[1] += 1
case rnd <= cumProbs[2]
actual[2] += 1
case rnd <= cumProbs[3]
actual[3] += 1
case rnd <= cumProbs[4]
actual[4] += 1
case rnd <= cumProbs[5]
actual[5] += 1
case rnd <= cumProbs[6]
actual[6] += 1
else
actual[7] += 1
end case
next i
sumActual = 0
print "Letter", " Actual", "Expected"
print "------", "--------", "--------"
for i = 0 to 7
print ljust(letters$[i],14," ");
print ljust(actual[i]/n,8,"0"); " ";
sumActual += actual[i]/n
print ljust(probs[i],8,"0")
next i
print " ", "--------", "--------"
print " ", ljust(sumActual,8,"0"), "1.000000"
end</syntaxhighlight>
=={{header|BBC BASIC}}==
<
item$() = "aleph","beth","gimel","daleth","he","waw","zayin","heth"
prob() = 1/5.0, 1/6.0, 1/7.0, 1/8.0, 1/9.0, 1/10.0, 1/11.0, 1759/27720
Line 384 ⟶ 506:
FOR i% = 0 TO DIM(item$(),1)
PRINT item$(i%), cnt%(i%)/1E6, prob(i%)
NEXT</
'''Output:'''
<pre>
Line 399 ⟶ 521:
=={{header|C}}==
<
#include <stdlib.h>
Line 432 ⟶ 554:
return 0;
}</
aleph 199928 19.9928% 20.0000%
beth 166489 16.6489% 16.6667%
Line 440 ⟶ 562:
waw 99935 9.9935% 10.0000%
zayin 91001 9.1001% 9.0909%
heth 63330 6.3330% 6.3456%</
=={{header|C sharp|C#}}==
Line 446 ⟶ 568:
{{trans|Java}}
<
using System;
Line 518 ⟶ 640:
}
}
</syntaxhighlight>
Output:
Line 528 ⟶ 650:
=={{header|C++}}==
<
#include <iostream>
#include <vector>
Line 579 ⟶ 701:
}
return 0 ;
}</
Output:
<PRE>letter frequency attained frequency expected
Line 597 ⟶ 719:
It uses the language built-in (frequencies) to count the number of occurrences of each distinct name. Note that while we actually generate a sequence of num-trials random samples, the sequence is lazily generated and lazily consumed. This means that the program will scale to an arbitrarily-large num-trials with no ill effects, by throwing away elements it's already processed.
<
(reduce
(fn [acc n] (conj acc (+ (or (last acc) 0) n)))
Line 618 ⟶ 740:
(doseq [[idx exp] expected]
(println "Expected number of" (*names* idx) "was"
(* num-trials exp) "and actually got" (actual idx))))</
<pre>Expected number of aleph was 200000.0 and actually got 199300
Line 632 ⟶ 754:
This is a straightforward, if a little verbose implementation based upon the Perl one.
<
(beth 1/6)
(gimel 1/7)
Line 677 ⟶ 799:
WAW 0.100068 0.1
ZAYIN 0.090458 0.09090909
HETH 0.063481 0.06345599</
=={{header|D}}==
===Basic Version===
<
import std.stdio, std.random, std.string, std.range;
Line 695 ⟶ 817:
foreach (name, p, co; zip(items, pr, counts[]))
writefln("%-7s %.8f %.8f", name, p, co / nTrials);
}</
{{out}}
<pre>Item Target prob Attained prob
Line 708 ⟶ 830:
===A Faster Version===
<
import std.stdio, std.random, std.algorithm, std.range;
Line 728 ⟶ 850:
foreach (name, p, co; zip(items, pr, counts[]))
writefln("%-7s %.8f %.8f", name, p, co / nTrials);
}</
=={{header|E}}==
Line 736 ⟶ 858:
It is rather verbose, due to using the tree rather than a linear search, and having code to print the tree (which was used to debug it).
<
First, the algorithm:
<
def leaf(value) {
return def leaf {
Line 794 ⟶ 916:
}
}
}</
Then the test setup:
<
"aleph" => 1/5,
"beth" => 1/6.0,
Line 819 ⟶ 941:
for item in probTable.domain() {
stdout.print(item, "\t", timesFound[item] / trials, "\t", probTable[item], "\n")
}</
=={{header|EasyLang}}==
<syntaxhighlight>
name$[] = [ "aleph " "beth " "gimel " "daleth" "he " "waw " "zayin " "heth " ]
probs[] = [ 1 / 5 1 / 6 1 / 7 1 / 8 1 / 9 1 / 10 1 / 11 0 ]
for i = 1 to 7
cum += probs[i]
cum[] &= cum
.
cum[] &= 1
probs[8] = 1 - cum[7]
len act[] 8
n = 1000000
for i to n
h = randomf
j = 1
while h > cum[j]
j += 1
.
act[j] += 1
.
print "Name Ratio Expected"
print "---------------------"
numfmt 4 6
for i to 8
print name$[i] & " " & act[i] / n & " " & probs[i]
.
</syntaxhighlight>
{{out}}
<pre>
Name Ratio Expected
---------------------
aleph 0.2000 0.2000
beth 0.1661 0.1667
gimel 0.1424 0.1429
daleth 0.1252 0.1250
he 0.1111 0.1111
waw 0.1003 0.1000
zayin 0.0913 0.0909
heth 0.0637 0.0635
</pre>
=={{header|Elixir}}==
{{trans|Erlang}}
<
@tries 1000000
@probs [aleph: 1/5,
Line 849 ⟶ 1,013:
end
Probabilistic.test</
{{out}}
Line 868 ⟶ 1,032:
The optimized version of Java.
<
-module(probabilistic_choice).
Line 900 ⟶ 1,064:
get_choice(T,Ran - Prob)
end.
</syntaxhighlight>
Output:
Line 916 ⟶ 1,080:
=={{header|ERRE}}==
<
DIM ITEM$[7],PROB[7],CNT[7]
Line 950 ⟶ 1,114:
END FOR
END IF
END PROGRAM</
Output:
Line 969 ⟶ 1,133:
=={{header|Euphoria}}==
{{trans|PureBasic}}
<
constant times = 1e6
atom d,e
Line 1,001 ⟶ 1,165:
printf(1,"%-7s should be %f is %f | Deviatation %6.3f%%\n",
{Mapps[j][1],Mapps[j][2],d,(1-Mapps[j][2]/d)*100})
end for</
Output:
Line 1,016 ⟶ 1,180:
=={{header|Factor}}==
<
math.statistics prettyprint quotations sequences sorting formatting ;
IN: rosettacode.proba
Line 1,052 ⟶ 1,216:
: example ( # data -- )
[ case-probas generate-normalized ]
[ summarize ] bi ; inline</
In a REPL:
<syntaxhighlight lang="text">USE: rosettacode.proba
1000000 data example</
outputs
<syntaxhighlight lang="text"> Key Value expected
heth: 0.063469 0.063456
waw: 0.100226 0.100000
Line 1,066 ⟶ 1,230:
he: 0.110562 0.111111
aleph: 0.199868 0.200000
gimel: 0.142961 0.142857</
=={{header|Fermat}}==
<syntaxhighlight lang="fermat">
trials:=1000000;
Array probs[8]; {store the probabilities}
[probs]:=[<i=1,8> 1/(i+4)];
probs[8]:=1-Sigma<i=1,7>[probs[i,1]];
Func Round( a, b ) = (2*a+b)\(2*b).; {rounds a fraction with numerator a and denominator b}
; {to the nearest integer (positive fractions only)}
Func Sel = {select a number from 1 to 8 according to the}
r:=Rand|27720; {specified probabilities}
if r < probs[1]*27720 then Return(1) fi;
if r < Sigma<i=1,2>[probs[i]]*27720 then Return(2) fi;
if r < Sigma<i=1,3>[probs[i]]*27720 then Return(3) fi;
if r < Sigma<i=1,4>[probs[i]]*27720 then Return(4) fi;
if r < Sigma<i=1,5>[probs[i]]*27720 then Return(5) fi;
if r < Sigma<i=1,6>[probs[i]]*27720 then Return(6) fi;
if r < Sigma<i=1,7>[probs[i]]*27720 then Return(7) fi;
Return(8);
.;
Array label[10]; {strings are not Fermat's strong suit}
Func Letter(n) = {assign a Hebrew letter to the numbers 1-8}
[label]:='heth ';
if n = 1 then [label]:='aleph ' fi;
if n = 2 then [label]:='beth ' fi;
if n = 3 then [label]:='gimel ' fi;
if n = 4 then [label]:='daleth ' fi;
if n = 5 then [label]:='he ' fi;
if n = 6 then [label]:='waw ' fi;
if n = 7 then [label]:='zayin ' fi;
.;
Array count[8]; {pick a bunch of random numbers}
for i = 1 to trials do
s:=Sel;
count[s]:=count[s]+1;
od;
for i = 1 to 8 do {now display some diagnostics}
Letter(i);
ctp:=count[i]/trials-probs[i];
!([label:char, count[i]/trials,' differs from ',probs[i]);
!(' by ',ctp, ' or about one part in ', Round(Denom(ctp),|Numer(ctp)|));
!!;
od;
!!('The various probabilities add up to ',Sigma<i=1,8>[count[i]/trials]); {check if our trials add to 1}
</syntaxhighlight>
{{out}}<pre>
aleph 199939 / 1000000 differs from 1 / 5 by -61 / 1000000 or about one part in 16393
beth 166361 / 1000000 differs from 1 / 6 by -917 / 3000000 or about one part in 3272
gimel 142509 / 1000000 differs from 1 / 7 by -2437 / 7000000 or about one part in 2872
daleth 124917 / 1000000 differs from 1 / 8 by -83 / 1000000 or about one part in 12048
he 111013 / 1000000 differs from 1 / 9 by -883 / 9000000 or about one part in 10193
waw 100327 / 1000000 differs from 1 / 10 by 327 / 1000000 or about one part in 3058
zayin 4569 / 50000 differs from 1 / 11 by 259 / 550000 or about one part in 2124
heth 31777 / 500000 differs from 1759 / 27720 by 33961 / 346500000 or about one part in 10203
The various probabilities add up to 1
</pre>
=={{header|Forth}}==
<
\ common factors of desired probabilities (1/5 .. 1/11)
Line 1,112 ⟶ 1,347:
f- fabs fs. ;
: .results .header 8 0 do i .result loop ;</
<pre>
Line 1,131 ⟶ 1,366:
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
<
IMPLICIT NONE
Line 1,163 ⟶ 1,398:
WRITE(*, "(A,8F10.6)") "Attained Probability:", REAL(probcount) / REAL(trials)
ENDPROGRAM PROBS</
Sample Output:
<pre>
Line 1,172 ⟶ 1,407:
=={{header|FreeBASIC}}==
<
Dim letters (0 To 7) As String = {"aleph", "beth", "gimel", "daleth", "he", "waw", "zayin", "heth"}
Line 1,230 ⟶ 1,465:
Print
Print "Press any key to quit"
Sleep</
{{out}}
Line 1,242 ⟶ 1,477:
he 0.110772 0.111111
waw 0.100236 0.100000
heth 0.063412 0.063456
-------- --------
1.000000 1.000000
</pre>
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
_elements = 8
local fn ProbabilisticChoice
double prob(_elements), cumulative(_elements)
Str15 item(_elements)
double r, p, sum = 0, checksum = 0
long i, j, samples = 1000000
item(1) = "aleph" : item(2) = "beth" : item(3) = "gimel" : item(4) = "daleth"
item(5) = "he" : item(6) = "waw" : item(7) = "zayin" : item(8) = "heth"
prob(1) = 1/5.0 : prob(2) = 1/6.0 : prob(3) = 1/7.0 : prob(4) = 1/8.0
prob(5) = 1/9.0 : prob(6) = 1/10.0 : prob(7) = 1/11.0 : prob(8) = 1759/27720
for i = 1 to _elements
sum += prob(i)
next
if abs(sum-1) > samples then print "Probabilities don't sum to 1." : exit fn
for i = 1 to samples
cln r = (((double)arc4random()/0x100000000));
p = 0
for j = 1 to _elements
p += prob(j)
if (r < p) then cumulative(j) += 1 : exit for
next
next
print
printf @"Item Actual Theoretical"
printf @"---- ------ -----------"
for i = 1 to _elements
printf @"%-7s %10.6f %12.6f", item(i), cumulative(i)/samples, prob(i)
checksum += cumulative(i)/samples
next
printf @" -------- -----------"
printf @"%17.6f %12.6f", checksum, 1.000000
end fn
fn ProbabilisticChoice
HandleEvents
</syntaxhighlight>
{{output}}
<pre>
Item Actual Theoretical
---- ------ -----------
aleph 0.199966 0.200000
beth 0.166505 0.166667
gimel 0.142958 0.142857
daleth 0.124827 0.125000
he 0.111451 0.111111
waw 0.100095 0.100000
zayin 0.090985 0.090909
heth 0.063213 0.063456
-------- -----------
1.000000 1.000000
</pre>
=={{header|Go}}==
<
import (
Line 1,311 ⟶ 1,609:
}
fmt.Printf("Totals %8.6f %8.6f\n", totalTarget, totalGenerated)
}</
Output:
<pre>
Line 1,327 ⟶ 1,625:
=={{header|Haskell}}==
<
dataBinCounts :: [Float] -> [Float] -> [Int]
dataBinCounts thresholds range =
zipWith
(-)
(0 : xs)
where
sampleSize = length range
xs =
(-) sampleSize . length
. flip filter range
. (<)
<$> thresholds
--------------------------- TEST -------------------------
main :: IO ()
main = do
g <- newStdGen
let fractions = recip <$> [5 .. 11] :: [Float]
expected = fractions
actual =
<$> dataBinCounts
(scanl1 (+) expected)
piv n x = take n (x <> repeat ' ');
putStrLn " expected actual"
mapM_ putStrLn $
zipWith3
( \l s c ->
piv 7 l
<> (piv 13 (show s) <> piv 12 (show c))
)
[ "aleph",
"beth",
"gimel",
"daleth",
"he",
"waw",
"zayin",
"heth"
]
expected
actual</
{{Out}}
Sample
Line 1,366 ⟶ 1,685:
=={{header|HicEst}}==
<
expected = 1 / ($ + 4)
Line 1,382 ⟶ 1,701:
outcome = outcome / trials
DLG(Text=expected, Text=outcome, Y=0) </
Exported from the spreadsheet-like DLG function:
<pre>0.2 0.199908
Line 1,395 ⟶ 1,714:
=={{header|Icon}} and {{header|Unicon}}==
<syntaxhighlight lang="icon">
record Item(value, probability)
Line 1,446 ⟶ 1,765:
left(count(sample, item.value)/*sample, 6))
end
</syntaxhighlight>
Output:
Line 1,461 ⟶ 1,780:
=={{header|J}}==
<syntaxhighlight lang="j">
main=: verb define
hdr=. ' target actual '
Line 1,478 ⟶ 1,797:
da (distribution of actual values among partitions)
pa (actual proportions)
)</
Example use:
<
target actual
aleph 0.200000 0.200344
Line 1,489 ⟶ 1,808:
waw 0.100000 0.099751
zayin 0.090909 0.091121
heth 0.063456 0.063527</
Note that there is no rounding error in summing the proportions, as they are represented as rational numbers, not floating-point approximations.
<
pt
1r5 1r6 1r7 1r8 1r9 1r10 1r11 1759r27720
+/pt
1</
=={{header|Java}}==
{{trans|C}}
<
static long TRIALS= 1000000;
Line 1,565 ⟶ 1,884:
}
}</
Output:
<pre>Trials: 1000000
Line 1,572 ⟶ 1,891:
Attained prob.: 0.199615 0.167517 0.142612 0.125211 0.110970 0.099614 0.091002 0.063459 </pre>
{{works with|Java|1.5+}}
<
public class Prob {
Line 1,623 ⟶ 1,942:
return null;
}
}</
Output:
<pre>Target probabliities: {ALEPH=0.2, BETH=0.16666666666666666, GIMEL=0.14285714285714285, DALETH=0.125, HE=0.1111111111111111, WAW=0.1, ZAYIN=0.09090909090909091, HETH=0.06345598845598846}
Line 1,631 ⟶ 1,950:
===ES5===
Fortunately, iterating over properties added to an object maintains the insertion order.
<
aleph: 1/5.0,
beth: 1/6.0,
Line 1,662 ⟶ 1,981:
for (var name in probabilities)
// using WSH
WScript.Echo(name + "\t" + probabilities[name] + "\t" + randomly[name]/iterations);</
output:
<pre>aleph 0.2 0.200597
Line 1,676 ⟶ 1,995:
By functional composition:
{{Trans|Haskell}}
<
'use strict';
Line 1,781 ⟶ 2,100:
.map(unwords)
.join('\n');
})();</
{{Out}}
Sample:
Line 1,793 ⟶ 2,112:
Zayin 0.0909091 0.0909630
Chet 0.0634560 0.0632870 </pre>
=={{header|jq}}==
In the task description, the probabilities are given as rationals,
so in this entry, we shall assume the probabilities are given as rationals
represented by JSON objects of the form {n: $numerator, d: denominator}.
For simplicity, it is further assumed that the largest denominator is not too large.
Neither the C nor the Go implmentations of jq provides a PRNG,
so in the following, /dev/urandom is used as a source of entropy;
an appropriate invocation of jq (or gojq) would thus be as follows:
<syntaxhighlight lang=bash>
#!/bin/bash
< /dev/urandom tr -cd '0-9' | fold -w 1 | jq -nr -f probabilistic-choice.jq
</syntaxhighlight>
<syntaxhighlight lang=jq>
# Output: a prn in range(0;$n) where $n is `.`
def prn:
if . == 1 then 0
else . as $n
| ([1, (($n-1)|tostring|length)]|max) as $w
| [limit($w; inputs)] | join("") | tonumber
| if . < $n then . else ($n | prn) end
end;
# General Utility Functions
# bag of words
def bow(stream):
reduce stream as $word ({}; .[($word|tostring)] += 1);
# left pad with blank
def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;
# right-pad with 0
def rpad($len): tostring | ($len - length) as $l | .+ ("0" * $l)[:$l];
# Input: a string of digits with up to one "."
# Output: the corresponding string representation with exactly $n decimal digits
def align_decimal($n):
tostring
| index(".") as $ix
| if $ix then capture("(?<i>[0-9]*[.])(?<j>[0-9]{0," + ($n|tostring) + "})") as {$i, $j}
| $i + ($j|rpad($n))
else . + "." + ("0" * $n)
end ;
# Input: a string of digits with up to one embedded "."
# Output: the corresponding string representation with up to $n decimal digits but aligned at the period
def align_decimal($n):
tostring
| index(".") as $ix
| if $ix then capture("(?<i>[0-9]*[.])(?<j>[0-9]{0," + ($n|tostring) + "})") as {$i, $j}
| $i + ($j|rpad($n))
else . + ".0" | align_decimal($n)
end ;
# least common multiple
# Define the helper function to take advantage of jq tail-recursion optimization
def lcm($m; $n):
def _lcm:
# state is [m, n, i]
if (.[2] % .[1]) == 0 then .[2]
else .[0:2] + [.[2] + $m] | _lcm
end;
[m, n, m] | _lcm;
def lcm(s): reduce s as $_ (1; lcm(.; $_));
# rationals
def r($n; $d): {$n, $d};
</syntaxhighlight>
'''The Task'''
<syntaxhighlight lang=jq>
# Given that $integers is an array of integers to be interpreted as
# relative probabilities, return a corresponding element chosen
# randomly from the input array.
def randomly($integers):
def accumulate: reduce .[1:][] as $i ([.[0]]; . + [$i + .[-1]]);
if ($integers | length) != length
then "randomly/1: the array lengths are unequal" | error
else . as $in
| $integers
| add as $sum
| accumulate as $p
| ($sum|prn + 1) as $random
| $in[first(range(0; $p|length) | select( $random <= $p[.] ))]
end ;
# Input should be a JSON object giving probabilities of each key as a rational: {n, d}
def choose($n):
lcm(.[].d) as $lcm
| ([.[] | $lcm * .n / .d]) as $p
| keys_unsorted as $items
| range(0; $n)
| $items | randomly($p);
# Print a table comparing expected, observed and the ratio
# (expected - observed)^2 / expected
def compare( $expected; $observed ):
def p($n): align_decimal($n) | lpad(8);
" : expected observed (e-o)^2 / e",
( $expected
| keys_unsorted[] as $k
| .[$k] as $e
| ($observed[$k] // 0) as $o
| "\($k|lpad(6)) : \($e|p(1)) \($o|floor|lpad(8)) \( (($e - $o) | (.*.) / $e) | p(2))" );
# The specific task
def probabilities:
{ "aleph": r(1; 5),
"beth": r(1; 6),
"gimel": r(1; 7),
"daleth": r(1; 8),
"he": r(1; 9),
"waw": r(1; 10),
"zayin": r(1; 11),
"heth": r(1759; 27720)
};
def task($n):
probabilities
| bow(choose($n)) as $observed
| compare( map_values($n * .n / .d); $observed ) ;
task(1E6)
'
</syntaxhighlight>
'''Output'''
<pre>
: expected observed (e-o)^2 / e
aleph : 200000.0 200247 0.30
beth : 166666.6 166668 1.06
gimel : 142857.1 142787 0.03
daleth : 125000.0 124789 0.35
he : 111111.1 111280 0.25
waw : 100000.0 100165 0.27
zayin : 90909.0 90716 0.41
heth : 63455.9 63348 0.18
</pre>
=={{header|Julia}}==
I made the solution to this task more difficult than I had anticipated by using the Hebrew characters (rather than their anglicised names) as labels for the sampled collection of objects. In doing so, I encountered an interesting subtlety of bidirectional text in Unicode. Namely, that strong right-to-left characters, such as those of Hebrew, override the directionality of European digits, which have weak directionality. Because of this property of Unicode, my table of items and yields had its lines of data interpreted as if it were entirely Hebrew and output in reverse order (from my English speaking perspective). I was able to get the table to display as I liked on my terminal by preceding the the Hebrew characters by the Unicode RLI (right-to-left isolate) control character (<tt>U+2067</tt>). However, when I pasted this output into this Rosetta Code entry, the display reverted to the "backwards" version. Rather than continue the struggle, trying to force this entry to display as it does on my terminal, I created an alternative version of the table. This "Displayable Here" table adds "yields" to to each line, and this strong left-to-right text makes the whole line display as left-to-right (without the need for a RLI characer).
<
p = [1/i for i in 5:11]
Line 1,827 ⟶ 2,292:
plab[i], accum[i], p[i], r[i]))
end
</syntaxhighlight>
{{out}}
Line 1,863 ⟶ 2,328:
=={{header|Kotlin}}==
{{trans|FreeBASIC}}
<
fun main(args: Array<String>) {
Line 1,900 ⟶ 2,365:
println("\t-------- --------")
println("\t${"%8.6f".format(sumActual)} 1.000000")
}</
{{out}}
Line 1,919 ⟶ 2,384:
=={{header|Liberty BASIC}}==
<syntaxhighlight lang="lb">
names$="aleph beth gimel daleth he waw zayin heth"
dim sum(8)
Line 1,944 ⟶ 2,409:
print word$(names$, i), using( "#.#####", counter(i) /N), using( "#.#####", 1/(i+4))
next
</syntaxhighlight>
=={{header|Lua}}==
<
items["aleph"] = 1/5.0
items["beth"] = 1/6.0
Line 1,980 ⟶ 2,445:
for item, _ in pairs( items ) do
print( item, samples[item]/num_trials, items[item] )
end</
Output
<pre>gimel 0.142606 0.14285714285714
Line 1,991 ⟶ 2,456:
waw 0.100062 0.1</pre>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Built-in function can already do a weighted random choosing. Example for making a million random choices would be:
<
data=RandomChoice[choices[[All,2]]->choices[[All,1]],10^6];</
To compare the data we use the following code to make a table:
<
gives back (item, attained prob., target prob.):
<pre>aleph 0.200036 0.2
Line 2,009 ⟶ 2,474:
=={{header|MATLAB}}==
{{works with|MATLAB|with Statistics Toolbox}}
<
choices = {'aleph' 'beth' 'gimel' 'daleth' 'he' 'waw' 'zayin' 'heth'};
w = [1/5 1/6 1/7 1/8 1/9 1/10 1/11 1759/27720];
Line 2,019 ⟶ 2,484:
choices{k}, T(k, 2), T(k, 3), 100*w(k))
end
end</
{{out}}
<pre>Value Count Percent Goal
Line 2,031 ⟶ 2,496:
heth 63171 6.32% 6.35%</pre>
{{works with|MATLAB|without toolboxes}}
<
choices = {'aleph' 'beth' 'gimel' 'daleth' 'he' 'waw' 'zayin' 'heth'};
w = [1/5 1/6 1/7 1/8 1/9 1/10 1/11 1759/27720];
Line 2,047 ⟶ 2,512:
choices{k}, results(k), 100*results(k)/nSamp, 100*w(k))
end
end</
{{out}}
<pre>Value Count Percent Goal
Line 2,060 ⟶ 2,525:
=={{header|Nim}}==
<
var start = cpuTime()
Line 2,093 ⟶ 2,558:
echo "====== ======== ======== "
echo &"Total: {s2:^8.2f} {s1:^8.2f}"
echo &"\nExecution time: {cpuTime()-start:.2f} s"</
{{out}}
Line 2,113 ⟶ 2,578:
=={{header|OCaml}}==
<
"Aleph", 1.0 /. 5.0;
"Beth", 1.0 /. 6.0;
Line 2,142 ⟶ 2,607:
let d = Hashtbl.find h v in
Printf.printf "%s \t %f %f\n" v p (float d /. float n)
) p</
Output:
Line 2,155 ⟶ 2,620:
=={{header|PARI/GP}}==
<
my(v=[5544,10164,14124,17589,20669,23441,25961,27720],u=vector(8),e);
for(i=1,1e6,
Line 2,168 ⟶ 2,633:
print("Diff: ",u-e);
print("StDev: ",vector(8,i,sqrt(abs(u[i]-v[i])/e[i])));
};</
=={{header|Perl}}==
<
use constant TRIALS => 1e6;
Line 2,208 ⟶ 2,673:
$_, $results{$_}/TRIALS, $ps{$_},
abs($results{$_}/TRIALS - $ps{$_});
}</
Sample output:
Line 2,223 ⟶ 2,688:
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">lim</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1000000</span><span style="color: #0000FF;">,</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">names</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">probs</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">columnize</span><span style="color: #0000FF;">({{</span><span style="color: #008000;">"aleph"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">5</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"beth"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">6</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"gimel"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">7</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"daleth"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">8</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"he"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">9</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"waw"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">10</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"zayin"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">11</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"heth"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1759</span><span style="color: #0000FF;">/</span><span style="color: #000000;">27720</span><span style="color: #0000FF;">}})</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">results</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">names</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">lim</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rnd</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">probs</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">r</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">probs</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">r</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">results</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]+=</span><span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" Name Actual Expected\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">probs</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%6s %8.6f %8.6f\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">names</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">results</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]/</span><span style="color: #000000;">lim</span><span style="color: #0000FF;">,</span><span style="color: #000000;">probs</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 2,263 ⟶ 2,728:
heth 0.063442 0.063456
</pre>
=={{header|Phixmonti}}==
<syntaxhighlight lang="phixmonti">/# Rosetta Code problem: http://rosettacode.org/wiki/Probabilistic_choice
by Galileo, 05/2022 #/
include ..\Utilitys.pmt
( ( "aleph" 0.200000 0 ) ( "beth" 0.166667 0 ) ( "gimel" 0.142857 0 ) ( "daleth" 0.125000 0 )
( "he" 0.111111 0 ) ( "waw" 0.100000 0 ) ( "zayin" 0.090909 0 ) ( "heth" 0.063456 0 ) )
len 1 swap 2 tolist var lprob
1000000 var trial
trial for drop
rand >ps
0 >ps
lprob for var i
( i 2 ) sget ps> +
tps swap dup >ps < if
( i 3 ) sget 1 + ( i 3 ) sset
exitfor
endif
endfor
ps> ps> drop drop
endfor
( "item" "\t" "actual" "\t\t" "theoretical" ) lprint nl nl
lprob for drop
pop swap
1 get "\t" rot 3 get trial / "\t" rot 2 get nip "\n" 6 tolist lprint
endfor</syntaxhighlight>
{{out}}
<pre>item actual theoretical
aleph 0.200018 0.2
beth 0.166987 0.166667
gimel 0.142654 0.142857
daleth 0.125217 0.125
he 0.111668 0.111111
waw 0.099827 0.1
zayin 0.090311 0.090909
heth 0.063318 0.063456
=== Press any key to exit ===</pre>
=={{header|PicoLisp}}==
<
(let Probs
(mapcar
Line 2,281 ⟶ 2,790:
(cdddr X)
(format (cadr X) 6)
(format (caddr X) 6) ) ) ) ) )</
Output:
<pre> Probability Result
Line 2,294 ⟶ 2,803:
=={{header|PL/I}}==
<
Dcl prob(8) Dec Float(15) Init((1/5.0), /* aleph */
(1/6.0), /* beth */
Line 2,338 ⟶ 2,847:
Put Edit(what(i),cnt(i),pr,prob(i))(Skip,a,f(10),x(2),2(f(11,8)));
End;
End;</
{{out}}
<pre>One million trials
Line 2,367 ⟶ 2,876:
{{trans|Java Script}}
The guts of this script are translated from the Java Script entry. Then I stole the idea to show the actual Hebrew character from Julia.
<syntaxhighlight lang="powershell">
$character = [PSCustomObject]@{
aleph = [PSCustomObject]@{Expected=1/5 ; Alpha="א"}
Line 2,414 ⟶ 2,923:
}
}
</syntaxhighlight>
{{Out}}
<pre>
Line 2,430 ⟶ 2,939:
=={{header|PureBasic}}==
<
Structure Item
Line 2,471 ⟶ 2,980:
Print(#CRLF$+"Press ENTER to exit"):Input()
CloseConsole()
EndIf</
Output may look like
Line 2,489 ⟶ 2,998:
=={{header|Python}}==
Two different algorithms are coded.
<
def probchoice(items, probs):
Line 2,552 ⟶ 3,061:
probs[-1] = 1-sum(probs[:-1])
tester(probchoice, items, probs, 1000000)
tester(probchoice2, items, probs, 1000000)</
Sample output:
Line 2,576 ⟶ 3,085:
Uses point$ from the bignum rational arithmetic module bigrat.qky. <code>10 point$</code> returns a ratio as a decimal string accurate to 10 decimal places with round-to-nearest on the final digit.
<
( --------------- zen object orientation -------------- )
Line 2,647 ⟶ 3,156:
drop ]
witheach [ report swap do ]</
{{out}}
Line 2,684 ⟶ 3,193:
=={{header|R}}==
<
# Note that R doesn't actually require the weights
# vector for rmultinom to sum to 1.
Line 2,691 ⟶ 3,200:
Requested = prob,
Obtained = hebrew/sum(hebrew))
print(d)</
Sample output:
Line 2,705 ⟶ 3,214:
A histogram of the data is also possible using, for example,
<
qplot(factor(names(prob), levels = names(prob)), hebrew, geom = "histogram")</
=={{header|Racket}}==
Line 2,717 ⟶ 3,226:
as a module. Either run the program in DrRacket or run `raco test prob-choice.rkt`
<
;;; returns a probabalistic choice from the sequence choices
;;; choices generates two values -- the chosen value and a
Line 2,803 ⟶ 3,312:
(test-p-c-function probabalistic-choice/exact test-weightings/50:50)
(test-p-c-function probabalistic-choice test-weightings/rosetta)
(test-p-c-function probabalistic-choice/exact test-weightings/rosetta))</
Output (note that the progress counts, which go to standard error, are
interleaved with the output on standard out)
Line 2,838 ⟶ 3,347:
(formerly Perl 6)
{{works with|Rakudo|2018.10}}
<syntaxhighlight lang="raku"
constant @event = <aleph beth gimel daleth he waw zayin heth>;
Line 2,856 ⟶ 3,365:
$expected,
abs $occurred - $expected;
}</
{{out}}
<pre>Event Occurred Expected Difference
Line 2,867 ⟶ 3,376:
zayin 90617 90909.1 292.1
heth 63481 63456.0 25.0</pre>
=={{header|ReScript}}==
<syntaxhighlight lang="rescript">let p = [
("Aleph", 1.0 /. 5.0),
("Beth", 1.0 /. 6.0),
("Gimel", 1.0 /. 7.0),
("Daleth", 1.0 /. 8.0),
("He", 1.0 /. 9.0),
("Waw", 1.0 /. 10.0),
("Zayin", 1.0 /. 11.0),
("Heth", 1759.0 /. 27720.0),
]
let prob_take = (arr, k) => {
let rec aux = (i, k) => {
let (v, p) = arr[i]
if k < p { v } else { aux(i+1, (k -. p)) }
}
aux(0, k)
}
{
let n = 1_000_000
let h = Belt.HashMap.String.make(~hintSize=10)
Js.Array2.forEach(p, ((v, _)) =>
Belt.HashMap.String.set(h, v, 0)
)
let tot = Js.Array2.reduce(p, (acc, (_, prob)) => acc +. prob, 0.0)
for _ in 1 to n {
let sel = prob_take(p, tot *. Js.Math.random())
let _n = Belt.HashMap.String.get(h, sel)
let n = Belt.Option.getExn(_n)
Belt.HashMap.String.set(h, sel, (n+1)) /* count the number of each item */
}
Printf.printf("Event expected occurred\n")
Js.Array2.forEach(p, ((v, p)) => {
let _d = Belt.HashMap.String.get(h, v)
let d = Belt.Option.getExn(_d)
Printf.printf("%s \t %8.5g %8.5g\n", v, p, float(d) /. float(n))
}
)
}</syntaxhighlight>
{{output}}
<pre>
Event expected occurred
Aleph 0.2 0.20042
Beth 0.16667 0.16606
Gimel 0.14286 0.14324
Daleth 0.125 0.1252
He 0.11111 0.11085
Waw 0.1 0.099557
Zayin 0.090909 0.090877
Heth 0.063456 0.0638
</pre>
=={{header|REXX}}==
Line 2,872 ⟶ 3,438:
A little extra REXX code was added to provide head and foot titles along with the totals.
<
parse arg trials digs seed . /*obtain the optional arguments from CL*/
if trials=='' | trials=="," then trials= +1e6 /*Not specified? Then use the default.*/
Line 2,903 ⟶ 3,469:
left( format( @.cell/trials * 100, d), w-2) /* [↓] foot title. [↓] */
if cell==# then say center(_,15,_) center(_,d,_) center(_,w,_) center(_,w,_)
end /*c*/ /*stick a fork in it, we are all done.*/</
{{out|output|text= when using the default input:}}
<pre>
Line 2,920 ⟶ 3,486:
=={{header|Ring}}==
<
# Project : Probabilistic choice
Line 2,943 ⟶ 3,509:
see "" + item[i] + " " + cnt[i]/1000000 + " " + prob[i] + nl
next
</syntaxhighlight>
Output:
<pre>
Line 2,958 ⟶ 3,524:
=={{header|Ruby}}==
<
"aleph" => 1/5.0,
"beth" => 1/6.0,
Line 2,994 ⟶ 3,560:
val = probabilities[k]
printf "%-8s%.8f %.8f %6.3f %%\n", k, val, act, 100*(act-val)/val
end</
{{out}}
Line 3,010 ⟶ 3,576:
=={{header|Rust}}==
<
use rand::distributions::{IndependentSample, Sample, Weighted, WeightedChoice};
Line 3,136 ⟶ 3,702:
let counts = take_samples(&mut rng, &wc);
print_mapping(&counts);
}</
{{out}}
<pre> ~~~ U32 METHOD ~~~
Line 3,164 ⟶ 3,730:
=={{header|Scala}}==
This algorithm consists of a concise two-line tail-recursive loop (<tt>def weighted</tt>). The rest of the code is for API robustness, testing and display. <tt>weightedProb</tt> is for the task as stated (0 < <i>p</i> < 1), and <tt>weightedFreq</tt> is the equivalent based on integer frequencies (<i>f</i> >= 0).
<
import scala.collection.mutable.LinkedHashMap
Line 3,227 ⟶ 3,793:
println("Checking weighted frequencies:")
check(frequencies.map{case (a, b) => a -> b.toDouble}, for (i <- 1 to 1000000) yield weightedFreq(frequencies))
}</
{{out}}
<pre>Checking weighted probabilities:
Line 3,255 ⟶ 3,821:
Using guile scheme 2.0.11.
<
(define (random-choice probs)
Line 3,299 ⟶ 3,865:
(he 1/9) (waw 1/10) (zayin 1/11) (heth 1759/27720)))
(format-results probs (choices 1000000 probs))</
Example output:
Line 3,314 ⟶ 3,880:
=={{header|Seed7}}==
To reduce the runtime this program should be compiled.
<
include "float.s7i";
Line 3,358 ⟶ 3,924:
100.0 * flt(table[aLetter]) / 27720.0 digits 4 lpad 8 <& "%");
end for;
end func;</
Outout:
Line 3,375 ⟶ 3,941:
=={{header|Sidef}}==
{{trans|Perl}}
<
func prob_choice_picker(options) {
Line 3,415 ⟶ 3,981:
abs(v/TRIALS - ps{k})
);
}</
{{out}}
Line 3,429 ⟶ 3,995:
heth 0.068800 0.063456 0.005344
</pre>
=={{header|SparForte}}==
As a structured script.
<syntaxhighlight lang="ada">#!/usr/local/bin/spar
pragma annotate( summary, "randdist" )
@( description, "Given a mapping between items and their required" )
@( description, "probability of occurrence, generate a million items" )
@( description, "randomly subject to the given probabilities and compare" )
@( description, "the target probability of occurrence versus the" )
@( description, "generated values." )
@( description, "" )
@( description, "The total of all the probabilities should equal one." )
@( description, "(Because floating point arithmetic is involved this is" )
@( description, "subject to rounding errors). Use the following mapping" )
@( description, "to test your programs: aleph 1/5.0, beth 1/6.0," )
@( description, "gimel 1/7.0, daleth 1/8.0, he 1/9.0, waw 1/10.0" )
@( description, "zayin 1/11.0, heth 1759/27720 adjusted so that" )
@( description, "probabilities add to 1" )
@( see_also, "http://rosettacode.org/wiki/Probabilistic_choice" )
@( author, "Ken O. Burtch" );
pragma license( unrestricted );
pragma restriction( no_external_commands );
procedure randdist is
trials : constant positive := 1_000_000;
type outcome is (aleph, beth, gimel, daleth, he, waw, zayin, heth);
pr : constant array(aleph..heth) of float :=
(1/5, 1/6, 1/7, 1/8, 1/9, 1/10, 1/11, 1 );
samples : array(aleph..heth) of natural := (0, 0, 0, 0, 0, 0, 0, 0);
random_value : float;
begin
for try in 1..trials loop
random_value := numerics.random;
for i in arrays.first( pr )..arrays.last( pr ) loop
if random_value <= pr(i) then
samples(i) := samples(i) + 1;
exit;
else
random_value := @ - pr(i);
end if;
end loop;
end loop;
-- Show results
for i in arrays.first( pr )..arrays.last( pr ) loop
put( i ) @ ( " " ) @ ( float( samples( i ) ) / float( trials ) );
if i = heth then
put_line( " rest" );
else
put_line( pr(i) );
end if;
end loop;
end randdist;</syntaxhighlight>
{{out}}
<pre>
$ spar randdist
aleph 2.00260000000000E-01 2.00000000000000E-01
beth 1.66376000000000E-01 1.66666666666667E-01
gimel 1.42698000000000E-01 1.42857142857143E-01
daleth 1.25408000000000E-01 1.25000000000000E-01
he 1.11311000000000E-01 1.11111111111111E-01
waw 9.97980000000000E-02 1.00000000000000E-01
zayin 9.09570000000000E-02 9.09090909090909E-02
heth 6.31920000000000E-02 rest</pre>
=={{header|Stata}}==
<
mata
letters="aleph","beth","gimel","daleth","he","waw","zayin","heth"
Line 3,438 ⟶ 4,068:
st_addvar("str10","a")
st_sstore(.,.,a)
end</
=={{header|Tcl}}==
<
set map [dict create]
Line 3,477 ⟶ 4,107:
]
}
}</
<pre>using 1000000 samples:
expected actual difference
Line 3,495 ⟶ 4,125:
implemented by the run time system.
<
#import nat
#import flo
Line 3,512 ⟶ 4,142:
#show+
results = format simulation 1000000</
output:
<pre>
Line 3,527 ⟶ 4,157:
=={{header|VBScript}}==
Derived from the BBC BASIC version
<syntaxhighlight lang="vb">
item = Array("aleph","beth","gimel","daleth","he","waw","zayin","heth")
prob = Array(1/5.0, 1/6.0, 1/7.0, 1/8.0, 1/9.0, 1/10.0, 1/11.0, 1759/27720)
Line 3,559 ⟶ 4,189:
WScript.StdOut.Write item(i) & vbTab & FormatNumber(cnt(i)/1000000,6) & vbTab & FormatNumber(prob(i),6)
WScript.StdOut.WriteLine
Next</
{{out}}
Line 3,577 ⟶ 4,207:
{{trans|Kotlin}}
{{libheader|Wren-fmt}}
<
import "./fmt" for Fmt
var letters = ["aleph", "beth", "gimel", "daleth", "he", "waw", "zayin", "heth"]
Line 3,612 ⟶ 4,242:
}
System.print("\t-------- --------")
Fmt.print("\t$8.6f 1.000000", sumActual)</
{{out}}
Line 3,632 ⟶ 4,262:
=={{header|XPL0}}==
<
def Size = 10_000_000;
int Tbl(12+1);
Line 3,658 ⟶ 4,288:
");
RlOut(0, S0); RlOut(0, S1);
]</
Output:
Line 3,673 ⟶ 4,303:
1.00000 1.00000
</pre>
=={{header|Yabasic}}==
<syntaxhighlight lang="yabasic">dim letters$(7)
data "aleph", "beth", "gimel", "daleth", "he", "waw", "zayin", "heth"
letters$(0) = "aleph"
letters$(1) = "beth"
letters$(2) = "gimel"
letters$(3) = "daleth"
letters$(4) = "he"
letters$(5) = "waw"
letters$(6) = "zayin"
letters$(7) = "heth"
dim actual(7)
dim probs(7)
probs(0) = 1/5.0
probs(1) = 1/6.0
probs(2) = 1/7.0
probs(3) = 1/8.0
probs(4) = 1/9.0
probs(5) = 1/10.0
probs(6) = 1/11.0
probs(7) = 1759/27720
dim cumProbs(7)
cumProbs(0) = probs(0)
for i = 1 to 6
cumProbs(i) = cumProbs(i - 1) + probs(i)
next i
cumProbs(7) = 1.0
n = 1000000
for test = 1 to n
r = ran(1)
p = 0.0
for i = 1 to arraysize(probs(),1)
p = p + probs(i)
if r < p then
actual(i) = actual(i) + 1
break
end if
next i
next t
sumActual = 0.0
tab$ = chr$(9)
print "Letter Actual Expected"
print "------ -------- --------"
for i = 0 to 7
print letters$(i), tab$,
print actual(i)/n using "#.######",
sumActual = sumActual + actual(i)/n
print probs(i) using "#.######"
next i
print " -------- --------"
print " ", sumActual using "#.######", tab$, "1.000000"
end</syntaxhighlight>
=={{header|zkl}}==
{{trans|C}}
<
"he", "waw", "zayin", "heth");
var ptable=T(5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0).apply('/.fp(1.0));
Line 3,697 ⟶ 4,384:
"%6s%7d %7.4f%% %7.4f%%".fmt(names[i], r[i], r[i]/M*100,
ptable[i]*100).println();
}</
{{out}}
<pre>
|