Probabilistic choice: Difference between revisions

Added Easylang
m (→‎{{header|Ring}}: Remove vanity tags)
(Added Easylang)
 
(35 intermediate revisions by 20 users not shown)
Line 19:
 
=={{header|Ada}}==
<langsyntaxhighlight lang="ada">with Ada.Numerics.Float_Random; use Ada.Numerics.Float_Random;
with Ada.Text_IO; use Ada.Text_IO;
 
Line 52:
end if;
end loop;
end Random_Distribution;</langsyntaxhighlight>
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}}
<langsyntaxhighlight lang="algol68">INT trials = 1 000 000;
 
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$)
)</langsyntaxhighlight>
Sample output:
<pre>
Line 151:
Attained prob.: 0.199987 0.166917 0.142531 0.124203 0.111338 0.099702 0.091660 0.063662
</pre>
 
=={{header|AppleScript}}==
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.
 
<syntaxhighlight lang="applescript">use AppleScript version "2.5" -- Mac OS X 10.11 (El Capitan) or later.
use framework "Foundation"
use framework "GameplayKit"
 
on probabilisticChoices(mapping, picks)
script o
property mapping : {}
end script
-- Make versions of the mapping records with additional 'actual' properties …
set mapping to current application's class "NSMutableArray"'s arrayWithArray:(mapping)
tell mapping to makeObjectsPerformSelector:("addEntriesFromDictionary:") withObject:({actual:0})
-- … ensuring that they're sorted (for accuracy) in descending order (for efficiency) of probability.
set descriptor to current application's class "NSSortDescriptor"'s sortDescriptorWithKey:("probability") ascending:(false)
tell mapping to sortUsingDescriptors:({descriptor})
set o's mapping to mapping as list
set rndGenerator to current application's class "GKRandomDistribution"'s distributionForDieWithSideCount:(picks)
set onePickth to 1 / picks
repeat picks times
-- Get a random number between 0.0 and 1.0.
set r to rndGenerator's nextUniform()
-- Interpret the probability of the number occurring in the range it does
-- as picking the item with the same probability of being picked.
repeat with thisRecord in o's mapping
set r to r - (thisRecord's probability)
if (r ≤ 0) then
set thisRecord's actual to (thisRecord's actual) + onePickth
exit repeat
end if
end repeat
end repeat
return o's mapping
end probabilisticChoices
 
on task()
set mapping to {{|item|:"aleph", probability:1 / 5}, {|item|:"beth", probability:1 / 6}, ¬
{|item|:"gimel", probability:1 / 7}, {|item|:"daleth", probability:1 / 8}, ¬
{|item|:"he", probability:1 / 9}, {|item|:"waw", probability:1 / 10}, ¬
{|item|:"zayin", probability:1 / 11}, {|item|:"heth", probability:1759 / 27720}}
set picks to 1000000
set theResults to probabilisticChoices(mapping, picks)
set output to {}
set template to {"|item|:", missing value, ", probability:", missing value, ", actual:", missing value}
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to ""
repeat with thisRecord in theResults
set {|item|:item 2 of template, probability:item 4 of template, actual:item 6 of template} to thisRecord
set {|item|:template's second item, probability:template's fourth item, actual:template's sixth item} to thisRecord
set end of output to template as text
end repeat
set AppleScript's text item delimiters to "}, ¬
{"
set output to "{ ¬
{" & output & "} ¬
}"
set AppleScript's text item delimiters to astid
return output
end task
 
task()</syntaxhighlight>
 
{{output}}
<syntaxhighlight lang="applescript">"{ ¬
{|item|:aleph, probability:0.2, actual:0.20033}, ¬
{|item|:beth, probability:0.166666666667, actual:0.166744}, ¬
{|item|:gimel, probability:0.142857142857, actual:0.142403}, ¬
{|item|:daleth, probability:0.125, actual:0.125195}, ¬
{|item|:he, probability:0.111111111111, actual:0.110284}, ¬
{|item|:waw, probability:0.1, actual:0.100505}, ¬
{|item|:zayin, probability:0.090909090909, actual:0.090721}, ¬
{|item|:heth, probability:0.063455988456, actual:0.063817} ¬
}"</syntaxhighlight>
 
=={{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]
<langsyntaxhighlight AutoHotkeylang="autohotkey">s1 := "aleph", p1 := 1/5.0 ; Input
s2 := "beth", p2 := 1/6.0
s3 := "gimel", p3 := 1/7.0
Line 192 ⟶ 338:
heth 0.063456 0.063342
---------------------------
*/</langsyntaxhighlight>
 
=={{header|AWK}}==
 
<langsyntaxhighlight lang="awk">#!/usr/bin/awk -f
 
BEGIN {
Line 268 ⟶ 414:
counts[sym] = 0;
}
</syntaxhighlight>
</lang>
 
Example output:
Line 286 ⟶ 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}}==
<langsyntaxhighlight lang="bbcbasic"> DIM item$(7), prob(7), cnt%(7)
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 306 ⟶ 506:
FOR i% = 0 TO DIM(item$(),1)
PRINT item$(i%), cnt%(i%)/1E6, prob(i%)
NEXT</langsyntaxhighlight>
'''Output:'''
<pre>
Line 321 ⟶ 521:
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
 
Line 354 ⟶ 554:
 
return 0;
}</langsyntaxhighlight>output<syntaxhighlight lang="text"> Name Count Ratio Expected
aleph 199928 19.9928% 20.0000%
beth 166489 16.6489% 16.6667%
Line 362 ⟶ 562:
waw 99935 9.9935% 10.0000%
zayin 91001 9.1001% 9.0909%
heth 63330 6.3330% 6.3456%</langsyntaxhighlight>
 
=={{header|C++}}==
<lang cpp>#include <cstdlib>
#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
#include <ctime>
#include <iomanip>
 
int main( ) {
typedef std::vector<std::pair<std::string, double> >::const_iterator SPI ;
typedef std::vector<std::pair<std::string , double> > ProbType ;
ProbType probabilities ;
probabilities.push_back( std::make_pair( "aleph" , 1/5.0 ) ) ;
probabilities.push_back( std::make_pair( "beth" , 1/6.0 ) ) ;
probabilities.push_back( std::make_pair( "gimel" , 1/7.0 ) ) ;
probabilities.push_back( std::make_pair( "daleth" , 1/8.0 ) ) ;
probabilities.push_back( std::make_pair( "he" , 1/9.0 ) ) ;
probabilities.push_back( std::make_pair( "waw" , 1/10.0 ) ) ;
probabilities.push_back( std::make_pair( "zayin" , 1/11.0 ) ) ;
probabilities.push_back( std::make_pair( "heth" , 1759/27720.0 ) ) ;
std::vector<std::string> generated ; //for the strings that are generatod
std::vector<int> decider ; //holds the numbers that determine the choice of letters
for ( int i = 0 ; i < probabilities.size( ) ; i++ ) {
if ( i == 0 ) {
decider.push_back( 27720 * (probabilities[ i ].second) ) ;
}
else {
int number = 0 ;
for ( int j = 0 ; j < i ; j++ ) {
number += 27720 * ( probabilities[ j ].second ) ;
}
number += 27720 * probabilities[ i ].second ;
decider.push_back( number ) ;
}
}
srand( time( 0 ) ) ;
for ( int i = 0 ; i < 1000000 ; i++ ) {
int randnumber = rand( ) % 27721 ;
int j = 0 ;
while ( randnumber > decider[ j ] )
j++ ;
generated.push_back( ( probabilities[ j ]).first ) ;
}
std::cout << "letter frequency attained frequency expected\n" ;
for ( SPI i = probabilities.begin( ) ; i != probabilities.end( ) ; i++ ) {
std::cout << std::left << std::setw( 8 ) << i->first ;
int found = std::count ( generated.begin( ) , generated.end( ) , i->first ) ;
std::cout << std::left << std::setw( 21 ) << found / 1000000.0 ;
std::cout << std::left << std::setw( 17 ) << i->second << '\n' ;
}
return 0 ;
}</lang>
Output:
<PRE>letter frequency attained frequency expected
aleph 0.200089 0.2
beth 0.16695 0.166667
gimel 0.142693 0.142857
daleth 0.124859 0.125
he 0.111258 0.111111
waw 0.099665 0.1
zayin 0.090654 0.0909091
heth 0.063832 0.063456
</PRE>
 
=={{header|C sharp|C#}}==
Line 433 ⟶ 568:
{{trans|Java}}
 
<langsyntaxhighlight lang="csharp">
using System;
 
Line 505 ⟶ 640:
}
}
</syntaxhighlight>
</lang>
 
Output:
Line 513 ⟶ 648:
Target prob.: 0.200000 0.166667 0.142857 0.125000 0.111111 0.100000 0.090909 0.063456
Attained prob.: 0.199975 0.166460 0.142290 0.125510 0.111374 0.100018 0.090746 0.063627</pre>
 
=={{header|C++}}==
<syntaxhighlight lang="cpp">#include <cstdlib>
#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
#include <ctime>
#include <iomanip>
 
int main( ) {
typedef std::vector<std::pair<std::string, double> >::const_iterator SPI ;
typedef std::vector<std::pair<std::string , double> > ProbType ;
ProbType probabilities ;
probabilities.push_back( std::make_pair( "aleph" , 1/5.0 ) ) ;
probabilities.push_back( std::make_pair( "beth" , 1/6.0 ) ) ;
probabilities.push_back( std::make_pair( "gimel" , 1/7.0 ) ) ;
probabilities.push_back( std::make_pair( "daleth" , 1/8.0 ) ) ;
probabilities.push_back( std::make_pair( "he" , 1/9.0 ) ) ;
probabilities.push_back( std::make_pair( "waw" , 1/10.0 ) ) ;
probabilities.push_back( std::make_pair( "zayin" , 1/11.0 ) ) ;
probabilities.push_back( std::make_pair( "heth" , 1759/27720.0 ) ) ;
std::vector<std::string> generated ; //for the strings that are generatod
std::vector<int> decider ; //holds the numbers that determine the choice of letters
for ( int i = 0 ; i < probabilities.size( ) ; i++ ) {
if ( i == 0 ) {
decider.push_back( 27720 * (probabilities[ i ].second) ) ;
}
else {
int number = 0 ;
for ( int j = 0 ; j < i ; j++ ) {
number += 27720 * ( probabilities[ j ].second ) ;
}
number += 27720 * probabilities[ i ].second ;
decider.push_back( number ) ;
}
}
srand( time( 0 ) ) ;
for ( int i = 0 ; i < 1000000 ; i++ ) {
int randnumber = rand( ) % 27721 ;
int j = 0 ;
while ( randnumber > decider[ j ] )
j++ ;
generated.push_back( ( probabilities[ j ]).first ) ;
}
std::cout << "letter frequency attained frequency expected\n" ;
for ( SPI i = probabilities.begin( ) ; i != probabilities.end( ) ; i++ ) {
std::cout << std::left << std::setw( 8 ) << i->first ;
int found = std::count ( generated.begin( ) , generated.end( ) , i->first ) ;
std::cout << std::left << std::setw( 21 ) << found / 1000000.0 ;
std::cout << std::left << std::setw( 17 ) << i->second << '\n' ;
}
return 0 ;
}</syntaxhighlight>
Output:
<PRE>letter frequency attained frequency expected
aleph 0.200089 0.2
beth 0.16695 0.166667
gimel 0.142693 0.142857
daleth 0.124859 0.125
he 0.111258 0.111111
waw 0.099665 0.1
zayin 0.090654 0.0909091
heth 0.063832 0.063456
</PRE>
 
=={{header|Clojure}}==
Line 519 ⟶ 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.
 
<langsyntaxhighlight Clojurelang="clojure">(defn to-cdf [pdf]
(reduce
(fn [acc n] (conj acc (+ (or (last acc) 0) n)))
Line 540 ⟶ 740:
(doseq [[idx exp] expected]
(println "Expected number of" (*names* idx) "was"
(* num-trials exp) "and actually got" (actual idx))))</langsyntaxhighlight>
 
<pre>Expected number of aleph was 200000.0 and actually got 199300
Line 554 ⟶ 754:
 
This is a straightforward, if a little verbose implementation based upon the Perl one.
<langsyntaxhighlight lang="lisp">(defvar *probabilities* '((aleph 1/5)
(beth 1/6)
(gimel 1/7)
Line 599 ⟶ 799:
WAW 0.100068 0.1
ZAYIN 0.090458 0.09090909
HETH 0.063481 0.06345599</langsyntaxhighlight>
 
=={{header|D}}==
===Basic Version===
<langsyntaxhighlight lang="d">void main() {
import std.stdio, std.random, std.string, std.range;
 
Line 617 ⟶ 817:
foreach (name, p, co; zip(items, pr, counts[]))
writefln("%-7s %.8f %.8f", name, p, co / nTrials);
}</langsyntaxhighlight>
{{out}}
<pre>Item Target prob Attained prob
Line 630 ⟶ 830:
 
===A Faster Version===
<langsyntaxhighlight lang="d">void main() {
import std.stdio, std.random, std.algorithm, std.range;
 
Line 650 ⟶ 850:
foreach (name, p, co; zip(items, pr, counts[]))
writefln("%-7s %.8f %.8f", name, p, co / nTrials);
}</langsyntaxhighlight>
 
=={{header|E}}==
Line 658 ⟶ 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).
 
<langsyntaxhighlight lang="e">pragma.syntax("0.9")</langsyntaxhighlight>
 
First, the algorithm:
 
<langsyntaxhighlight lang="e">/** Makes leaves of the binary tree */
def leaf(value) {
return def leaf {
Line 695 ⟶ 895:
makeIntervalTree(assocs.run(midpoint)))
} else {
def <nowiki>[[value, _]] := assocs</nowiki>
return leaf(value)
}
Line 716 ⟶ 916:
}
}
}</langsyntaxhighlight>
 
Then the test setup:
 
<langsyntaxhighlight lang="e">def rosetta := setupProbabilisticChoice(entropy, def probTable := [
"aleph" => 1/5,
"beth" => 1/6.0,
Line 741 ⟶ 941:
for item in probTable.domain() {
stdout.print(item, "\t", timesFound[item] / trials, "\t", probTable[item], "\n")
}</langsyntaxhighlight>
 
=={{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}}
<langsyntaxhighlight lang="elixir">defmodule Probabilistic do
@tries 1000000
@probs [aleph: 1/5,
Line 771 ⟶ 1,013:
end
 
Probabilistic.test</langsyntaxhighlight>
 
{{out}}
Line 790 ⟶ 1,032:
The optimized version of Java.
 
<langsyntaxhighlight lang="erlang">
-module(probabilistic_choice).
 
Line 822 ⟶ 1,064:
get_choice(T,Ran - Prob)
end.
</syntaxhighlight>
</lang>
 
Output:
Line 838 ⟶ 1,080:
 
=={{header|ERRE}}==
<langsyntaxhighlight ERRElang="erre">PROGRAM PROB_CHOICE
 
DIM ITEM$[7],PROB[7],CNT[7]
Line 872 ⟶ 1,114:
END FOR
END IF
END PROGRAM</langsyntaxhighlight>
 
Output:
Line 891 ⟶ 1,133:
=={{header|Euphoria}}==
{{trans|PureBasic}}
<langsyntaxhighlight lang="euphoria">constant MAX = #3FFFFFFF
constant times = 1e6
atom d,e
Line 923 ⟶ 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</langsyntaxhighlight>
 
Output:
Line 938 ⟶ 1,180:
 
=={{header|Factor}}==
<langsyntaxhighlight lang="factor">USING: arrays assocs combinators.random io kernel macros math
math.statistics prettyprint quotations sequences sorting formatting ;
IN: rosettacode.proba
Line 974 ⟶ 1,216:
: example ( # data -- )
[ case-probas generate-normalized ]
[ summarize ] bi ; inline</langsyntaxhighlight>
 
In a REPL:
<syntaxhighlight lang="text">USE: rosettacode.proba
1000000 data example</langsyntaxhighlight>
outputs
<syntaxhighlight lang="text"> Key Value expected
heth: 0.063469 0.063456
waw: 0.100226 0.100000
Line 988 ⟶ 1,230:
he: 0.110562 0.111111
aleph: 0.199868 0.200000
gimel: 0.142961 0.142857</langsyntaxhighlight>
 
=={{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}}==
<langsyntaxhighlight lang="forth">include random.fs
 
\ common factors of desired probabilities (1/5 .. 1/11)
Line 1,034 ⟶ 1,347:
f- fabs fs. ;
 
: .results .header 8 0 do i .result loop ;</langsyntaxhighlight>
 
<pre>
Line 1,053 ⟶ 1,366:
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
<langsyntaxhighlight lang="fortran">PROGRAM PROBS
IMPLICIT NONE
Line 1,085 ⟶ 1,398:
WRITE(*, "(A,8F10.6)") "Attained Probability:", REAL(probcount) / REAL(trials)
ENDPROGRAM PROBS</langsyntaxhighlight>
Sample Output:
<pre>
Line 1,094 ⟶ 1,407:
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">' FB 1.05.0 Win64
 
Dim letters (0 To 7) As String = {"aleph", "beth", "gimel", "daleth", "he", "waw", "zayin", "heth"}
Line 1,152 ⟶ 1,465:
Print
Print "Press any key to quit"
Sleep</langsyntaxhighlight>
 
{{out}}
Line 1,164 ⟶ 1,477:
he 0.110772 0.111111
waw 0.100236 0.100000
zayin> 0.090664 0.090909
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}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,233 ⟶ 1,609:
}
fmt.Printf("Totals %8.6f %8.6f\n", totalTarget, totalGenerated)
}</langsyntaxhighlight>
Output:
<pre>
Line 1,249 ⟶ 1,625:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">import System.Random (newStdGen, randomRs)
 
dataBinCounts :: [Float] -> [Float] -> [Int]
dataBinCounts thresholds range =
zipWith
let sampleSize = length range
(-)
xs = ((-) sampleSize . length . flip filter range . (<)) <$> thresholds
in zipWith (-) (xs ++<> [sampleSize]) (0 : xs)
(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 ++<> [1 - sum fractions]
actual =
((/ 1000000.0) . fromIntegral) <$>
<$> dataBinCounts
dataBinCounts (scanl1 (+) expected) (take 1000000 (randomRs (0, 1) g))
(scanl1 (+) expected)
piv n = take n . (++take repeat1000000 (randomRs (0, '1) 'g))
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))
piv 7 l
["aleph", "beth", "gimel", "daleth", "he", "waw", "zayin", "heth"]
<> (piv 13 (show s) <> piv 12 (show c))
)
[ "aleph",
"beth",
"gimel",
"daleth",
"he",
"waw",
"zayin",
"heth"
]
expected
actual</langsyntaxhighlight>
{{Out}}
Sample
Line 1,288 ⟶ 1,685:
 
=={{header|HicEst}}==
<langsyntaxhighlight HicEstlang="hicest">REAL :: trials=1E6, n=8, map(n), limit(n), expected(n), outcome(n)
 
expected = 1 / ($ + 4)
Line 1,304 ⟶ 1,701:
outcome = outcome / trials
 
DLG(Text=expected, Text=outcome, Y=0) </langsyntaxhighlight>
Exported from the spreadsheet-like DLG function:
<pre>0.2 0.199908
Line 1,317 ⟶ 1,714:
=={{header|Icon}} and {{header|Unicon}}==
 
<syntaxhighlight lang="icon">
<lang Icon>
record Item(value, probability)
 
Line 1,368 ⟶ 1,765:
left(count(sample, item.value)/*sample, 6))
end
</syntaxhighlight>
</lang>
 
Output:
Line 1,383 ⟶ 1,780:
 
=={{header|J}}==
<syntaxhighlight lang="j">
<lang J>
main=: verb define
hdr=. ' target actual '
Line 1,400 ⟶ 1,797:
da (distribution of actual values among partitions)
pa (actual proportions)
)</langsyntaxhighlight>
Example use:
<langsyntaxhighlight lang="j">main 1e6
target actual
aleph 0.200000 0.200344
Line 1,411 ⟶ 1,808:
waw 0.100000 0.099751
zayin 0.090909 0.091121
heth 0.063456 0.063527</langsyntaxhighlight>
Note that there is no rounding error in summing the proportions, as they are represented as rational numbers, not floating-point approximations.
<langsyntaxhighlight Jlang="j"> pt=. (, 1-+/)1r1%5+i.7
pt
1r5 1r6 1r7 1r8 1r9 1r10 1r11 1759r27720
+/pt
1</langsyntaxhighlight>
 
=={{header|Java}}==
{{trans|C}}
<langsyntaxhighlight lang="java">public class Prob{
static long TRIALS= 1000000;
 
Line 1,487 ⟶ 1,884:
 
}
}</langsyntaxhighlight>
Output:
<pre>Trials: 1000000
Line 1,494 ⟶ 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+}}
<langsyntaxhighlight lang="java5">import java.util.EnumMap;
 
public class Prob {
Line 1,545 ⟶ 1,942:
return null;
}
}</langsyntaxhighlight>
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,553 ⟶ 1,950:
===ES5===
Fortunately, iterating over properties added to an object maintains the insertion order.
<langsyntaxhighlight lang="javascript">var probabilities = {
aleph: 1/5.0,
beth: 1/6.0,
Line 1,584 ⟶ 1,981:
for (var name in probabilities)
// using WSH
WScript.Echo(name + "\t" + probabilities[name] + "\t" + randomly[name]/iterations);</langsyntaxhighlight>
output:
<pre>aleph 0.2 0.200597
Line 1,598 ⟶ 1,995:
By functional composition:
{{Trans|Haskell}}
<langsyntaxhighlight JavaScriptlang="javascript">(() => {
'use strict';
 
Line 1,703 ⟶ 2,100:
.map(unwords)
.join('\n');
})();</langsyntaxhighlight>
{{Out}}
Sample:
Line 1,715 ⟶ 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).
<syntaxhighlight lang="julia">using Printf
<lang Julia>
 
p = [1/i for i in 5:11]
plen = length(p)
Line 1,748 ⟶ 2,292:
plab[i], accum[i], p[i], r[i]))
end
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,784 ⟶ 2,328:
=={{header|Kotlin}}==
{{trans|FreeBASIC}}
<langsyntaxhighlight lang="scala">// version 1.0.6
 
fun main(args: Array<String>) {
Line 1,821 ⟶ 2,365:
println("\t-------- --------")
println("\t${"%8.6f".format(sumActual)} 1.000000")
}</langsyntaxhighlight>
 
{{out}}
Line 1,840 ⟶ 2,384:
 
=={{header|Liberty BASIC}}==
<syntaxhighlight lang="lb">
<lang lb>
names$="aleph beth gimel daleth he waw zayin heth"
dim sum(8)
Line 1,865 ⟶ 2,409:
print word$(names$, i), using( "#.#####", counter(i) /N), using( "#.#####", 1/(i+4))
next
</syntaxhighlight>
</lang>
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">items = {}
items["aleph"] = 1/5.0
items["beth"] = 1/6.0
Line 1,901 ⟶ 2,445:
for item, _ in pairs( items ) do
print( item, samples[item]/num_trials, items[item] )
end</langsyntaxhighlight>
Output
<pre>gimel 0.142606 0.14285714285714
Line 1,912 ⟶ 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:
<langsyntaxhighlight Mathematicalang="mathematica">choices={{"aleph", 1/5},{"beth", 1/6},{"gimel", 1/7},{"daleth", 1/8},{"he", 1/9},{"waw", 1/10},{"zayin", 1/11},{"heth", 1759/27720}};
data=RandomChoice[choices[[All,2]]->choices[[All,1]],10^6];</langsyntaxhighlight>
To compare the data we use the following code to make a table:
<langsyntaxhighlight Mathematicalang="mathematica">Grid[{#[[1]],N[Count[data,#[[1]]]/10^6],N[#[[2]]]}&/@choices]</langsyntaxhighlight>
gives back (item, attained prob., target prob.):
<pre>aleph 0.200036 0.2
Line 1,930 ⟶ 2,474:
=={{header|MATLAB}}==
{{works with|MATLAB|with Statistics Toolbox}}
<langsyntaxhighlight MATLABlang="matlab">function probChoice
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 1,940 ⟶ 2,484:
choices{k}, T(k, 2), T(k, 3), 100*w(k))
end
end</langsyntaxhighlight>
{{out}}
<pre>Value Count Percent Goal
Line 1,952 ⟶ 2,496:
heth 63171 6.32% 6.35%</pre>
{{works with|MATLAB|without toolboxes}}
<langsyntaxhighlight MATLABlang="matlab">function probChoice
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 1,968 ⟶ 2,512:
choices{k}, results(k), 100*results(k)/nSamp, 100*w(k))
end
end</langsyntaxhighlight>
{{out}}
<pre>Value Count Percent Goal
Line 1,981 ⟶ 2,525:
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">import tables, mathrandom, strutilsstrformat, times
 
const
num_trials = 1000000
precsn = 6
 
var start = cpuTime()
 
const
var probs = initTable[string,float](16)
NumTrials = 1_000_000
probs.add("aleph", 1/5.0)
Probabilities = {"aleph": 1 / 5, "beth": 1 / 6, "gimel": 1 / 7, "daleth": 1 / 8,
probs.add("beth", 1/6.0)
"he": 1 / 9, "waw": 1 / 10, "zayin": 1 / 11, "heth": 1759 / 27720}.toTable
probs.add("gimel", 1/7.0)
 
probs.add("daleth", 1/8.0)
var samples: CountTable[string]
probs.add("he", 1/9.0)
probs.add("waw", 1/10.0)
probs.add("zayin", 1/11.0)
probs.add("heth", 1759/27720)
var samples = initTable[string,int](16)
for i, j in pairs(probs):
samples.add(i,0)
 
randomize()
for i in 1 .. num_trials:
var z = random(1.0)
for j,k in pairs(probs):
if z < probs[j]:
samples[j] = samples[j] + 1
break
else:
z = z - probs[j]
 
for i in 1 .. NumTrials:
var s1, s2: float
var z = rand(1.0)
for item, prob in Probabilities.pairs:
if z < prob:
samples.inc(item)
break
else:
z -= prob
 
var s1, s2 = 0.0
 
echo " Item Target Results Differences"
echo "====== ======== ======== ==========="
for item, prob in Probabilities.pairs:
let r = samples[item] / NumTrials
s1 += r * 100
s2 += prob * 100
echo &"{item:<6} {prob:.6f} {r:.6f} {100 * (1 - r / prob):9.6f} %"
echo "====== ======== ======== "
echo &"Total: {s2:^8.2f} {s1:^8.2f}"
echo &"\nExecution time: {cpuTime()-start:.2f} s"</syntaxhighlight>
 
echo("Item ","\t","Target ","\t","Results ","\t","Difference")
echo("==== ","\t","====== ","\t","======= ","\t","==========")
for i, j in pairs(probs):
s1 += samples[i]/num_trials*100.0
s2 += probs[i]*100.0
echo( i,
"\t", formatFloat(probs[i],ffDecimal,precsn),
"\t", formatFloat(samples[i]/num_trials,ffDecimal,precsn),
"\t", formatFloat(100.0*(1.0-(samples[i]/num_trials)/probs[i]),ffDecimal,precsn),"%")
echo("======","\t","======= ","\t","======== ")
echo("Total:","\t",formatFloat(s2,ffDecimal,2)," \t",formatFloat(s1,ffDecimal,2))
echo("\n",formatFloat(cpuTime()-start,ffDecimal,2)," secs")</lang>
{{out}}
<pre> Item Target Results Difference Differences
====== ======== ======== ===========
he 0.111111 0.110760 111485 -0.316000336500 %
heth 0.063456 0.063777 063758 -0.505881475939 %
zayin 0.090909 0.090811 0.107900 %
beth 0.166667 0.166386 0.168400%
aleph 0.200000 0.200039 -199603 0.019500198500 %
gimel 0.142857 0.142702 0.108600 %
zayin 0.090909 0.090923 -0.015300%
daleth 0.125000 0.124831 0.135200 %
waw 0.100000 0.100513 -0.513000%
beth 0.166667 0.167160 -0.296000 %
gimel 0.142857 0.142691 0.116300%
waw 0.100000 0.099650 0.350000 %
daleth 0.125000 0.124911 0.071200%
====== ======== ========
Total: 100.00 100.00
 
7Execution time: 0.0605 secss</pre>
 
=={{header|OCaml}}==
 
<langsyntaxhighlight lang="ocaml">let p = [
"Aleph", 1.0 /. 5.0;
"Beth", 1.0 /. 6.0;
Line 2,075 ⟶ 2,607:
let d = Hashtbl.find h v in
Printf.printf "%s \t %f %f\n" v p (float d /. float n)
) p</langsyntaxhighlight>
 
Output:
Line 2,088 ⟶ 2,620:
 
=={{header|PARI/GP}}==
<langsyntaxhighlight lang="parigp">pc()={
my(v=[5544,10164,14124,17589,20669,23441,25961,27720],u=vector(8),e);
for(i=1,1e6,
Line 2,101 ⟶ 2,633:
print("Diff: ",u-e);
print("StDev: ",vector(8,i,sqrt(abs(u[i]-v[i])/e[i])));
};</langsyntaxhighlight>
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">use List::Util qw(first sum);
use constant TRIALS => 1e6;
 
Line 2,141 ⟶ 2,673:
$_, $results{$_}/TRIALS, $ps{$_},
abs($results{$_}/TRIALS - $ps{$_});
}</langsyntaxhighlight>
 
Sample output:
Line 2,154 ⟶ 2,686:
zayin 0.091014 0.090909 0.000105
heth 0.063731 0.063456 0.000275</pre>
 
=={{header|Perl 6}}==
{{works with|rakudo|2015-10-20}}
<lang perl6>constant TRIALS = 1e6;
constant @event = <aleph beth gimel daleth he waw zayin heth>;
constant @P = flat (1 X/ 5 .. 11), 1759/27720;
constant @cP = [\+] @P;
my @results;
@results[ @cP.first: { $_ > once rand }, :k ]++ xx TRIALS;
say 'Event Occurred Expected Difference';
for ^@results {
my ($occurred, $expected) = @results[$_], @P[$_] * TRIALS;
printf "%-9s%8.0f%9.1f%12.1f\n",
@event[$_],
$occurred,
$expected,
abs $occurred - $expected;
}</lang>
{{out}}
<pre>Event Occurred Expected Difference
aleph 200369 200000.0 369.0
beth 167005 166666.7 338.3
gimel 142690 142857.1 167.1
daleth 125061 125000.0 61.0
he 110563 111111.1 548.1
waw 100214 100000.0 214.0
zayin 90617 90909.1 292.1
heth 63481 63456.0 25.0</pre>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>constant {names, probs} = columnize({{"aleph", 1/5},
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
{"beth", 1/6},
<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>
{"gimel", 1/7},
<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>
{"daleth", 1/8},
<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>
{"he", 1/9},
<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>
{"waw", 1/10},
<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>
{"zayin", 1/11},
<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>
{"heth", 1759/27720}})
<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>
sequence results = repeat(0,length(names))
<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>
atom r
<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>
constant lim = 1000000
<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>
for j=1 to lim do
<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>
r = rnd()
<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>
for i=1 to length(probs) do
<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>
r -= probs[i]
<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>
if r<=0 then
results[i]+ <span style=1"color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
exit
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for
end for
<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>
printf(1," Name Actual Expected\n")
<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>
for i=1 to length(probs) do
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
printf(1,"%6s %8.6f %8.6f\n",{names[i],results[i]/lim,probs[i]})
<!--</syntaxhighlight>-->
end for</lang>
{{out}}
<pre>
Line 2,228 ⟶ 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}}==
<langsyntaxhighlight PicoLisplang="picolisp">(let (Count 1000000 Denom 27720 N Denom)
(let Probs
(mapcar
Line 2,246 ⟶ 2,790:
(cdddr X)
(format (cadr X) 6)
(format (caddr X) 6) ) ) ) ) )</langsyntaxhighlight>
Output:
<pre> Probability Result
Line 2,259 ⟶ 2,803:
 
=={{header|PL/I}}==
<langsyntaxhighlight lang="pli"> probch: Proc Options(main);
Dcl prob(8) Dec Float(15) Init((1/5.0), /* aleph */
(1/6.0), /* beth */
Line 2,303 ⟶ 2,847:
Put Edit(what(i),cnt(i),pr,prob(i))(Skip,a,f(10),x(2),2(f(11,8)));
End;
End;</langsyntaxhighlight>
{{out}}
<pre>One million trials
Line 2,332 ⟶ 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">
<lang PowerShell>
$character = [PSCustomObject]@{
aleph = [PSCustomObject]@{Expected=1/5 ; Alpha="א"}
Line 2,379 ⟶ 2,923:
}
}
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 2,395 ⟶ 2,939:
 
=={{header|PureBasic}}==
<langsyntaxhighlight PureBasiclang="purebasic">#times=1000000
 
Structure Item
Line 2,436 ⟶ 2,980:
Print(#CRLF$+"Press ENTER to exit"):Input()
CloseConsole()
EndIf</langsyntaxhighlight>
 
Output may look like
Line 2,454 ⟶ 2,998:
=={{header|Python}}==
Two different algorithms are coded.
<langsyntaxhighlight lang="python">import random, bisect
 
def probchoice(items, probs):
Line 2,517 ⟶ 3,061:
probs[-1] = 1-sum(probs[:-1])
tester(probchoice, items, probs, 1000000)
tester(probchoice2, items, probs, 1000000)</langsyntaxhighlight>
 
Sample output:
Line 2,536 ⟶ 3,080:
Target probability: 0.200000,0.166667,0.142857,0.125000,0.111111,0.100000,0.090909,0.063456
Attained probability: 0.199720,0.166424,0.142474,0.124561,0.111511,0.100313,0.091316,0.063681</pre>
 
=={{header|Quackery}}==
 
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.
 
<syntaxhighlight lang="quackery"> [ $ "bigrat.qky" loadfile ] now!
 
( --------------- zen object orientation -------------- )
 
[ immovable
]this[ swap do ]done[ ] is object ( [ --> )
 
[ ]'[ ] is method ( --> [ )
 
[ method
[ dup share
swap put ] ] is localise ( --> )
 
[ method [ release ] ] is delocalise ( --> )
 
 
( ------------------ rand-gen methods ----------------- )
 
[ method
[ dup take
2 split drop
' [ 0 0 ] join
swap put ] ] is reset-gen ( --> [ )
 
[ method
[ dup take
dup 2 peek 1+
swap 2 poke
dup 1 peek random
over 0 peek <
if
[ dup 3 peek 1+
swap 3 poke ]
swap put ] ] is rand-gen ( --> [ )
 
[ method
[ dup echo say ": "
share
dup 2 peek dup echo
say " trials" cr
say " Actual: "
over 3 peek
swap 10 point$ echo$ cr
say " Expected: "
dup 0 peek
swap 1 peek
10 point$ echo$ cr
cr ] ] is report ( --> [ )
 
 
( ------------------ rand-gen objects ----------------- )
 
[ object [ 1 5 0 0 ] ] is aleph ( [ --> )
[ object [ 1 6 0 0 ] ] is beth ( [ --> )
[ object [ 1 7 0 0 ] ] is gimel ( [ --> )
[ object [ 1 8 0 0 ] ] is daleth ( [ --> )
[ object [ 1 9 0 0 ] ] is he ( [ --> )
[ object [ 1 10 0 0 ] ] is waw ( [ --> )
[ object [ 1 11 0 0 ] ] is zayin ( [ --> )
[ object [ 1759 27720 0 0 ] ] is heth ( [ --> )
 
 
' [ aleph beth gimel daleth he waw zayin heth ]
 
dup witheach [ reset-gen swap do ]
 
dup witheach
[ 1000000 times
[ rand-gen over do ]
drop ]
 
witheach [ report swap do ]</syntaxhighlight>
 
{{out}}
 
<pre>aleph: 1000000 trials
Actual: 0.199454
Expected: 0.2
 
beth: 1000000 trials
Actual: 0.166854
Expected: 0.1666666667
 
gimel: 1000000 trials
Actual: 0.142329
Expected: 0.1428571429
 
daleth: 1000000 trials
Actual: 0.12457
Expected: 0.125
 
he: 1000000 trials
Actual: 0.111143
Expected: 0.1111111111
 
waw: 1000000 trials
Actual: 0.100061
Expected: 0.1
 
zayin: 1000000 trials
Actual: 0.090979
Expected: 0.0909090909
 
heth: 1000000 trials
Actual: 0.063131
Expected: 0.0634559885</pre>
 
=={{header|R}}==
<langsyntaxhighlight Rlang="r">prob = c(aleph=1/5, beth=1/6, gimel=1/7, daleth=1/8, he=1/9, waw=1/10, zayin=1/11, heth=1759/27720)
# Note that R doesn't actually require the weights
# vector for rmultinom to sum to 1.
Line 2,545 ⟶ 3,200:
Requested = prob,
Obtained = hebrew/sum(hebrew))
print(d)</langsyntaxhighlight>
 
Sample output:
Line 2,559 ⟶ 3,214:
 
A histogram of the data is also possible using, for example,
<langsyntaxhighlight Rlang="r">library(ggplot2)
qplot(factor(names(prob), levels = names(prob)), hebrew, geom = "histogram")</langsyntaxhighlight>
 
=={{header|Racket}}==
Line 2,571 ⟶ 3,226:
as a module. Either run the program in DrRacket or run `raco test prob-choice.rkt`
 
<langsyntaxhighlight lang="racket">#lang racket
;;; returns a probabalistic choice from the sequence choices
;;; choices generates two values -- the chosen value and a
Line 2,657 ⟶ 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))</langsyntaxhighlight>
Output (note that the progress counts, which go to standard error, are
interleaved with the output on standard out)
Line 2,688 ⟶ 3,343:
zayin 90478 1000000/11 45239/500000 -0.47%
he 111275 1000000/9 4451/40000 0.15%</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2018.10}}
<syntaxhighlight lang="raku" line>constant TRIALS = 1e6;
constant @event = <aleph beth gimel daleth he waw zayin heth>;
constant @P = flat (1 X/ 5 .. 11), 1759/27720;
constant @cP = [\+] @P;
my atomicint @results[+@event];
(^TRIALS).race.map: { @results[ @cP.first: { $_ > once rand }, :k ]⚛++; }
 
say 'Event Occurred Expected Difference';
for ^@results {
my ($occurred, $expected) = @results[$_], @P[$_] * TRIALS;
printf "%-9s%8.0f%9.1f%12.1f\n",
@event[$_],
$occurred,
$expected,
abs $occurred - $expected;
}</syntaxhighlight>
{{out}}
<pre>Event Occurred Expected Difference
aleph 200369 200000.0 369.0
beth 167005 166666.7 338.3
gimel 142690 142857.1 167.1
daleth 125061 125000.0 61.0
he 110563 111111.1 548.1
waw 100214 100000.0 214.0
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}}==
Note: &nbsp; REXX can generate random numbers up to a range of &nbsp; 100,000.
 
<lang rexx>/*REXX program displays results of probabilistic choices, gen random #s per probability.*/
A little extra REXX code was added to provide head and foot titles along with the totals.
<syntaxhighlight lang="rexx">/*REXX program displays results of probabilistic choices, gen random #s per probability.*/
parse arg trials digs seed . /*obtain the optional arguments from CL*/
if trials=='' | trials=="," then trials=1000000 +1e6 /*Not specified? Then use the default.*/
if digs=='' | digs=="," then digs=15 15 /* " " " " " " */
if datatype(seed, 'W') then call random ,,seed /*allows repeatability for RANDOM nums.*/
numeric digits digs /*use a specific number of decimal digs*/
names= 'aleph beth gimel daleth he waw zayin heth ───totals───►' /*names of the cells.*/
HIhi=100000 100000 /*max REXX RANDOM num*/
z= words(names); #=z - 1 #= z - 1 /*#≡the: the number of actual/useableusable names.*/
$=0 0 /*initialize sum of the probabilities. */
do n=1 for #; prob.n= 1 / (n+4); if n==# then prob.n= 1759 / 27720
$= $ + prob.n; Hprob.n= prob.n * HIhi /*spread the range of probabilities. */
end /*n*/
prob.z=$ $ /*define the value of the ───totals───.*/
@.=0 0 /*initialize all counters in the range.*/
@.z=trials trials /*define the last counter of " " */
do j=1 for trials; r= random(HIhi) /*gen TRIAL number of random numbers.*/
do k=1 for # /*for each cell, compute percentages. */
if r<=Hprob.k then @.k= @.k + 1 /* " " " range, bump the counter*/
end /*k*/
end /*j*/
_= '═' /*_: a literalpadding used forby the CENTER BIF padBIF.*/
w= digs + 6 /*W: display width for the percentages*/
d= 4 + max( length(trials), length('count') ) /* [↓] display a formatted top header.*/
say center('name',15,_) center('count',d,_) center('target %',w,_) center('actual %',w,_)
 
do cell=1 for z /*display each of the cells and totals.*/
say ' ' left( word(names, cell), 13) right(@.cell, d-2) " " ,
left( format( prob.cell * 100, d), w-2) ,
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 displayin ait, formatted footwe headerare all done.*/</syntaxhighlight>
/*stick a fork in it, we are all done.*/</lang>
{{out|output|text=&nbsp; when using the default input:}}
<pre>
Line 2,740 ⟶ 3,486:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project : Probabilistic choice
 
Line 2,763 ⟶ 3,509:
see "" + item[i] + " " + cnt[i]/1000000 + " " + prob[i] + nl
next
</syntaxhighlight>
</lang>
Output:
<pre>
Line 2,778 ⟶ 3,524:
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">probabilities = {
"aleph" => 1/5.0,
"beth" => 1/6.0,
Line 2,814 ⟶ 3,560:
val = probabilities[k]
printf "%-8s%.8f %.8f %6.3f %%\n", k, val, act, 100*(act-val)/val
end</langsyntaxhighlight>
 
{{out}}
Line 2,830 ⟶ 3,576:
 
=={{header|Rust}}==
<langsyntaxhighlight Rustlang="rust">extern crate rand;
 
use rand::distributions::{IndependentSample, Sample, Weighted, WeightedChoice};
Line 2,956 ⟶ 3,702:
let counts = take_samples(&mut rng, &wc);
print_mapping(&counts);
}</langsyntaxhighlight>
{{out}}
<pre> ~~~ U32 METHOD ~~~
Line 2,984 ⟶ 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).
<langsyntaxhighlight Scalalang="scala">object ProbabilisticChoice extends App {
import scala.collection.mutable.LinkedHashMap
 
Line 3,047 ⟶ 3,793:
println("Checking weighted frequencies:")
check(frequencies.map{case (a, b) => a -> b.toDouble}, for (i <- 1 to 1000000) yield weightedFreq(frequencies))
}</langsyntaxhighlight>
{{out}}
<pre>Checking weighted probabilities:
Line 3,070 ⟶ 3,816:
'heth 0.0630 0.0632 ok
1.0000 1.0000</pre>
 
=={{header|Seed7}}==
To reduce the runtime this program should be compiled.
<lang seed7>$ include "seed7_05.s7i";
include "float.s7i";
 
const type: letter is new enum
aleph, beth, gimel, daleth, he, waw, zayin, heth
end enum;
 
const func string: str (in letter: aLetter) is
return [] ("aleph", "beth", "gimel", "daleth", "he", "waw", "zayin", "heth") [succ(ord(aLetter))];
 
enable_output(letter);
 
const array [letter] integer: table is [letter] (
5544, 4620, 3960, 3465, 3080, 2772, 2520, 1759);
 
const func letter: randomLetter is func
result
var letter: resultLetter is aleph;
local
var integer: number is 0;
begin
number := rand(1, 27720);
while number > table[resultLetter] do
number -:= table[resultLetter];
incr(resultLetter);
end while;
end func;
 
const proc: main is func
local
var integer: count is 0;
var letter: aLetter is aleph;
var array [letter] integer: occurrence is letter times 0;
begin
for count range 1 to 1000000 do
aLetter := randomLetter;
incr(occurrence[aLetter]);
end for;
writeln("Name Count Ratio Expected");
for aLetter range letter.first to letter.last do
writeln(aLetter rpad 7 <& occurrence[aLetter] lpad 6 <&
flt(occurrence[aLetter]) / 10000.9 digits 4 lpad 8 <& "%" <&
100.0 * flt(table[aLetter]) / 27720.0 digits 4 lpad 8 <& "%");
end for;
end func;</lang>
 
Outout:
<pre>
Name Count Ratio Expected
aleph 199788 19.9770% 20.0000%
beth 166897 16.6882% 16.6667%
gimel 143103 14.3090% 14.2857%
daleth 125060 12.5049% 12.5000%
he 110848 11.0838% 11.1111%
waw 99550 9.9541% 10.0000%
zayin 90918 9.0910% 9.0909%
heth 63836 6.3830% 6.3456%
</pre>
 
=={{header|Scheme}}==
Line 3,136 ⟶ 3,821:
Using guile scheme 2.0.11.
 
<langsyntaxhighlight lang="scheme">(use-modules (ice-9 format))
 
(define (random-choice probs)
Line 3,180 ⟶ 3,865:
(he 1/9) (waw 1/10) (zayin 1/11) (heth 1759/27720)))
 
(format-results probs (choices 1000000 probs))</langsyntaxhighlight>
 
Example output:
Line 3,192 ⟶ 3,877:
zayin 0.09091 0.09096
heth 0.06346 0.06313
 
=={{header|Seed7}}==
To reduce the runtime this program should be compiled.
<syntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "float.s7i";
 
const type: letter is new enum
aleph, beth, gimel, daleth, he, waw, zayin, heth
end enum;
 
const func string: str (in letter: aLetter) is
return [] ("aleph", "beth", "gimel", "daleth", "he", "waw", "zayin", "heth") [succ(ord(aLetter))];
 
enable_output(letter);
 
const array [letter] integer: table is [letter] (
5544, 4620, 3960, 3465, 3080, 2772, 2520, 1759);
 
const func letter: randomLetter is func
result
var letter: resultLetter is aleph;
local
var integer: number is 0;
begin
number := rand(1, 27720);
while number > table[resultLetter] do
number -:= table[resultLetter];
incr(resultLetter);
end while;
end func;
 
const proc: main is func
local
var integer: count is 0;
var letter: aLetter is aleph;
var array [letter] integer: occurrence is letter times 0;
begin
for count range 1 to 1000000 do
aLetter := randomLetter;
incr(occurrence[aLetter]);
end for;
writeln("Name Count Ratio Expected");
for aLetter range letter.first to letter.last do
writeln(aLetter rpad 7 <& occurrence[aLetter] lpad 6 <&
flt(occurrence[aLetter]) / 10000.9 digits 4 lpad 8 <& "%" <&
100.0 * flt(table[aLetter]) / 27720.0 digits 4 lpad 8 <& "%");
end for;
end func;</syntaxhighlight>
 
Outout:
<pre>
Name Count Ratio Expected
aleph 199788 19.9770% 20.0000%
beth 166897 16.6882% 16.6667%
gimel 143103 14.3090% 14.2857%
daleth 125060 12.5049% 12.5000%
he 110848 11.0838% 11.1111%
waw 99550 9.9541% 10.0000%
zayin 90918 9.0910% 9.0909%
heth 63836 6.3830% 6.3456%
</pre>
 
=={{header|Sidef}}==
{{trans|Perl}}
<langsyntaxhighlight lang="ruby">define TRIALS = 1e4;
 
func prob_choice_picker(options) {
Line 3,235 ⟶ 3,981:
abs(v/TRIALS - ps{k})
);
}</langsyntaxhighlight>
 
{{out}}
Line 3,249 ⟶ 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}}==
<langsyntaxhighlight lang="stata">clear
mata
letters="aleph","beth","gimel","daleth","he","waw","zayin","heth"
Line 3,258 ⟶ 4,068:
st_addvar("str10","a")
st_sstore(.,.,a)
end</langsyntaxhighlight>
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
 
set map [dict create]
Line 3,297 ⟶ 4,107:
]
}
}</langsyntaxhighlight>
<pre>using 1000000 samples:
expected actual difference
Line 3,315 ⟶ 4,125:
implemented by the run time system.
 
<langsyntaxhighlight Ursalalang="ursala">#import std
#import nat
#import flo
Line 3,332 ⟶ 4,142:
#show+
 
results = format simulation 1000000</langsyntaxhighlight>
output:
<pre>
Line 3,347 ⟶ 4,157:
=={{header|VBScript}}==
Derived from the BBC BASIC version
<syntaxhighlight lang="vb">
<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,379 ⟶ 4,189:
WScript.StdOut.Write item(i) & vbTab & FormatNumber(cnt(i)/1000000,6) & vbTab & FormatNumber(prob(i),6)
WScript.StdOut.WriteLine
Next</langsyntaxhighlight>
 
{{out}}
Line 3,392 ⟶ 4,202:
zayin 0.090745 0.090909
heth 0.063705 0.063456
</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "random" for Random
import "./fmt" for Fmt
 
var letters = ["aleph", "beth", "gimel", "daleth", "he", "waw", "zayin", "heth"]
var actual = [0] * 8
var probs = [1/5, 1/6, 1/7, 1/8, 1/9, 1/10, 1/11, 0]
var cumProbs = [0] * 8
 
cumProbs[0] = probs[0]
for (i in 1..6) cumProbs[i] = cumProbs[i-1] + probs[i]
cumProbs[7] = 1
probs[7] = 1 - cumProbs[6]
var n = 1e6
var rand = Random.new()
(1..n).each { |i|
var r = rand.float()
var index = (r <= cumProbs[0]) ? 0 :
(r <= cumProbs[1]) ? 1 :
(r <= cumProbs[2]) ? 2 :
(r <= cumProbs[3]) ? 3 :
(r <= cumProbs[4]) ? 4 :
(r <= cumProbs[5]) ? 5 :
(r <= cumProbs[6]) ? 6 : 7
actual[index] = actual[index] + 1
}
 
var sumActual = 0
System.print("Letter\t Actual Expected")
System.print("------\t-------- --------")
for (i in 0..7) {
var generated = actual[i]/n
Fmt.print("$s\t$8.6f $8.6f", letters[i], generated, probs[i])
sumActual = sumActual + generated
}
System.print("\t-------- --------")
Fmt.print("\t$8.6f 1.000000", sumActual)</syntaxhighlight>
 
{{out}}
Sample run:
<pre>
Letter Actual Expected
------ -------- --------
aleph 0.200037 0.200000
beth 0.166643 0.166667
gimel 0.143012 0.142857
daleth 0.125219 0.125000
he 0.111183 0.111111
waw 0.099510 0.100000
zayin 0.091015 0.090909
heth 0.063381 0.063456
-------- --------
1.000000 1.000000
</pre>
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">include c:\cxpl\codes;
def Size = 10_000_000;
int Tbl(12+1);
Line 3,421 ⟶ 4,288:
");
RlOut(0, S0); RlOut(0, S1);
]</langsyntaxhighlight>
 
Output:
Line 3,436 ⟶ 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}}
<langsyntaxhighlight lang="zkl">var names=T("aleph", "beth", "gimel", "daleth",
"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,460 ⟶ 4,384:
"%6s%7d %7.4f%% %7.4f%%".fmt(names[i], r[i], r[i]/M*100,
ptable[i]*100).println();
}</langsyntaxhighlight>
{{out}}
<pre>
1,983

edits