Goal: Practice R basics through a simulation experiment.

Certain (dubious) websites advertise various roulette strategies. One example is the martingale strategy, whereby:

You start placing a small bet, say $1, on low/high (i.e. 1:18/19:36) If you lose, you double-down (i.e. you bet double the previous amount) If you win, you stop

If you are allowed to raise your bets indefinitely, you can show that you will eventually win. Casinos know that, so they have limits on the amounts you can bet. We will use simulation to estimate the expected gain/loss of such a strategy, assuming a European-style roulette (i.e. single-zero) and a $1,000 bet limit. Without loss of generality, assume we play low/high (equivalently, red/black, odd/even) and always bet on high (19:36). We will first simulate a single sequence of bets (roulette tosses), and then try to scale up to multiple sequences without using loops.

  1. Use the sample() function to generate a vector of 10 random roulette spins, i.e. a sequence of 10 numbers randomly selected from 0 to 36. Use spins = sample( ..., replace = TRUE ).
spins = sample( x = 0:5, size = 3 )

Note: We used a sequence of 10 spins since that is the maximum number of possible bets in one iteration of the strategy: an initial bet of $1, and a maximum of 9 double-downs before hitting the $1,000 limit (\(2^9=512\) but \(2^{10}=1024\)).

  1. Tranform the spins vector into a logical vector of wins: use a comparison operator to check if the spin was from 19 to 36.

  2. Check whether there was any win in the 10 bets: use function any().

If you win any of the 10 bets your net gain is always $1. E.g if you win the 1st bet it is obvious, if you lose the first bet ($1) and win the 2nd bet ($2) you have 2-1=$1, if you lose the first two bets ($1 & $2) and win the 3rd bet ($4) you have 4-2-1=$1, etc. But if you lose all 10 bets your net loss is very big, at -$1023!

  1. Verify that the net loss is -1023, by summing up all the bet amounts: create a vector of 2 raised to the powers of 0 to 9, and then sum it up.

By now, you have simulated the gain/loss of a single iteration of the strategy. We need to simulate many iterations in parallel, and calculate the average gain/loss.

  1. Let \(N\) denote the number of iterations and set it to 100,000. Simulate \(N \times 10\) spins and arrange them into a \(N\)-by-\(10\) matrix: use matrix(..., nrow = ...). Then transform the spins matrix into a logical wins matrix.

  2. For each iteration (row) of the strategy, you want to check if there was any win or not: use the apply() function, to apply any() over the rows of the wins matrix (the result should be a logical vector of length \(N\)).

  3. Create a vector GL with the gain/loss of each iteration: use ifelse() together with the logical vector from the previous part, to get +1 when there is any win, -1023 when there is a loss.

  4. Calculate the average gain/loss over all iterations: use mean().

  5. Run plot( cumsum( GL), type ="l" ) to plot the cumulative gain/loss of the martingale strategy, over the number of times (1 to \(N\)) it is employed.

  6. [Extra] Make your code faster by simulating the logical wins matrix directly, i.e. without simulating any roulette spins first: use sample() with the prob argument.

LS0tDQp0aXRsZTogIlNUQUE1NyAtIFdvcmtTaGVldCAyIg0KZGF0ZTogIiAgIg0KYXV0aG9yOiAiTmFtZTogICAgLCBJRCM6ICAgIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUNCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCmBgYA0KDQoNCipHb2FsKjogUHJhY3RpY2UgUiBiYXNpY3MgdGhyb3VnaCBhIHNpbXVsYXRpb24gZXhwZXJpbWVudC4NCg0KDQpDZXJ0YWluIChkdWJpb3VzKSB3ZWJzaXRlcyBhZHZlcnRpc2UgdmFyaW91cyByb3VsZXR0ZSBzdHJhdGVnaWVzLiBPbmUgZXhhbXBsZSBpcyB0aGUgbWFydGluZ2FsZSBzdHJhdGVneSwgd2hlcmVieToNCg0KWW91IHN0YXJ0IHBsYWNpbmcgYSBzbWFsbCBiZXQsIHNheSAkMSwgb24gbG93L2hpZ2ggKGkuZS4gMToxOC8xOTozNikNCklmIHlvdSBsb3NlLCB5b3UgZG91YmxlLWRvd24gKGkuZS4geW91IGJldCBkb3VibGUgdGhlIHByZXZpb3VzIGFtb3VudCkNCklmIHlvdSB3aW4sIHlvdSBzdG9wDQoNCklmIHlvdSBhcmUgYWxsb3dlZCB0byByYWlzZSB5b3VyIGJldHMgKmluZGVmaW5pdGVseSosIHlvdSBjYW4gc2hvdyB0aGF0IHlvdSB3aWxsICpldmVudHVhbGx5KiB3aW4uIENhc2lub3Mga25vdyB0aGF0LCBzbyB0aGV5IGhhdmUgKmxpbWl0cyogb24gdGhlIGFtb3VudHMgeW91IGNhbiBiZXQuIFdlIHdpbGwgdXNlIHNpbXVsYXRpb24gdG8gZXN0aW1hdGUgdGhlICpleHBlY3RlZCBnYWluL2xvc3MqIG9mIHN1Y2ggYSBzdHJhdGVneSwgYXNzdW1pbmcgYSBbRXVyb3BlYW4tc3R5bGUgcm91bGV0dGVdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1JvdWxldHRlI1JvdWxldHRlX3RhYmxlX2xheW91dCkgKGkuZS4gc2luZ2xlLXplcm8pIGFuZCBhIFwkMSwwMDAgYmV0IGxpbWl0LiAqV2l0aG91dCBsb3NzIG9mIGdlbmVyYWxpdHkqLCBhc3N1bWUgd2UgcGxheSBsb3cvaGlnaCAoZXF1aXZhbGVudGx5LCByZWQvYmxhY2ssIG9kZC9ldmVuKSBhbmQgYWx3YXlzIGJldCBvbiBoaWdoICgxOTozNikuIFdlIHdpbGwgZmlyc3Qgc2ltdWxhdGUgYSBzaW5nbGUgc2VxdWVuY2Ugb2YgYmV0cyAocm91bGV0dGUgdG9zc2VzKSwgYW5kIHRoZW4gdHJ5IHRvIHNjYWxlIHVwIHRvIG11bHRpcGxlIHNlcXVlbmNlcyAqd2l0aG91dCB1c2luZyBsb29wcyouDQoNCjEuIFVzZSB0aGUgYHNhbXBsZSgpYCBmdW5jdGlvbiB0byBnZW5lcmF0ZSBhIHZlY3RvciBvZiAxMCByYW5kb20gcm91bGV0dGUgc3BpbnMsIGkuZS4gYSBzZXF1ZW5jZSBvZiAxMCBudW1iZXJzIHJhbmRvbWx5IHNlbGVjdGVkIGZyb20gMCB0byAzNi4gVXNlIGBzcGlucyA9IHNhbXBsZSggLi4uLCByZXBsYWNlID0gVFJVRSApYC4gIA0KDQpgYGB7cn0NCnNwaW5zID0gc2FtcGxlKCB4ID0gMDo1LCBzaXplID0gMyApDQpgYGANCg0KDQpOb3RlOiBXZSB1c2VkIGEgc2VxdWVuY2Ugb2YgMTAgc3BpbnMgc2luY2UgdGhhdCBpcyB0aGUgbWF4aW11bSBudW1iZXIgb2YgcG9zc2libGUgYmV0cyBpbiBvbmUgaXRlcmF0aW9uIG9mIHRoZSBzdHJhdGVneTogYW4gaW5pdGlhbCBiZXQgb2YgXCQxLCBhbmQgYSBtYXhpbXVtIG9mIDkgZG91YmxlLWRvd25zIGJlZm9yZSBoaXR0aW5nIHRoZSBcJDEsMDAwIGxpbWl0ICgkMl45PTUxMiQgYnV0ICQyXnsxMH09MTAyNCQpLg0KDQoyLiBUcmFuZm9ybSB0aGUgYHNwaW5zYCB2ZWN0b3IgaW50byBhICpsb2dpY2FsKiB2ZWN0b3Igb2YgYHdpbnNgOiB1c2UgYSBjb21wYXJpc29uIG9wZXJhdG9yIHRvIGNoZWNrIGlmIHRoZSBzcGluIHdhcyBmcm9tIDE5IHRvIDM2Lg0KDQozLiBDaGVjayB3aGV0aGVyIHRoZXJlIHdhcyAqYW55KiB3aW4gaW4gdGhlIDEwIGJldHM6IHVzZSBmdW5jdGlvbiBgYW55KClgLg0KDQpJZiB5b3Ugd2luICphbnkqIG9mIHRoZSAxMCBiZXRzIHlvdXIgbmV0IGdhaW4gaXMgYWx3YXlzIFwkMS4gRS5nIGlmIHlvdSB3aW4gdGhlIDFzdCBiZXQgaXQgaXMgb2J2aW91cywgaWYgeW91IGxvc2UgdGhlIGZpcnN0IGJldCAoXCQxKSBhbmQgd2luIHRoZSAybmQgYmV0IChcJDIpIHlvdSBoYXZlIDItMT1cJDEsIGlmIHlvdSBsb3NlIHRoZSBmaXJzdCB0d28gYmV0cyAoXCQxICYgXCQyKSBhbmQgd2luIHRoZSAzcmQgYmV0IChcJDQpIHlvdSBoYXZlIDQtMi0xPVwkMSwgZXRjLiBCdXQgaWYgeW91IGxvc2UgYWxsIDEwIGJldHMgeW91ciBuZXQgbG9zcyBpcyB2ZXJ5IGJpZywgYXQgLVwkMTAyMyEgIA0KDQo0LiBWZXJpZnkgdGhhdCB0aGUgbmV0IGxvc3MgaXMgLTEwMjMsIGJ5IHN1bW1pbmcgdXAgYWxsIHRoZSBiZXQgYW1vdW50czogY3JlYXRlIGEgdmVjdG9yIG9mIDIgcmFpc2VkIHRvIHRoZSBwb3dlcnMgb2YgMCB0byA5LCBhbmQgdGhlbiBzdW0gaXQgdXAuICANCg0KQnkgbm93LCB5b3UgaGF2ZSBzaW11bGF0ZWQgdGhlIGdhaW4vbG9zcyBvZiBhICpzaW5nbGUgaXRlcmF0aW9uKiBvZiB0aGUgc3RyYXRlZ3kuIFdlIG5lZWQgdG8gc2ltdWxhdGUgbWFueSBpdGVyYXRpb25zIGluIHBhcmFsbGVsLCBhbmQgY2FsY3VsYXRlIHRoZSAqYXZlcmFnZSBnYWluL2xvc3MqLiANCg0KNS4gTGV0ICROJCBkZW5vdGUgdGhlIG51bWJlciBvZiBpdGVyYXRpb25zIGFuZCBzZXQgaXQgdG8gMTAwLDAwMC4gU2ltdWxhdGUgJE4gXHRpbWVzIDEwJCBzcGlucyBhbmQgYXJyYW5nZSB0aGVtIGludG8gYSAkTiQtYnktJDEwJCBtYXRyaXg6IHVzZSBgbWF0cml4KC4uLiwgbnJvdyA9IC4uLilgLiBUaGVuIHRyYW5zZm9ybSB0aGUgYHNwaW5zYCBtYXRyaXggaW50byBhIGxvZ2ljYWwgYHdpbnNgIG1hdHJpeC4gDQoNCjYuIEZvciBlYWNoIGl0ZXJhdGlvbiAocm93KSBvZiB0aGUgc3RyYXRlZ3ksIHlvdSB3YW50IHRvIGNoZWNrIGlmIHRoZXJlIHdhcyBhbnkgd2luIG9yIG5vdDogdXNlIHRoZSBgYXBwbHkoKWAgZnVuY3Rpb24sIHRvIGFwcGx5IGBhbnkoKWAgb3ZlciB0aGUgcm93cyBvZiB0aGUgYHdpbnNgIG1hdHJpeCAodGhlIHJlc3VsdCBzaG91bGQgYmUgYSBsb2dpY2FsIHZlY3RvciBvZiBsZW5ndGggJE4kKS4NCg0KNy4gQ3JlYXRlIGEgdmVjdG9yIGBHTGAgd2l0aCB0aGUgZ2Fpbi9sb3NzIG9mIGVhY2ggaXRlcmF0aW9uOiB1c2UgYGlmZWxzZSgpYCB0b2dldGhlciB3aXRoIHRoZSBsb2dpY2FsIHZlY3RvciBmcm9tIHRoZSBwcmV2aW91cyBwYXJ0LCB0byBnZXQgKzEgd2hlbiB0aGVyZSBpcyBhbnkgd2luLCAtMTAyMyB3aGVuIHRoZXJlIGlzIGEgbG9zcy4gDQoNCjguIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBnYWluL2xvc3Mgb3ZlciBhbGwgaXRlcmF0aW9uczogdXNlIGBtZWFuKClgLiANCg0KOS4gUnVuIGBwbG90KCBjdW1zdW0oIEdMKSwgdHlwZSA9ImwiIClgIHRvIHBsb3QgdGhlICpjdW11bGF0aXZlKiBnYWluL2xvc3Mgb2YgdGhlIG1hcnRpbmdhbGUgc3RyYXRlZ3ksIG92ZXIgdGhlIG51bWJlciBvZiB0aW1lcyAoMSB0byAkTiQpIGl0IGlzIGVtcGxveWVkLg0KDQoxMC4gW0V4dHJhXSBNYWtlIHlvdXIgY29kZSBmYXN0ZXIgYnkgc2ltdWxhdGluZyB0aGUgbG9naWNhbCBgd2luc2AgbWF0cml4ICpkaXJlY3RseSosIGkuZS4gd2l0aG91dCBzaW11bGF0aW5nIGFueSByb3VsZXR0ZSBzcGlucyBmaXJzdDogdXNlIGBzYW1wbGUoKWAgd2l0aCB0aGUgYHByb2JgIGFyZ3VtZW50Lg0KDQo=