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, 4 and the other with the sides 1, 3, 4, 5, 6, 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)