Sicherman Dice

Python Puzzles

Back to the Python! homepage


Sicherman dice are a pair of 6-sided dice with non-standard numbers–one with the sides 1, 2, 2, 3, 3, and 4, and the other with the sides 1, 3, 4, 5, 6, and 8. They are notable as the only pair of 6-sided dice that are not normal dice, bear only positive integers, and have the same probability distribution for the sum as normal dice.

Run a simulation to prove Sicherman dice have the same probability as a normal pair of dice.


Observing the results, it is evident that the counts are remarkably similar.

ID     Dice Sum   Normal        Sicherman     Difference
-----------------------------------------------------------------
0         2       28,159          27,650        509
1         3       55,499          55,425         74
2         4       83,553          83,034        519
3         5      111,067         111,101        -34
4         6      139,156         139,617       -461
5         7      166,948         166,435        513
6         8      138,000         138,616       -616
7         9      110,680         111,222       -542
8        10       83,369          83,920       -551
9        11       55,872          55,414        458
10       12       27,697          27,566        131
import numpy as np
import pandas as pd

# Define dice
standard_dice = np.array([1, 2, 3, 4, 5, 6])
sicherman_dice_1 = np.array([1, 2, 2, 3, 3, 4])
sicherman_dice_2 = np.array([1, 3, 4, 5, 6, 8])

# Define number of simulations
num_simulations = 1000000

# Simulate dice throws
standard_sums = np.random.choice(standard_dice, num_simulations) + np.random.choice(standard_dice, num_simulations)
sicherman_sums = np.random.choice(sicherman_dice_1, num_simulations) + np.random.choice(sicherman_dice_2, num_simulations)

# Create dataframes
standard_df = pd.DataFrame(standard_sums, columns=['DiceSum'])
standard_df['Type'] = 'Standard'
sicherman_df = pd.DataFrame(sicherman_sums, columns=['DiceSum'])
sicherman_df['Type'] = 'Sicherman'

# Concatenate dataframes
df = pd.concat([standard_df, sicherman_df])

# Get counts
counts_df = df.groupby(['Type', 'DiceSum']).size().reset_index(name='Counts')

# Pivot the dataframe
pivot_df = counts_df.pivot(index='DiceSum', columns='Type', values='Counts').reset_index()

# Compute the difference
pivot_df['Difference'] = pivot_df['Sicherman'] - pivot_df['Standard']

# Rename columns
pivot_df.columns = ['DiceSum', 'Normal Count', 'Sicherman Count', 'Difference']

# Format numbers with commas
pivot_df['Normal Count'] = pivot_df['Normal Count'].apply('{:,}'.format)
pivot_df['Sicherman Count'] = pivot_df['Sicherman Count'].apply('{:,}'.format)
pivot_df['Difference'] = pivot_df['Difference'].apply('{:,}'.format)

print(pivot_df)