Data update
This commit is contained in:
parent
4bb20c9b71
commit
cbaf4c4b64
12390 changed files with 318560 additions and 27248 deletions
|
|
@ -0,0 +1,43 @@
|
|||
BEGIN # Dice game probabilities - translation of Action! #
|
||||
|
||||
PROC roll = ( INT sides, ndice )INT:
|
||||
BEGIN
|
||||
INT sum := 0;
|
||||
FOR i TO ndice DO
|
||||
sum +:= ENTIER ( random * sides ) + 1
|
||||
OD;
|
||||
sum
|
||||
END # roll # ;
|
||||
|
||||
PROC test = ( INT sides1, ndice1, sides2, ndice2 )VOID:
|
||||
BEGIN
|
||||
INT wins1 := 0, wins2 := 0, draws := 0;
|
||||
INT count = 10 000;
|
||||
|
||||
TO count DO
|
||||
INT sum1 = roll( sides1, ndice1 );
|
||||
INT sum2 = roll( sides2, ndice2 );
|
||||
IF sum1 > sum2 THEN
|
||||
wins1 +:= 1
|
||||
ELIF sum1 < sum2 THEN
|
||||
wins2 +:= 1
|
||||
ELSE
|
||||
draws +:= 1
|
||||
FI
|
||||
OD;
|
||||
|
||||
print( ( "After ", whole( count, 0 ), " rolls", newline ) );
|
||||
print( ( "Player 1 with ", whole( ndice1, 0 ) ) );
|
||||
print( ( " dice of ", whole( sides1, 0 ), " sides", newline ) );
|
||||
print( ( "Player 2 with ", whole( ndice2, 0 ) ) );
|
||||
print( ( " dice of ", whole( sides2, 0 ), " sides", newline ) );
|
||||
print( ( " Player 1 wins ", whole( wins1, 0 ), " times", newline ) );
|
||||
print( ( " Player 2 wins ", whole( wins2, 0 ), " times", newline ) );
|
||||
print( ( " they draw ", whole( draws, 0 ), " times", newline ) );
|
||||
print( ( "Probability of Player 1 beating Player 2:" ) );
|
||||
print( ( fixed( wins2 / wins1, -7, 4 ), newline, newline ) )
|
||||
END # test # ;
|
||||
|
||||
test( 4, 9, 6, 6 );
|
||||
test( 10, 5, 7, 6 )
|
||||
END
|
||||
57
Task/Dice-game-probabilities/Ada/dice-game-probabilities.adb
Normal file
57
Task/Dice-game-probabilities/Ada/dice-game-probabilities.adb
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
with Ada.Text_IO; use Ada.Text_IO;
|
||||
with Ada.Numerics.Discrete_Random;
|
||||
|
||||
procedure Main is
|
||||
package real_io is new Float_IO (Long_Float);
|
||||
use real_io;
|
||||
|
||||
type Dice is record
|
||||
Faces : Positive;
|
||||
Num_Dice : Positive;
|
||||
end record;
|
||||
|
||||
procedure Roll_Dice (The_Dice : in Dice; Count : out Natural) is
|
||||
subtype Faces is Integer range 1 .. The_Dice.Faces;
|
||||
package Die_Random is new Ada.Numerics.Discrete_Random (Faces);
|
||||
use Die_Random;
|
||||
Seed : Generator;
|
||||
begin
|
||||
Reset (Seed);
|
||||
Count := 0;
|
||||
for I in 1 .. The_Dice.Num_Dice loop
|
||||
Count := Count + Random (Seed);
|
||||
end loop;
|
||||
end Roll_Dice;
|
||||
|
||||
function Win_Prob
|
||||
(Dice_1 : Dice; Dice_2 : Dice; Tries : Positive) return Long_Float
|
||||
is
|
||||
Count_1 : Natural := 0;
|
||||
Count_2 : Natural := 0;
|
||||
Count_1_Wins : Natural := 0;
|
||||
begin
|
||||
for I in 1 .. Tries loop
|
||||
Roll_Dice (Dice_1, Count_1);
|
||||
Roll_Dice (Dice_2, Count_2);
|
||||
if Count_1 > Count_2 then
|
||||
Count_1_Wins := Count_1_Wins + 1;
|
||||
end if;
|
||||
end loop;
|
||||
return Long_Float (Count_1_Wins) / Long_Float (Tries);
|
||||
end Win_Prob;
|
||||
|
||||
D1 : Dice := (Faces => 4, Num_Dice => 9);
|
||||
D2 : Dice := (Faces => 6, Num_Dice => 6);
|
||||
D3 : Dice := (Faces => 10, Num_Dice => 5);
|
||||
D4 : Dice := (Faces => 7, Num_Dice => 6);
|
||||
|
||||
P1 : Long_Float := Win_Prob (D1, D2, 1_000_000);
|
||||
P2 : Long_Float := Win_Prob (D3, D4, 1_000_000);
|
||||
begin
|
||||
Put ("Dice D1 wins = ");
|
||||
Put (Item => P1, Fore => 1, Aft => 7, Exp => 0);
|
||||
New_Line;
|
||||
Put ("Dice D2 wins = ");
|
||||
Put (Item => P2, Fore => 1, Aft => 7, Exp => 0);
|
||||
New_Line;
|
||||
end Main;
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
// Dice game probabilities. Nigel Galloway: March 31st., 2026
|
||||
let r=new System.Random()
|
||||
let fG n g=List.init n (fun _->r.Next(g)+1)|>List.sum
|
||||
let fN i g e l=Seq.init 1000000 (fun _->(fG i g),(fG e l))|>Seq.filter(fun(n,g)->n>g)|>Seq.length
|
||||
printfn "Player 1 had 9 4 sided dice, Player 2 had 6 6 sided dice->Player 1 won %A percent of the time." (float (fN 9 4 6 6)/10000.0)
|
||||
printfn "Player 1 had 5 10 sided dice, Player 2 had 6 7 sided dice->Player 1 won %A percent of the time." (float (fN 5 10 6 7)/10000.0)
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
! Dice game probabilities
|
||||
! tested with Intel ifx (IFX) 2025.2.1 20250806 on Kubuntu 25.10
|
||||
! GNU Fortran (Ubuntu 15.2.0-4ubuntu4) 15.2.0 on Kubuntu 25.10
|
||||
! VSI Fortran x86-64 V8.7-001 on OpenVMS x86_64 V9.2-3
|
||||
! No Non-standard features used, should compile on any fairly recent Fortran.
|
||||
! U.B., February 2026
|
||||
!=========================================================================================
|
||||
program DiceGame
|
||||
|
||||
implicit none
|
||||
|
||||
integer, parameter :: longInteger=8, double=8
|
||||
|
||||
write (*,'(1x,F19.14)') beating_probability(4_longInteger, 9_longInteger, 6_longInteger, 6_longInteger)
|
||||
write (*,'(1x,F19.14)') beating_probability(10_longInteger, 5_longInteger, 7_longInteger, 6_longInteger)
|
||||
|
||||
contains
|
||||
|
||||
! =================================================================================
|
||||
! count all possible Results of both players
|
||||
! then see how often player 1 has sum larger than player 2's sum
|
||||
! Probability that Player 1 wins is this number divided by nuimber of all possible
|
||||
! outcomes of both players combined.
|
||||
! =================================================================================
|
||||
|
||||
function beating_probability (nSides1, nDice1, nSides2, nDice2) result (tot)
|
||||
|
||||
integer (kind=longInteger), intent(in) :: nSides1, nDice1, nSides2, nDice2
|
||||
real (kind=double) :: tot
|
||||
|
||||
real (kind=double) :: p12
|
||||
integer (kind=longInteger) :: i, j
|
||||
|
||||
! Counters for all possible sums of all dice of Players 1 and 2 (index is sum)
|
||||
! sum can go from nDice up to nDice * nSides (incl)
|
||||
integer (kind=longInteger), dimension (nSides1 * nDice1) :: C1 ! C1(1...nDice1-1) unused, always 0
|
||||
integer (kind=longInteger), dimension (nSides2 * nDice2) :: C2 ! C2(1...nDice2-1) unused, always 0
|
||||
|
||||
! Initialise counters
|
||||
C1=0_longInteger
|
||||
C2=0_longInteger
|
||||
|
||||
! count sums of all combinations separately for Player 1 and Player 2
|
||||
call throw_die (nSides1, nDice1, 0_longInteger, C1)
|
||||
call throw_die (nSides2, nDice2, 0_longInteger, C2)
|
||||
|
||||
p12 = nSides1 ** nDice1 * nSides2 ** nDice2 ! Number of of all possible combinations
|
||||
tot = 0._double
|
||||
|
||||
! for all of player 1's potential dice sums, find out how often they win
|
||||
! against player 2
|
||||
do i=nDice1, nSides1 * nDice1 ! For each of Player 1's sums
|
||||
! C1(i) is count of player 1's sum being i,
|
||||
! see how many combinations of player 2 are smaller than this combi:
|
||||
! Max sum2 is C1(i)-1 or Size(C2), whatever is smaller
|
||||
do j=nDice2, min(i-1, nSides2*nDice2)
|
||||
! C2(j) is count for player 2's sum being j
|
||||
! partial probability of combination (i,j) is (C1(i) * C2(j) / all possible results), add up to total prob.
|
||||
tot =tot + real(C1(i)*C2(j), double) / p12
|
||||
enddo
|
||||
enddo
|
||||
end function beating_probability
|
||||
|
||||
! ====================================================================
|
||||
! Throw all dices: construct all possible combinations of the dice.
|
||||
! Variable "sum" is the accumulated result of of all nDice dice.
|
||||
! Variable "counts(sum)" counts how many times a particular sum occurs
|
||||
! ====================================================================
|
||||
recursive subroutine throw_die (nSides, nDice, sum, counts)
|
||||
|
||||
integer (kind=longInteger), intent(in) :: nSides, nDice, sum
|
||||
integer(kind=longInteger), dimension(*) , intent(inout) :: counts
|
||||
integer (kind=longInteger) :: i
|
||||
|
||||
if (nDice .eq. 0) then
|
||||
! All dice have been thrown. "sum" is the result of all dice added up.
|
||||
! in this particular constellation. Increment the sum's counter
|
||||
counts(sum) = counts(sum) + 1_longInteger
|
||||
else
|
||||
! construct all combinations of a dice: take the value of the faces of this
|
||||
! dice plus the combination of the (nDice-1) remaining dice
|
||||
do i=1, nSides
|
||||
call throw_die (nSides, nDice-1, sum+i, counts)
|
||||
enddo
|
||||
endif
|
||||
end subroutine throw_die
|
||||
|
||||
end program DiceGame
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
import gleam/int
|
||||
|
||||
pub fn main() {
|
||||
echo probability(9, 4, 6, 6)
|
||||
echo probability(5, 10, 6, 7)
|
||||
}
|
||||
|
||||
/// Returns the probability that rolling `a` dice with `b` sides will
|
||||
/// have a higher total than rolling `c` dice with `d` sides.
|
||||
///
|
||||
pub fn probability(a: Int, b: Int, c: Int, d: Int) -> Float {
|
||||
probability_loop(a, b, c, d, 10_000, 0)
|
||||
}
|
||||
|
||||
fn probability_loop(a, b, c, d, iter, wins) -> Float {
|
||||
case iter, roll(a, b) > roll(c, d) {
|
||||
0, _ -> int.to_float(wins) /. 10_000.0
|
||||
_, True -> probability_loop(a, b, c, d, iter - 1, wins + 1)
|
||||
_, False -> probability_loop(a, b, c, d, iter - 1, wins)
|
||||
}
|
||||
}
|
||||
|
||||
/// Rolls some dice with the given number of sides and returns their total.
|
||||
///
|
||||
fn roll(dice: Int, sides: Int) -> Int {
|
||||
roll_loop(dice, sides, 0)
|
||||
}
|
||||
|
||||
fn roll_loop(dice, sides, total) -> Int {
|
||||
case dice {
|
||||
0 -> total
|
||||
_ -> roll_loop(dice - 1, sides, total + int.random(sides) + 1)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
MODULE DiceGameProbabilities; (* Dice game probabilities - translation of Action! *)
|
||||
IMPORT Out, RandomNumbers;
|
||||
|
||||
PROCEDURE roll( sides, ndice : INTEGER ) : INTEGER;
|
||||
VAR sum, i : INTEGER;
|
||||
BEGIN
|
||||
sum := 0;
|
||||
FOR i := 1 TO ndice DO
|
||||
INC( sum, RandomNumbers.randomInt( sides ) + 1 )
|
||||
END
|
||||
RETURN sum
|
||||
END roll ;
|
||||
|
||||
PROCEDURE test( sides1, ndice1, sides2, ndice2 : INTEGER );
|
||||
CONST count = 10000;
|
||||
VAR wins1, wins2, draws, i, sum1, sum2 : INTEGER;
|
||||
|
||||
PROCEDURE OutSNS( t1 : ARRAY OF CHAR; n : INTEGER; t2 : ARRAY OF CHAR );
|
||||
BEGIN
|
||||
Out.String( t1 );Out.Int( n, 0 );Out.String( t2 )
|
||||
END OutSNS ;
|
||||
|
||||
BEGIN
|
||||
wins1 := 0; wins2 := 0; draws := 0;
|
||||
FOR i := 1 TO count DO
|
||||
sum1 := roll( sides1, ndice1 );
|
||||
sum2 := roll( sides2, ndice2 );
|
||||
IF sum1 > sum2 THEN
|
||||
INC( wins1 )
|
||||
ELSIF sum1 < sum2 THEN
|
||||
INC( wins2 )
|
||||
ELSE
|
||||
INC( draws )
|
||||
END
|
||||
END;
|
||||
|
||||
OutSNS( "After ", count, " rolls" );Out.Ln;
|
||||
OutSNS( "Player 1 with ", ndice1, "" );
|
||||
OutSNS( " dice of ", sides1, " sides" );Out.Ln;
|
||||
OutSNS( "Player 2 with ", ndice2, "" );
|
||||
OutSNS( " dice of ", sides2, " sides" );Out.Ln;
|
||||
OutSNS( " Player 1 wins ", wins1, " times" );Out.Ln;
|
||||
OutSNS( " Player 2 wins ", wins2, " times" );Out.Ln;
|
||||
OutSNS( " they draw ", draws, " times" );Out.Ln;
|
||||
Out.String( "Probability of Player 1 beating Player 2:" );
|
||||
Out.Real( FLT( wins2 ) / FLT( wins1 ), 12 );Out.Ln;Out.Ln
|
||||
END test ;
|
||||
|
||||
BEGIN
|
||||
test( 4, 9, 6, 6 );
|
||||
test( 10, 5, 7, 6 )
|
||||
END DiceGameProbabilities.
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
require "table2"
|
||||
|
||||
local function throw_die(nsides, ndice, s, counts)
|
||||
if ndice == 0 then
|
||||
counts[s + 1] += 1
|
||||
return
|
||||
end
|
||||
for i = 1, nsides do throw_die(nsides, ndice - 1, s + i, counts) end
|
||||
end
|
||||
|
||||
local function beating_probability(nsides1, ndice1, nsides2, ndice2)
|
||||
local len1 = (nsides1 + 1) * ndice1
|
||||
local c1 = table.rep(len1, 0)
|
||||
throw_die(nsides1, ndice1, 0, c1)
|
||||
|
||||
local len2 = (nsides2 + 1) * ndice2
|
||||
local c2 = table.rep(len2, 0)
|
||||
throw_die(nsides2, ndice2, 0, c2)
|
||||
|
||||
local p12 = (nsides1 ^ ndice1) * (nsides2 ^ ndice2)
|
||||
local tot = 0
|
||||
for i = 0, len1 - 1 do
|
||||
for j = 0, math.min(i, len2) - 1 do
|
||||
tot += c1[i + 1] * c2[j + 1] / p12
|
||||
end
|
||||
end
|
||||
return tot
|
||||
end
|
||||
|
||||
print(beating_probability(4, 9, 6, 6))
|
||||
print(beating_probability(10, 5, 7, 6))
|
||||
Loading…
Add table
Add a link
Reference in a new issue