Data update

This commit is contained in:
Ingy döt Net 2026-04-30 12:34:36 -04:00
parent 4bb20c9b71
commit cbaf4c4b64
12390 changed files with 318560 additions and 27248 deletions

View file

@ -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

View 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;

View file

@ -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)

View file

@ -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

View file

@ -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)
}
}

View file

@ -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.

View file

@ -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))