Examples:
Takes 1 random sample from the vector (in this case, c(“heads”, “tails”) you supplied in the first argument.
sample(c("heads", "tails"), 1)
[1] "tails"
Takes ten random samples from the vector you supplied. Note that you have to specify replace=TRUE or there wouldn’t be ten outcomes available for sampling in your vector. Here, we’ve saved the outcome as ‘flips’. You are likely to get a different sample each time you run this code.
flips<-sample(c("heads", "tails"), 10, replace = TRUE)
flips
[1] "heads" "heads" "tails" "heads" "tails" "tails" "heads" "heads" "heads"
[10] "heads"
#flips<-sample(c("heads", "tails"), 10, replace = FALSE)
#flips
Yields a count of the number of heads in ‘flips’. The sum function works because R treats true (heads) as equaling 1 and false (tails) as equaling 0.
sum(flips=="heads")
[1] 5
We are telling R that this function requires one argument, k, which is the number of coin flips. The code within the { brackets } dictates what the function will do. In this case, it will automatically simulate k number of coin flips and calculate the sum the number of heads.
head_count<-function(k){
flips <- sample(c("heads", "tails"), k, replace = TRUE)
sum(flips=="heads")
}
head_count(10)
[1] 5
Using our function ‘head_count’, we can conduct a single experiment with 10 coin flips. We can repeat this experiment 100 times using the replicate function. Note that we are calling this data ‘heads’. *Check: Look at the results of your 100 replicates of the experiment. What does the output mean?
heads <- replicate(100, head_count(10))
Displays a histogram of the frequency of how many heads there were in each of the 100 replicates of the coin-tossing experiment saved as ‘heads’.
hist(heads)

hist(heads, freq=FALSE)

Displays a summary table with the frequencies of how many heads there were across the 100 replicates of the coin-tossing experiment saved as ‘heads’.
table(heads)
heads
0 1 2 3 4 5 6 7 8
1 2 5 15 24 21 15 11 6
- If we flip a coin 20 times, what is the expected probability of getting six heads? Conduct a simulation using 1000 replicates.
head_count <- function(k){
flips <- sample(c("heads", "tails"), k, replace = TRUE)
sum(flips=="heads")
}
table(replicate(1000, head_count(20)))/100
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
0.03 0.04 0.15 0.41 0.80 1.31 1.42 1.76 1.63 1.23 0.69 0.32 0.11 0.07 0.03
- Simulating coin flips: Generate 10 separate random flips with probability 0.7 of producing heads. What kind of values do you see and what do they represent?
rr rbinom(10, 10, 0.7)
[1] 7 8 7 8 7 8 7 8 6 9
Getting to know the binomial distribution functions in R: Simulates a random draw from a binomial distribution. This function has three arguments: the number of random draws, the number of coins being flipped on each draw, and the probability of a heads as the outcome.As before, heads will be assigned a value of 1 and tails a value of 0.
rbinom(1,1,.5)
Simulates 10 flips of a single coin.
rbinom(10,1,.5)
[1] 0 0 0 0 1 0 1 1 0 1
Simulates one draw of ten coins. This counts the number of heads out of 10 flips.
rbinom(1,10,.5)
[1] 4
Simulates 10 draws with each having 10 coins and reports the number of heads from each draw. You can think of the number of draws as the number of replicates and the number of coins as the sample size in each replicate.
rbinom(10,10,.5)
[1] 6 3 7 4 5 4 5 7 4 4
Simulates 10 draws of 10 coins, each with an 80% chance of producing a head instead of a 50% chance. These biased coins are still considered random variables because the outcome is random.
rbinom(10,10,.8)
[1] 9 8 9 9 7 8 10 8 10 6
Simulates 100000 draws, each with 10 fair coins, and saves the outcome as ‘flips’.
flips<-rbinom(100000, 10, .5)
Finds the fraction of draws where 5 heads occurred, which reflects the probability that this outcome will occur.
mean(flips==5)
[1] 0.24626
Finds the cumulative probability that heads will occur 4 or fewer times during each draw. This is referred to as the cumulative density because it sums up the probability that the number of heads is 0, 1, 2, 3, or 4 out of 10 flips.
mean(flips<=4)
[1] 0.37734
Estimates the exact probability density at a given point. The arguments here are the density being estimated (5 heads), the number of coins (10), and the probability of producing a head (0.5).
dbinom(5,10, .5)
[1] 0.2460938
Estimates the exact cumulative probability density for a given range. The arguments here are the density being estimated (4 or fewer heads), the number of coins (10), and the probability of producing a head (0.5).
pbinom(4,10,.5)
[1] 0.3769531
- Simulating coin flips: Generate 10 separate random flips with probability 0.7 of producing heads. What kind of values do you see and what do they represent?
rbinom(10, 1, .7)
[1] 0 1 1 0 0 1 0 1 1 1
- Simulating draws from a binomial distribution: Generate 100 occurrences of flipping 10 coins, each with 70% probability of producing heads. What kind of values do you produce and what do they represent? Produce a plot of the probability distribution that you generate and describe its shape.
flips<-rbinom(100, 10, 0.7)
table(flips)/100
flips
3 4 5 6 7 8 9 10
0.03 0.02 0.14 0.21 0.25 0.15 0.15 0.05
hist(flips, freq = F)

- Calculate the exact probability that 2 heads will arise from 10 coin flips with a 70% probability of coming up tails. Compare your answer with a simulation of 10,000 trials. Do the two approaches yield similar results?
dbinom(2, 10, 0.3) #Note that the word problem lists probability of getting tails
[1] 0.2334744
mean(rbinom(10000, 10, 0.3)==2)
[1] 0.2269
- Calculate the cumulative probability that at least five coins out of 10 are heads with a 30% probability of coming up heads. Compare your answer with a simulation of 10,000 trials. Do the two approaches yield similar results?
1-pbinom(4, 10, .3) #Note that we have to subtract from 1 to get the right range
[1] 0.1502683
pbinom(4, 10, .3, lower.tail = FALSE) #same as the line above
[1] 0.1502683
mean(rbinom(10000, 10, .3)>= 5)
[1] 0.1498
- Repeat the simulation you ran in exercise (4) with 10, 100, 1,000, 10,000, and 100,000 trials. Which simulation yields a result most similar to the exact probability? Produce a plot depicting the number of trails on the x-axis and the associated probabilities you calculated on the y-axis. Make sure to adjust your axis labels appropriately. What pattern do you see? Produce the plot again but this time log-transform the number of trials. What does this graph reveal that your first graph did not?
r10<-mean(rbinom(10, 10, 0.3)==2)
r100<-mean(rbinom(100, 10, 0.3)==2)
r1000<-mean(rbinom(1000, 10, 0.3)==2)
r10000<-mean(rbinom(10000, 10, 0.3)==2)
r100000<-mean(rbinom(100000, 10, 0.3)==2)
r<-c(r10, r100, r1000, r10000, r100000)
n<-c(10, 100, 1000, 10000, 100000)
plot(n, r, xlab="Number of replicates", ylab="Probability of 70% flips coming up tails")

plot(log(n), r, xlab="Log of number of replicates", ylab="Probability of 70% flips coming up tails")

- If events A and B are independent, and A has a 50% chance of happening and B has a 30% chance of happening, what is the probability that they will both happen? Use simulations to answer this question.
A<-rbinom(1000, 1, 0.5)
B<-rbinom(1000, 1, 0.3)
mean(A & B) #Answer is around 15.2%
[1] 0.162
- Expanding on exercise (7), event C has a 70% chance of happening. What is the probability that events A, B, and C all happen?
C<-rbinom(1000, 1, 0.7)
mean(A & B & C) #Answer is around 9.5%
[1] 0.105
- If events A and B are independent, and A has a 40% chance of coming up heads and B has a 75% chance of coming up heads, what is the probability that either A or B will come up heads? Use simulations to answer this question.
A<-rbinom(1000, 1, 0.4)
B<-rbinom(1000, 1, 0.75)
mean(A|B) #Answer is around 86.1%
[1] 0.866
- Suppose X is a random binomially distributed variable (10, 0.3) and Y is another random binomially distributed variable (10, 0.65), and that they are independent. What is the probability that either of these variables is less than or equal to 5? Estimate this probability both using simulations of 10,000 trials and by calculating exact cumulative densities. How do these two approaches compare?
X<-rbinom(100000, 10, 0.3)
Y<-rbinom(100000, 10, 0.65)
mean(X<=5|Y<=5)
[1] 0.96442
prob_X_less<-pbinom(5, 10, 0.3)
prob_Y_less<-pbinom(5, 10, 0.65)
prob_X_less + prob_Y_less - prob_X_less*prob_Y_less
[1] 0.9644174
- Write a function called ‘dice’ containing no arguments that simulates a roll of two, six-sided dice and calculates the sum of the sides of the dice. Use the replicate function to repeat this process 100 times and create a plot of the resulting probability distribution. What is the probability of that your two dice will produce a sum of 2 (i.e. that your dice come up ‘snake eyes’)?
Repeat this process using 1,000 and 10,000 replicates. Does the shape of the probability distribution change as the number of replicates increases? Does the probability of rolling ‘snake eyes’ depend on the number of replicates used to estimate probabilities?
dice <- function() {
tosses <- sample(x=1:6, size=2, replace=T)
sum(tosses)
}
rep_1K<-replicate(1000, dice())
barplot(table(rep_1K)/1000)

table(rep_1K)/1000
rep_1K
2 3 4 5 6 7 8 9 10 11 12
0.027 0.045 0.079 0.114 0.164 0.166 0.115 0.122 0.081 0.066 0.021
rep_1H<-replicate(100, dice())
barplot(table(rep_1H)/100)

table(rep_1H)/100
rep_1H
2 3 4 5 6 7 8 9 10 11 12
0.01 0.07 0.08 0.13 0.12 0.17 0.17 0.15 0.03 0.04 0.03
rep_10K<-replicate(10000, dice())
barplot(table(rep_10K)/10000)

table(rep_10K)/10000
rep_10K
2 3 4 5 6 7 8 9 10 11 12
0.0260 0.0532 0.0867 0.1108 0.1335 0.1705 0.1364 0.1150 0.0820 0.0560 0.0299
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQKLS0tCgpFeGFtcGxlczoKClRha2VzIDEgcmFuZG9tIHNhbXBsZSBmcm9tIHRoZSB2ZWN0b3IgKGluIHRoaXMgY2FzZSwgYyjigJxoZWFkc+KAnSwg4oCcdGFpbHPigJ0pIHlvdSBzdXBwbGllZCBpbiB0aGUgZmlyc3QgYXJndW1lbnQuCgpgYGB7cn0Kc2FtcGxlKGMoImhlYWRzIiwgInRhaWxzIiksIDEpCmBgYAoKVGFrZXMgdGVuIHJhbmRvbSBzYW1wbGVzIGZyb20gdGhlIHZlY3RvciB5b3Ugc3VwcGxpZWQuICBOb3RlIHRoYXQgeW91IGhhdmUgdG8gc3BlY2lmeSByZXBsYWNlPVRSVUUgb3IgdGhlcmUgd291bGRu4oCZdCBiZSB0ZW4gb3V0Y29tZXMgYXZhaWxhYmxlIGZvciBzYW1wbGluZyBpbiB5b3VyIHZlY3Rvci4gIEhlcmUsIHdl4oCZdmUgc2F2ZWQgdGhlIG91dGNvbWUgYXMg4oCYZmxpcHPigJkuICBZb3UgYXJlIGxpa2VseSB0byBnZXQgYSBkaWZmZXJlbnQgc2FtcGxlIGVhY2ggdGltZSB5b3UgcnVuIHRoaXMgY29kZS4gIAoKYGBge3J9CmZsaXBzPC1zYW1wbGUoYygiaGVhZHMiLCAidGFpbHMiKSwgMTAsIHJlcGxhY2UgPSBUUlVFKQpmbGlwcwojZmxpcHM8LXNhbXBsZShjKCJoZWFkcyIsICJ0YWlscyIpLCAxMCwgcmVwbGFjZSA9IEZBTFNFKSAjcHJvZHVjZXMgZXJyb3IgYi9jIHNhbXBsZSBzcGFjZSBub3QgbGFyZ2UgZW5vZ3VoIHdpdGhvdXQgcmVwbGFjZW1lbnQKI2ZsaXBzCmBgYAoKWWllbGRzIGEgY291bnQgb2YgdGhlIG51bWJlciBvZiBoZWFkcyBpbiDigJhmbGlwc+KAmS4gVGhlIHN1bSBmdW5jdGlvbiB3b3JrcyBiZWNhdXNlIFIgdHJlYXRzIHRydWUgKGhlYWRzKSBhcyBlcXVhbGluZyAxIGFuZCBmYWxzZSAodGFpbHMpIGFzIGVxdWFsaW5nIDAuCgpgYGB7cn0Kc3VtKGZsaXBzPT0iaGVhZHMiKQpgYGAKCldlIGFyZSB0ZWxsaW5nIFIgdGhhdCB0aGlzIGZ1bmN0aW9uIHJlcXVpcmVzIG9uZSBhcmd1bWVudCwgaywgd2hpY2ggaXMgdGhlIG51bWJlciBvZiBjb2luIGZsaXBzLiAgVGhlIGNvZGUgd2l0aGluIHRoZSB7IGJyYWNrZXRzIH0gZGljdGF0ZXMgd2hhdCB0aGUgZnVuY3Rpb24gd2lsbCBkby4gIEluIHRoaXMgY2FzZSwgaXQgd2lsbCBhdXRvbWF0aWNhbGx5IHNpbXVsYXRlIGsgbnVtYmVyIG9mIGNvaW4gZmxpcHMgYW5kIGNhbGN1bGF0ZSB0aGUgc3VtIHRoZSBudW1iZXIgb2YgaGVhZHMuCgpgYGB7cn0KaGVhZF9jb3VudDwtZnVuY3Rpb24oayl7CiAgZmxpcHMgPC0gc2FtcGxlKGMoImhlYWRzIiwgInRhaWxzIiksIGssIHJlcGxhY2UgPSBUUlVFKQogIHN1bShmbGlwcz09ImhlYWRzIikKfQpoZWFkX2NvdW50KDEwKQpgYGAKClVzaW5nIG91ciBmdW5jdGlvbiDigJhoZWFkX2NvdW504oCZLCB3ZSBjYW4gY29uZHVjdCBhIHNpbmdsZSBleHBlcmltZW50IHdpdGggMTAgY29pbiBmbGlwcy4gIFdlIGNhbiByZXBlYXQgdGhpcyBleHBlcmltZW50IDEwMCB0aW1lcyB1c2luZyB0aGUgcmVwbGljYXRlIGZ1bmN0aW9uLiBOb3RlIHRoYXQgd2UgYXJlIGNhbGxpbmcgdGhpcyBkYXRhIOKAmGhlYWRz4oCZLgoqQ2hlY2s6IExvb2sgYXQgdGhlIHJlc3VsdHMgb2YgeW91ciAxMDAgcmVwbGljYXRlcyBvZiB0aGUgZXhwZXJpbWVudC4gV2hhdCBkb2VzIHRoZSBvdXRwdXQgbWVhbj8KCmBgYHtyfQpoZWFkcyA8LSByZXBsaWNhdGUoMTAwLCBoZWFkX2NvdW50KDEwKSkKYGBgCgpEaXNwbGF5cyBhIGhpc3RvZ3JhbSBvZiB0aGUgZnJlcXVlbmN5IG9mIGhvdyBtYW55IGhlYWRzIHRoZXJlIHdlcmUgaW4gZWFjaCBvZiB0aGUgMTAwIHJlcGxpY2F0ZXMgb2YgdGhlIGNvaW4tdG9zc2luZyBleHBlcmltZW50IHNhdmVkIGFzIOKAmGhlYWRz4oCZLiAgCgpgYGB7cn0KaGlzdChoZWFkcykKaGlzdChoZWFkcywgZnJlcT1GQUxTRSkKYGBgCgpEaXNwbGF5cyBhIHN1bW1hcnkgdGFibGUgd2l0aCB0aGUgZnJlcXVlbmNpZXMgb2YgaG93IG1hbnkgaGVhZHMgdGhlcmUgd2VyZSBhY3Jvc3MgdGhlIDEwMCByZXBsaWNhdGVzIG9mIHRoZSBjb2luLXRvc3NpbmcgZXhwZXJpbWVudCBzYXZlZCBhcyDigJhoZWFkc+KAmS4KCmBgYHtyfQp0YWJsZShoZWFkcykKYGBgCjEpIElmIHdlIGZsaXAgYSBjb2luIDIwIHRpbWVzLCB3aGF0IGlzIHRoZSBleHBlY3RlZCBwcm9iYWJpbGl0eSBvZiBnZXR0aW5nIHNpeCBoZWFkcz8gIENvbmR1Y3QgYSBzaW11bGF0aW9uIHVzaW5nIDEwMDAgcmVwbGljYXRlcy4KCmBgYHtyfQpoZWFkX2NvdW50IDwtIGZ1bmN0aW9uKGspewogIGZsaXBzIDwtIHNhbXBsZShjKCJoZWFkcyIsICJ0YWlscyIpLCBrLCByZXBsYWNlID0gVFJVRSkKICBzdW0oZmxpcHM9PSJoZWFkcyIpCn0KdGFibGUocmVwbGljYXRlKDEwMDAsIGhlYWRfY291bnQoMjApKSkvMTAwCmBgYAoKMikgU2ltdWxhdGluZyBjb2luIGZsaXBzOiAgR2VuZXJhdGUgMTAgc2VwYXJhdGUgcmFuZG9tIGZsaXBzIHdpdGggcHJvYmFiaWxpdHkgMC43IG9mIHByb2R1Y2luZyBoZWFkcy4gIFdoYXQga2luZCBvZiB2YWx1ZXMgZG8geW91IHNlZSBhbmQgd2hhdCBkbyB0aGV5IHJlcHJlc2VudD8KCmBgYHtyfQpyYmlub20oMTAsIDEwLCAwLjcpCmBgYAoKR2V0dGluZyB0byBrbm93IHRoZSBiaW5vbWlhbCBkaXN0cmlidXRpb24gZnVuY3Rpb25zIGluIFI6ClNpbXVsYXRlcyBhIHJhbmRvbSBkcmF3IGZyb20gYSBiaW5vbWlhbCBkaXN0cmlidXRpb24uICBUaGlzIGZ1bmN0aW9uIGhhcyB0aHJlZSBhcmd1bWVudHM6IHRoZSBudW1iZXIgb2YgcmFuZG9tIGRyYXdzLCB0aGUgbnVtYmVyIG9mIGNvaW5zIGJlaW5nIGZsaXBwZWQgb24gZWFjaCBkcmF3LCBhbmQgdGhlIHByb2JhYmlsaXR5IG9mIGEgaGVhZHMgYXMgdGhlIG91dGNvbWUuQXMgYmVmb3JlLCBoZWFkcyB3aWxsIGJlIGFzc2lnbmVkIGEgdmFsdWUgb2YgMSBhbmQgdGFpbHMgYSB2YWx1ZSBvZiAwLgoKYGBge3J9CnJiaW5vbSgxLDEsLjUpCmBgYAoKU2ltdWxhdGVzIDEwIGZsaXBzIG9mIGEgc2luZ2xlIGNvaW4uCmBgYHtyfQpyYmlub20oMTAsMSwuNSkKYGBgCgpTaW11bGF0ZXMgb25lIGRyYXcgb2YgdGVuIGNvaW5zLiAgVGhpcyBjb3VudHMgdGhlIG51bWJlciBvZiBoZWFkcyBvdXQgb2YgMTAgZmxpcHMuCgpgYGB7cn0KcmJpbm9tKDEsMTAsLjUpCmBgYAoKU2ltdWxhdGVzIDEwIGRyYXdzIHdpdGggZWFjaCBoYXZpbmcgMTAgY29pbnMgYW5kIHJlcG9ydHMgdGhlIG51bWJlciBvZiBoZWFkcyBmcm9tIGVhY2ggZHJhdy4gIFlvdSBjYW4gdGhpbmsgb2YgdGhlIG51bWJlciBvZiBkcmF3cyBhcyB0aGUgbnVtYmVyIG9mIHJlcGxpY2F0ZXMgYW5kIHRoZSBudW1iZXIgb2YgY29pbnMgYXMgdGhlIHNhbXBsZSBzaXplIGluIGVhY2ggcmVwbGljYXRlLgoKYGBge3J9CnJiaW5vbSgxMCwxMCwuNSkKYGBgCgpTaW11bGF0ZXMgMTAgZHJhd3Mgb2YgMTAgY29pbnMsIGVhY2ggd2l0aCBhbiA4MCUgY2hhbmNlIG9mIHByb2R1Y2luZyBhIGhlYWQgaW5zdGVhZCBvZiBhIDUwJSBjaGFuY2UuICBUaGVzZSBiaWFzZWQgY29pbnMgYXJlIHN0aWxsIGNvbnNpZGVyZWQgcmFuZG9tIHZhcmlhYmxlcyBiZWNhdXNlIHRoZSBvdXRjb21lIGlzIHJhbmRvbS4KCmBgYHtyfQpyYmlub20oMTAsMTAsLjgpCmBgYAoKU2ltdWxhdGVzIDEwMDAwMCBkcmF3cywgZWFjaCB3aXRoIDEwIGZhaXIgY29pbnMsIGFuZCBzYXZlcyB0aGUgb3V0Y29tZSBhcyDigJhmbGlwc+KAmS4gCgpgYGB7cn0KZmxpcHM8LXJiaW5vbSgxMDAwMDAsIDEwLCAuNSkKYGBgCgpGaW5kcyB0aGUgZnJhY3Rpb24gb2YgZHJhd3Mgd2hlcmUgNSBoZWFkcyBvY2N1cnJlZCwgd2hpY2ggcmVmbGVjdHMgdGhlIHByb2JhYmlsaXR5IHRoYXQgdGhpcyBvdXRjb21lIHdpbGwgb2NjdXIuCgpgYGB7cn0KbWVhbihmbGlwcz09NSkKYGBgCgpGaW5kcyB0aGUgY3VtdWxhdGl2ZSBwcm9iYWJpbGl0eSB0aGF0IGhlYWRzIHdpbGwgb2NjdXIgNCBvciBmZXdlciB0aW1lcyBkdXJpbmcgZWFjaCBkcmF3LiAgVGhpcyBpcyByZWZlcnJlZCB0byBhcyB0aGUgY3VtdWxhdGl2ZSBkZW5zaXR5IGJlY2F1c2UgaXQgc3VtcyB1cCB0aGUgcHJvYmFiaWxpdHkgdGhhdCB0aGUgbnVtYmVyIG9mIGhlYWRzIGlzIDAsIDEsIDIsIDMsIG9yIDQgb3V0IG9mIDEwIGZsaXBzLgoKYGBge3J9Cm1lYW4oZmxpcHM8PTQpCmBgYAoKRXN0aW1hdGVzIHRoZSBleGFjdCBwcm9iYWJpbGl0eSBkZW5zaXR5IGF0IGEgZ2l2ZW4gcG9pbnQuICBUaGUgYXJndW1lbnRzIGhlcmUgYXJlIHRoZSBkZW5zaXR5IGJlaW5nIGVzdGltYXRlZCAoNSBoZWFkcyksIHRoZSBudW1iZXIgb2YgY29pbnMgKDEwKSwgYW5kIHRoZSBwcm9iYWJpbGl0eSBvZiBwcm9kdWNpbmcgYSBoZWFkICgwLjUpLgoKYGBge3J9CmRiaW5vbSg1LDEwLCAuNSkKYGBgCgpFc3RpbWF0ZXMgdGhlIGV4YWN0IGN1bXVsYXRpdmUgcHJvYmFiaWxpdHkgZGVuc2l0eSBmb3IgYSBnaXZlbiByYW5nZS4gIFRoZSBhcmd1bWVudHMgaGVyZSBhcmUgdGhlIGRlbnNpdHkgYmVpbmcgZXN0aW1hdGVkICg0IG9yIGZld2VyIGhlYWRzKSwgdGhlIG51bWJlciBvZiBjb2lucyAoMTApLCBhbmQgdGhlIHByb2JhYmlsaXR5IG9mIHByb2R1Y2luZyBhIGhlYWQgKDAuNSkuCgpgYGB7cn0KcGJpbm9tKDQsMTAsLjUpCmBgYAoKMikgU2ltdWxhdGluZyBjb2luIGZsaXBzOiAgR2VuZXJhdGUgMTAgc2VwYXJhdGUgcmFuZG9tIGZsaXBzIHdpdGggcHJvYmFiaWxpdHkgMC43IG9mIHByb2R1Y2luZyBoZWFkcy4gIFdoYXQga2luZCBvZiB2YWx1ZXMgZG8geW91IHNlZSBhbmQgd2hhdCBkbyB0aGV5IHJlcHJlc2VudD8KCmBgYHtyfQpyYmlub20oMTAsIDEsIC43KQpgYGAKCjMpIFNpbXVsYXRpbmcgZHJhd3MgZnJvbSBhIGJpbm9taWFsIGRpc3RyaWJ1dGlvbjogIEdlbmVyYXRlIDEwMCBvY2N1cnJlbmNlcyBvZiBmbGlwcGluZyAxMCBjb2lucywgZWFjaCB3aXRoIDcwJSBwcm9iYWJpbGl0eSBvZiBwcm9kdWNpbmcgaGVhZHMuICBXaGF0IGtpbmQgb2YgdmFsdWVzIGRvIHlvdSBwcm9kdWNlIGFuZCB3aGF0IGRvIHRoZXkgcmVwcmVzZW50PyAgUHJvZHVjZSBhIHBsb3Qgb2YgdGhlIHByb2JhYmlsaXR5IGRpc3RyaWJ1dGlvbiB0aGF0IHlvdSBnZW5lcmF0ZSBhbmQgZGVzY3JpYmUgaXRzIHNoYXBlLgoKYGBge3J9CmZsaXBzPC1yYmlub20oMTAwLCAxMCwgMC43KQp0YWJsZShmbGlwcykvMTAwCmhpc3QoZmxpcHMsIGZyZXEgPSBGKQpgYGAKCjQpIENhbGN1bGF0ZSB0aGUgZXhhY3QgcHJvYmFiaWxpdHkgdGhhdCAyIGhlYWRzIHdpbGwgYXJpc2UgZnJvbSAxMCBjb2luIGZsaXBzIHdpdGggYSA3MCUgcHJvYmFiaWxpdHkgb2YgY29taW5nIHVwIHRhaWxzLiAgQ29tcGFyZSB5b3VyIGFuc3dlciB3aXRoIGEgc2ltdWxhdGlvbiBvZiAxMCwwMDAgdHJpYWxzLiAgRG8gdGhlIHR3byBhcHByb2FjaGVzIHlpZWxkIHNpbWlsYXIgcmVzdWx0cz8KCgpgYGB7cn0KZGJpbm9tKDIsIDEwLCAwLjMpICAjTm90ZSB0aGF0IHRoZSB3b3JkIHByb2JsZW0gbGlzdHMgcHJvYmFiaWxpdHkgb2YgZ2V0dGluZyB0YWlscwptZWFuKHJiaW5vbSgxMDAwMCwgMTAsIDAuMyk9PTIpCmBgYAoKNSkgQ2FsY3VsYXRlIHRoZSBjdW11bGF0aXZlIHByb2JhYmlsaXR5IHRoYXQgYXQgbGVhc3QgZml2ZSBjb2lucyBvdXQgb2YgMTAgYXJlIGhlYWRzIHdpdGggYSAzMCUgcHJvYmFiaWxpdHkgb2YgY29taW5nIHVwIGhlYWRzLiAgQ29tcGFyZSB5b3VyIGFuc3dlciB3aXRoIGEgc2ltdWxhdGlvbiBvZiAxMCwwMDAgdHJpYWxzLiAgRG8gdGhlIHR3byBhcHByb2FjaGVzIHlpZWxkIHNpbWlsYXIgcmVzdWx0cz8KCmBgYHtyfQoxLXBiaW5vbSg0LCAxMCwgLjMpICNOb3RlIHRoYXQgd2UgaGF2ZSB0byBzdWJ0cmFjdCBmcm9tIDEgdG8gZ2V0IHRoZSByaWdodCByYW5nZQpwYmlub20oNCwgMTAsIC4zLCBsb3dlci50YWlsID0gRkFMU0UpICNzYW1lIGFzIHRoZSBsaW5lIGFib3ZlCm1lYW4ocmJpbm9tKDEwMDAwLCAxMCwgLjMpPj0gNSkKYGBgCgo2KSBSZXBlYXQgdGhlIHNpbXVsYXRpb24geW91IHJhbiBpbiBleGVyY2lzZSAoNCkgd2l0aCAxMCwgMTAwLCAxLDAwMCwgMTAsMDAwLCBhbmQgMTAwLDAwMCB0cmlhbHMuICBXaGljaCBzaW11bGF0aW9uIHlpZWxkcyBhIHJlc3VsdCBtb3N0IHNpbWlsYXIgdG8gdGhlIGV4YWN0IHByb2JhYmlsaXR5PyAgUHJvZHVjZSBhIHBsb3QgZGVwaWN0aW5nIHRoZSBudW1iZXIgb2YgdHJhaWxzIG9uIHRoZSB4LWF4aXMgYW5kIHRoZSBhc3NvY2lhdGVkIHByb2JhYmlsaXRpZXMgeW91IGNhbGN1bGF0ZWQgb24gdGhlIHktYXhpcy4gIE1ha2Ugc3VyZSB0byBhZGp1c3QgeW91ciBheGlzIGxhYmVscyBhcHByb3ByaWF0ZWx5LiAgV2hhdCBwYXR0ZXJuIGRvIHlvdSBzZWU/ICBQcm9kdWNlIHRoZSBwbG90IGFnYWluIGJ1dCB0aGlzIHRpbWUgbG9nLXRyYW5zZm9ybSB0aGUgbnVtYmVyIG9mIHRyaWFscy4gIFdoYXQgZG9lcyB0aGlzIGdyYXBoIHJldmVhbCB0aGF0IHlvdXIgZmlyc3QgZ3JhcGggZGlkIG5vdD8KCmBgYHtyfQpyMTA8LW1lYW4ocmJpbm9tKDEwLCAxMCwgMC4zKT09MikKcjEwMDwtbWVhbihyYmlub20oMTAwLCAxMCwgMC4zKT09MikKcjEwMDA8LW1lYW4ocmJpbm9tKDEwMDAsIDEwLCAwLjMpPT0yKQpyMTAwMDA8LW1lYW4ocmJpbm9tKDEwMDAwLCAxMCwgMC4zKT09MikKcjEwMDAwMDwtbWVhbihyYmlub20oMTAwMDAwLCAxMCwgMC4zKT09MikKCnI8LWMocjEwLCByMTAwLCByMTAwMCwgcjEwMDAwLCByMTAwMDAwKQpuPC1jKDEwLCAxMDAsIDEwMDAsIDEwMDAwLCAxMDAwMDApCgpwbG90KG4sIHIsIHhsYWI9Ik51bWJlciBvZiByZXBsaWNhdGVzIiwgeWxhYj0iUHJvYmFiaWxpdHkgb2YgNzAlIGZsaXBzIGNvbWluZyB1cCB0YWlscyIpCnBsb3QobG9nKG4pLCByLCB4bGFiPSJMb2cgb2YgbnVtYmVyIG9mIHJlcGxpY2F0ZXMiLCB5bGFiPSJQcm9iYWJpbGl0eSBvZiA3MCUgZmxpcHMgY29taW5nIHVwIHRhaWxzIikKCmBgYAoKNykgSWYgZXZlbnRzIEEgYW5kIEIgYXJlIGluZGVwZW5kZW50LCBhbmQgQSBoYXMgYSA1MCUgY2hhbmNlIG9mIGhhcHBlbmluZyBhbmQgQiBoYXMgYSAzMCUgY2hhbmNlIG9mIGhhcHBlbmluZywgd2hhdCBpcyB0aGUgcHJvYmFiaWxpdHkgdGhhdCB0aGV5IHdpbGwgYm90aCBoYXBwZW4/ICBVc2Ugc2ltdWxhdGlvbnMgdG8gYW5zd2VyIHRoaXMgcXVlc3Rpb24uCgpgYGB7cn0KQTwtcmJpbm9tKDEwMDAsIDEsIDAuNSkKQjwtcmJpbm9tKDEwMDAsIDEsIDAuMykKbWVhbihBICYgQikgICNBbnN3ZXIgaXMgYXJvdW5kIDE1LjIlCgpgYGAKCjgpIEV4cGFuZGluZyBvbiBleGVyY2lzZSAoNyksIGV2ZW50IEMgaGFzIGEgNzAlIGNoYW5jZSBvZiBoYXBwZW5pbmcuICBXaGF0IGlzIHRoZSBwcm9iYWJpbGl0eSB0aGF0IGV2ZW50cyBBLCBCLCBhbmQgQyBhbGwgaGFwcGVuPwoKYGBge3J9CkM8LXJiaW5vbSgxMDAwLCAxLCAwLjcpCm1lYW4oQSAmIEIgJiBDKSAgI0Fuc3dlciBpcyBhcm91bmQgMTAuNSUKCmBgYAoKOSkgSWYgZXZlbnRzIEEgYW5kIEIgYXJlIGluZGVwZW5kZW50LCBhbmQgQSBoYXMgYSA0MCUgY2hhbmNlIG9mIGNvbWluZyB1cCBoZWFkcyBhbmQgQiBoYXMgYSA3NSUgY2hhbmNlIG9mIGNvbWluZyB1cCBoZWFkcywgd2hhdCBpcyB0aGUgcHJvYmFiaWxpdHkgdGhhdCBlaXRoZXIgQSBvciBCIHdpbGwgY29tZSB1cCBoZWFkcz8gIFVzZSBzaW11bGF0aW9ucyB0byBhbnN3ZXIgdGhpcyBxdWVzdGlvbi4KCmBgYHtyfQpBPC1yYmlub20oMTAwMCwgMSwgMC40KQpCPC1yYmlub20oMTAwMCwgMSwgMC43NSkKbWVhbihBfEIpICAjQW5zd2VyIGlzIGFyb3VuZCA4Ni4xJQpgYGAKCjEwKSBTdXBwb3NlIFggaXMgYSByYW5kb20gYmlub21pYWxseSBkaXN0cmlidXRlZCB2YXJpYWJsZSAoMTAsIDAuMykgYW5kIFkgaXMgYW5vdGhlciByYW5kb20gYmlub21pYWxseSBkaXN0cmlidXRlZCB2YXJpYWJsZSAoMTAsIDAuNjUpLCBhbmQgdGhhdCB0aGV5IGFyZSBpbmRlcGVuZGVudC4gIFdoYXQgaXMgdGhlIHByb2JhYmlsaXR5IHRoYXQgZWl0aGVyIG9mIHRoZXNlIHZhcmlhYmxlcyBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gNT8gIEVzdGltYXRlIHRoaXMgcHJvYmFiaWxpdHkgYm90aCB1c2luZyBzaW11bGF0aW9ucyBvZiAxMCwwMDAgdHJpYWxzIGFuZCBieSBjYWxjdWxhdGluZyBleGFjdCBjdW11bGF0aXZlIGRlbnNpdGllcy4gIEhvdyBkbyB0aGVzZSB0d28gYXBwcm9hY2hlcyBjb21wYXJlPwoKYGBge3J9Clg8LXJiaW5vbSgxMDAwMDAsIDEwLCAwLjMpClk8LXJiaW5vbSgxMDAwMDAsIDEwLCAwLjY1KQptZWFuKFg8PTV8WTw9NSkKCnByb2JfWF9sZXNzPC1wYmlub20oNSwgMTAsIDAuMykKcHJvYl9ZX2xlc3M8LXBiaW5vbSg1LCAxMCwgMC42NSkKcHJvYl9YX2xlc3MgKyBwcm9iX1lfbGVzcyAtIHByb2JfWF9sZXNzKnByb2JfWV9sZXNzCgpgYGAKCjExKSBXcml0ZSBhIGZ1bmN0aW9uIGNhbGxlZCDigJhkaWNl4oCZIGNvbnRhaW5pbmcgbm8gYXJndW1lbnRzIHRoYXQgc2ltdWxhdGVzIGEgcm9sbCBvZiB0d28sIHNpeC1zaWRlZCBkaWNlIGFuZCBjYWxjdWxhdGVzIHRoZSBzdW0gb2YgdGhlIHNpZGVzIG9mIHRoZSBkaWNlLiBVc2UgdGhlIHJlcGxpY2F0ZSBmdW5jdGlvbiB0byByZXBlYXQgdGhpcyBwcm9jZXNzIDEwMCB0aW1lcyBhbmQgY3JlYXRlIGEgcGxvdCBvZiB0aGUgcmVzdWx0aW5nIHByb2JhYmlsaXR5IGRpc3RyaWJ1dGlvbi4gIFdoYXQgaXMgdGhlIHByb2JhYmlsaXR5IG9mIHRoYXQgeW91ciB0d28gZGljZSB3aWxsIHByb2R1Y2UgYSBzdW0gb2YgMiAoaS5lLiB0aGF0IHlvdXIgZGljZSBjb21lIHVwIOKAmHNuYWtlIGV5ZXPigJkpPwoKUmVwZWF0IHRoaXMgcHJvY2VzcyB1c2luZyAxLDAwMCBhbmQgMTAsMDAwIHJlcGxpY2F0ZXMuICBEb2VzIHRoZSBzaGFwZSBvZiB0aGUgcHJvYmFiaWxpdHkgZGlzdHJpYnV0aW9uIGNoYW5nZSBhcyB0aGUgbnVtYmVyIG9mIHJlcGxpY2F0ZXMgaW5jcmVhc2VzPyAgRG9lcyB0aGUgcHJvYmFiaWxpdHkgb2Ygcm9sbGluZyDigJhzbmFrZSBleWVz4oCZIGRlcGVuZCBvbiB0aGUgbnVtYmVyIG9mIHJlcGxpY2F0ZXMgdXNlZCB0byBlc3RpbWF0ZSBwcm9iYWJpbGl0aWVzPwoKYGBge3J9CmRpY2UgPC0gZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRvc3NlcyA8LSBzYW1wbGUoeD0xOjYsIHNpemU9MiwgcmVwbGFjZT1UKQogICAgICAgICAgICAgICAgICAgICAgICBzdW0odG9zc2VzKQp9CiAKIApyZXBfMUs8LXJlcGxpY2F0ZSgxMDAwLCBkaWNlKCkpCmJhcnBsb3QodGFibGUocmVwXzFLKS8xMDAwKQp0YWJsZShyZXBfMUspLzEwMDAKIApyZXBfMUg8LXJlcGxpY2F0ZSgxMDAsIGRpY2UoKSkKYmFycGxvdCh0YWJsZShyZXBfMUgpLzEwMCkKdGFibGUocmVwXzFIKS8xMDAKIApyZXBfMTBLPC1yZXBsaWNhdGUoMTAwMDAsIGRpY2UoKSkKYmFycGxvdCh0YWJsZShyZXBfMTBLKS8xMDAwMCkKdGFibGUocmVwXzEwSykvMTAwMDAKYGBgCgoK