I am working with the R programming language.
I have the following problem:
- There are 100 coins: the coins are randomly initialized at turn=0 (i.e. 0.5 probability of heads and 0.5 probability of tails)
- At each turn, any given coin has a 0.5 probability of being selected and flipped
- When a coin is flipped, there is a 0.6 probability it will land on the same side that was facing upwards when flipped and a 0.4 probability of landing on the other side
- At the end of each turn, we check each coin (flipped or not flipped, does not matter). If a coin is heads up then +1 else -1
- We do this for 100 turns
My Question: For each of these 100 turns, for each of these 100 coins - I want to track the cumulative number of heads and the cumulative number of tails.
As an example, suppose coin43 was flipped 7 times:
- heads, tails, not selected, not selected, heads, not selected, tails
Then, the scores would be:
- +1 , -1, -1, -1, +1, +1, -1
And at the most recent turn, the cumulative numbers would be:
- 3 heads and 4 tails
First, I initialized the coins:
num_coins <- 100
num_turns <- 100
coins <- sample(c(-1, 1), num_coins, replace = TRUE)
cumulative_heads <- matrix(0, nrow = num_turns, ncol = num_coins)
cumulative_tails <- matrix(0, nrow = num_turns, ncol = num_coins)
Next, I tried to write the bulk of the simulation code:
# Simulation
for (turn in 1:num_turns) {
if(turn > 1){
cumulative_heads[turn,] <- cumulative_heads[turn-1,]
cumulative_tails[turn,] <- cumulative_tails[turn-1,]
}
for (coin in 1:num_coins) {
# Check if coin is selected
if (runif(1) < 0.5) {
# Flip the coin
if (runif(1) < 0.6) {
# Coin lands on the same side
coins[coin] <- coins[coin]
} else {
# Coin lands on the other side
coins[coin] <- -coins[coin]
}
}
# Update cumulative counts
if (coins[coin] == 1) {
cumulative_heads[turn, coin] <- cumulative_heads[turn, coin] + 1
} else {
cumulative_tails[turn, coin] <- cumulative_tails[turn, coin] + 1
}
}
}
Then, I created a data frame to store the results:
results <- data.frame(matrix(ncol = num_coins, nrow = num_turns))
names(results) <- paste0("coin", 1:num_coins)
for (turn in 1:num_turns) {
for (coin in 1:num_coins) {
results[turn, coin] <- paste("Heads: ", cumulative_heads[turn, coin], ", Tails: ", cumulative_tails[turn, coin])
}
}
The final results look something like this (a sample):
> results[1:5, 1:5]
coin1 coin2 coin3 coin4 coin5
1 Heads: 1 , Tails: 0 Heads: 0 , Tails: 1 Heads: 1 , Tails: 0 Heads: 1 , Tails: 0 Heads: 1 , Tails: 0
2 Heads: 1 , Tails: 1 Heads: 0 , Tails: 2 Heads: 2 , Tails: 0 Heads: 2 , Tails: 0 Heads: 2 , Tails: 0
3 Heads: 1 , Tails: 2 Heads: 0 , Tails: 3 Heads: 3 , Tails: 0 Heads: 3 , Tails: 0 Heads: 2 , Tails: 1
4 Heads: 2 , Tails: 2 Heads: 0 , Tails: 4 Heads: 4 , Tails: 0 Heads: 4 , Tails: 0 Heads: 2 , Tails: 2
5 Heads: 3 , Tails: 2 Heads: 0 , Tails: 5 Heads: 5 , Tails: 0 Heads: 5 , Tails: 0 Heads: 2 , Tails: 3
I think I have overcomplicated this - can someone please show me what I can do to simplify this?
Thanks!
Idea and Code
You can define a function that updates the selected coins for flips, e.g.,
then we use
Reducefunction (but enable theaccumulateargument) to keep track of the progress of changes, where the updated coin status from the previous iteration will be the taken as the input for the upcoming iterationFinally, if you would like to obtain the cumulative statistics of the heads and tails of each coin, you can first
rbindthe outcomes ofp, and then analyze the distribution of heads and tails by column, e.g.,Output
The outcome of the first
6turns (incl.turn=0) is shown as belowand the updating progress of the first
6coins