Speed up code to numerically simulate a game of coin tossing











up vote
8
down vote

favorite
2












Description



I would like to simulate n games in which two players toss one coin each at the same time: If you toss a tail you will receive two tokens, if you toss a head you will only get one token.



The player who first accumulates at least m tokens wins; if this happens at the same time, the game will result in a draw.



Code



I have written the following code:



m = 10; (* threshhold to win the game *)
n = 10^6; (* number of games simulated *)

flag1 = 0; (* # P1 wins *)
flag2 = 0; (* # P2 wins *)
flag3 = 0; (* # draws *)
flag4 = 0; (* # total throws *)

Do[
(
i1 = 0; (* initial score P1 *)
i2 = 0; (* initial score P2 *)
i3 = 0; (* initial # of tosses *)

(* play one game until at least one player has collected m or more tokens *)
While[i1 < m && i2 < m,
i1 = i1 + 1 + RandomInteger;
i2 = i2 + 1 + RandomInteger;
i3 = i3 + 1
];

(* keep score *)
If[i1 >= m && i2 >= m,
flag3 = flag3 + 1, (* game is a draw *)
If[i1 > i2,
flag1 = flag1 + 1, (* P1 wins *)
flag2 = flag2 + 1 (* P2 wins *)
]
];

flag4 = flag4 + i3
),
n
]


Could someone please kindly tell me how to modify this to make it faster?










share|improve this question




















  • 4




    Possible description of the algorithm, in natural language?
    – Αλέξανδρος Ζεγγ
    Nov 27 at 9:43






  • 2




    Preallocate storage and write into it instead of expanding it successively with Join; each Join requires a copy operation. Replace For by Do. Leave away Monitor. And Compile everything in the end.
    – Henrik Schumacher
    Nov 27 at 9:44






  • 6




    I did not downvote, but I would have expected a clear explanation of what you want to do instead of just posting a code block. Code like this does not communicate the intent behind it very well. The explanation must be in the question, not in comments.
    – Szabolcs
    Nov 27 at 10:27








  • 1




    But you are getting +1 for each throw and +1 conditional upon the result in your code above?
    – gwr
    Nov 27 at 11:52






  • 1




    @gwr: thank you very much, very kind, the next time I'll try to set it all up like this! =)
    – TeM
    Nov 27 at 12:14















up vote
8
down vote

favorite
2












Description



I would like to simulate n games in which two players toss one coin each at the same time: If you toss a tail you will receive two tokens, if you toss a head you will only get one token.



The player who first accumulates at least m tokens wins; if this happens at the same time, the game will result in a draw.



Code



I have written the following code:



m = 10; (* threshhold to win the game *)
n = 10^6; (* number of games simulated *)

flag1 = 0; (* # P1 wins *)
flag2 = 0; (* # P2 wins *)
flag3 = 0; (* # draws *)
flag4 = 0; (* # total throws *)

Do[
(
i1 = 0; (* initial score P1 *)
i2 = 0; (* initial score P2 *)
i3 = 0; (* initial # of tosses *)

(* play one game until at least one player has collected m or more tokens *)
While[i1 < m && i2 < m,
i1 = i1 + 1 + RandomInteger;
i2 = i2 + 1 + RandomInteger;
i3 = i3 + 1
];

(* keep score *)
If[i1 >= m && i2 >= m,
flag3 = flag3 + 1, (* game is a draw *)
If[i1 > i2,
flag1 = flag1 + 1, (* P1 wins *)
flag2 = flag2 + 1 (* P2 wins *)
]
];

flag4 = flag4 + i3
),
n
]


Could someone please kindly tell me how to modify this to make it faster?










share|improve this question




















  • 4




    Possible description of the algorithm, in natural language?
    – Αλέξανδρος Ζεγγ
    Nov 27 at 9:43






  • 2




    Preallocate storage and write into it instead of expanding it successively with Join; each Join requires a copy operation. Replace For by Do. Leave away Monitor. And Compile everything in the end.
    – Henrik Schumacher
    Nov 27 at 9:44






  • 6




    I did not downvote, but I would have expected a clear explanation of what you want to do instead of just posting a code block. Code like this does not communicate the intent behind it very well. The explanation must be in the question, not in comments.
    – Szabolcs
    Nov 27 at 10:27








  • 1




    But you are getting +1 for each throw and +1 conditional upon the result in your code above?
    – gwr
    Nov 27 at 11:52






  • 1




    @gwr: thank you very much, very kind, the next time I'll try to set it all up like this! =)
    – TeM
    Nov 27 at 12:14













up vote
8
down vote

favorite
2









up vote
8
down vote

favorite
2






2





Description



I would like to simulate n games in which two players toss one coin each at the same time: If you toss a tail you will receive two tokens, if you toss a head you will only get one token.



The player who first accumulates at least m tokens wins; if this happens at the same time, the game will result in a draw.



Code



I have written the following code:



m = 10; (* threshhold to win the game *)
n = 10^6; (* number of games simulated *)

flag1 = 0; (* # P1 wins *)
flag2 = 0; (* # P2 wins *)
flag3 = 0; (* # draws *)
flag4 = 0; (* # total throws *)

Do[
(
i1 = 0; (* initial score P1 *)
i2 = 0; (* initial score P2 *)
i3 = 0; (* initial # of tosses *)

(* play one game until at least one player has collected m or more tokens *)
While[i1 < m && i2 < m,
i1 = i1 + 1 + RandomInteger;
i2 = i2 + 1 + RandomInteger;
i3 = i3 + 1
];

(* keep score *)
If[i1 >= m && i2 >= m,
flag3 = flag3 + 1, (* game is a draw *)
If[i1 > i2,
flag1 = flag1 + 1, (* P1 wins *)
flag2 = flag2 + 1 (* P2 wins *)
]
];

flag4 = flag4 + i3
),
n
]


Could someone please kindly tell me how to modify this to make it faster?










share|improve this question















Description



I would like to simulate n games in which two players toss one coin each at the same time: If you toss a tail you will receive two tokens, if you toss a head you will only get one token.



The player who first accumulates at least m tokens wins; if this happens at the same time, the game will result in a draw.



Code



I have written the following code:



m = 10; (* threshhold to win the game *)
n = 10^6; (* number of games simulated *)

flag1 = 0; (* # P1 wins *)
flag2 = 0; (* # P2 wins *)
flag3 = 0; (* # draws *)
flag4 = 0; (* # total throws *)

Do[
(
i1 = 0; (* initial score P1 *)
i2 = 0; (* initial score P2 *)
i3 = 0; (* initial # of tosses *)

(* play one game until at least one player has collected m or more tokens *)
While[i1 < m && i2 < m,
i1 = i1 + 1 + RandomInteger;
i2 = i2 + 1 + RandomInteger;
i3 = i3 + 1
];

(* keep score *)
If[i1 >= m && i2 >= m,
flag3 = flag3 + 1, (* game is a draw *)
If[i1 > i2,
flag1 = flag1 + 1, (* P1 wins *)
flag2 = flag2 + 1 (* P2 wins *)
]
];

flag4 = flag4 + i3
),
n
]


Could someone please kindly tell me how to modify this to make it faster?







performance-tuning programming






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 27 at 14:00









gwr

7,20122457




7,20122457










asked Nov 27 at 9:41









TeM

1,775618




1,775618








  • 4




    Possible description of the algorithm, in natural language?
    – Αλέξανδρος Ζεγγ
    Nov 27 at 9:43






  • 2




    Preallocate storage and write into it instead of expanding it successively with Join; each Join requires a copy operation. Replace For by Do. Leave away Monitor. And Compile everything in the end.
    – Henrik Schumacher
    Nov 27 at 9:44






  • 6




    I did not downvote, but I would have expected a clear explanation of what you want to do instead of just posting a code block. Code like this does not communicate the intent behind it very well. The explanation must be in the question, not in comments.
    – Szabolcs
    Nov 27 at 10:27








  • 1




    But you are getting +1 for each throw and +1 conditional upon the result in your code above?
    – gwr
    Nov 27 at 11:52






  • 1




    @gwr: thank you very much, very kind, the next time I'll try to set it all up like this! =)
    – TeM
    Nov 27 at 12:14














  • 4




    Possible description of the algorithm, in natural language?
    – Αλέξανδρος Ζεγγ
    Nov 27 at 9:43






  • 2




    Preallocate storage and write into it instead of expanding it successively with Join; each Join requires a copy operation. Replace For by Do. Leave away Monitor. And Compile everything in the end.
    – Henrik Schumacher
    Nov 27 at 9:44






  • 6




    I did not downvote, but I would have expected a clear explanation of what you want to do instead of just posting a code block. Code like this does not communicate the intent behind it very well. The explanation must be in the question, not in comments.
    – Szabolcs
    Nov 27 at 10:27








  • 1




    But you are getting +1 for each throw and +1 conditional upon the result in your code above?
    – gwr
    Nov 27 at 11:52






  • 1




    @gwr: thank you very much, very kind, the next time I'll try to set it all up like this! =)
    – TeM
    Nov 27 at 12:14








4




4




Possible description of the algorithm, in natural language?
– Αλέξανδρος Ζεγγ
Nov 27 at 9:43




Possible description of the algorithm, in natural language?
– Αλέξανδρος Ζεγγ
Nov 27 at 9:43




2




2




Preallocate storage and write into it instead of expanding it successively with Join; each Join requires a copy operation. Replace For by Do. Leave away Monitor. And Compile everything in the end.
– Henrik Schumacher
Nov 27 at 9:44




Preallocate storage and write into it instead of expanding it successively with Join; each Join requires a copy operation. Replace For by Do. Leave away Monitor. And Compile everything in the end.
– Henrik Schumacher
Nov 27 at 9:44




6




6




I did not downvote, but I would have expected a clear explanation of what you want to do instead of just posting a code block. Code like this does not communicate the intent behind it very well. The explanation must be in the question, not in comments.
– Szabolcs
Nov 27 at 10:27






I did not downvote, but I would have expected a clear explanation of what you want to do instead of just posting a code block. Code like this does not communicate the intent behind it very well. The explanation must be in the question, not in comments.
– Szabolcs
Nov 27 at 10:27






1




1




But you are getting +1 for each throw and +1 conditional upon the result in your code above?
– gwr
Nov 27 at 11:52




But you are getting +1 for each throw and +1 conditional upon the result in your code above?
– gwr
Nov 27 at 11:52




1




1




@gwr: thank you very much, very kind, the next time I'll try to set it all up like this! =)
– TeM
Nov 27 at 12:14




@gwr: thank you very much, very kind, the next time I'll try to set it all up like this! =)
– TeM
Nov 27 at 12:14










3 Answers
3






active

oldest

votes

















up vote
7
down vote













Some improvement with Compile and a slightly different "take" on the problem using NestWhile:



cf = Compile[
{
{ m, _Integer },
{ n, _Integer }
},
Module[
{
game, (* vector to track a single game: { P1 tokens, P2 tokens, tosses } *)
p1wins = {1, 0, 0, 0},
p2wins = {0, 1, 0, 0},
draw = {0, 0, 1, 0},
count = {0, 0, 0, 1}
},
(* function returns vector: { # P1 wins, #P2 wins, # draws, # tosses } *)
Total @ Table[
(
(* play game until at least one player has m or more tokens *)
game = NestWhile[
# + { RandomInteger @ {1,2}, RandomInteger @ {1,2} , 1 } &,
{0, 0, 0},
#[[1]] < m && #[[2]] < m &
];
(* keep score *)
Which[
game[[1]] >= m && game[[2]] >= m, draw,
game[[1]] > game[[2]], p1wins,
True, p2wins
] + game[[3]] * count
),
n
]
],
CompilationTarget -> "C" (* this option requires C compiler installed *)
];

cf[ 10, 10^6]; // AbsoluteTiming

(* {0.922876, Null} *)


Maybe more is possible with parallelization.






share|improve this answer



















  • 2




    @TeM Ok, Compile brings this down to around 1 sec.
    – gwr
    Nov 27 at 13:55








  • 3




    1 + RandomInteger is equivalent to RandomInteger[{1, 2}]
    – Okkes Dulgerci
    Nov 27 at 14:40










  • @Okkes Thanks, indeed that is more concise.
    – gwr
    Nov 27 at 14:54


















up vote
6
down vote













I wrote something similar to @Okkes (+1), but with a general maximum m.



TeMgame = Compile[{{m, _Integer}},
Block[{r = Range[m]},
Sign[
First[ Pick[r, UnitStep[Accumulate[RandomInteger[{1, 2}, m]] - m], 1]] -
First[ Pick[r, UnitStep[Accumulate[RandomInteger[{1, 2}, m]] - m], 1]]
]], CompilationTarget -> "C", Parallelization -> True]


It is faster than cf from @gwr when m is larger. For example,



AbsoluteTiming[Sort@Tally[Table[TeMgame[200], {10^6}]]]



{10.4598, {{-1, 463391}, {0, 72762}, {1, 463847}}}




ParallelTable on 8 kernels takes 2.5 seconds.



Update



Write TeMgame3 to save the numbers of flips.



TeMgame3 = Compile[{{m, _Integer}},
Block[{r},
r = Range[m];
{First[Pick[r, UnitStep[Accumulate[RandomInteger[{1, 2}, m]] - m], 1]],
First[Pick[r, UnitStep[Accumulate[RandomInteger[{1, 2}, m]] - m], 1]]}
], CompilationTarget -> "C", Parallelization -> True]


Now run the following to count the total number of flips, as well as the wins, draws, and losses.



AbsoluteTiming[
With[{t = ParallelTable[TeMgame3[200], {i, 1, 10^6}]},
{Total[Map[Min, t]], Sort[Tally[Sign[Subtract @@@ t]]]}
]]



{2.74122, {131388986, {{-1, 463096}, {0, 73098}, {1, 463806}}}}




Your second question refers to a draw being achieved "only when both players have the same number of coins". I currently do not see how it can be otherwise...






share|improve this answer























  • I'm amazed at the speed !! I have a couple of questions! Is it possible to print the number of tosses made? If the draw is achieved only when both players have the same number of coins, could you adapt your code in some way? Thank you!
    – TeM
    Nov 27 at 16:19










  • Suppose, for simplicity, the case in which the tokens to accumulate are 100. CASE A: the draw is when at the end of the game the two players have the same number of coins (both 100 or both 101). CASE B: the draw occurs when at the end of the game the two players have accumulated at least 100 tokens. The code that I have reported here is CASE B, that produces your own results.
    – TeM
    Nov 27 at 20:39


















up vote
4
down vote













Edit:



m = 10;
n = 100;
Table[Sign@
Differences@
Flatten[FirstPosition[#, 1] & /@
UnitStep[Accumulate /@ RandomInteger[{1, 2}, {2, m}] - m]], n]


Original answer



Here is more compact one but slow, it might be improved. ${+1,0,-1}={text{p1 wins},text{draw},text{p2 wins}}$



   n=100;
Table[Sign@
Differences[
First@Flatten@Position[#, 10 | 11] & /@
Accumulate /@ RandomInteger[{1, 2}, {2, 10}]], n]





share|improve this answer























    Your Answer





    StackExchange.ifUsing("editor", function () {
    return StackExchange.using("mathjaxEditing", function () {
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["$", "$"], ["\\(","\\)"]]);
    });
    });
    }, "mathjax-editing");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "387"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f186766%2fspeed-up-code-to-numerically-simulate-a-game-of-coin-tossing%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    7
    down vote













    Some improvement with Compile and a slightly different "take" on the problem using NestWhile:



    cf = Compile[
    {
    { m, _Integer },
    { n, _Integer }
    },
    Module[
    {
    game, (* vector to track a single game: { P1 tokens, P2 tokens, tosses } *)
    p1wins = {1, 0, 0, 0},
    p2wins = {0, 1, 0, 0},
    draw = {0, 0, 1, 0},
    count = {0, 0, 0, 1}
    },
    (* function returns vector: { # P1 wins, #P2 wins, # draws, # tosses } *)
    Total @ Table[
    (
    (* play game until at least one player has m or more tokens *)
    game = NestWhile[
    # + { RandomInteger @ {1,2}, RandomInteger @ {1,2} , 1 } &,
    {0, 0, 0},
    #[[1]] < m && #[[2]] < m &
    ];
    (* keep score *)
    Which[
    game[[1]] >= m && game[[2]] >= m, draw,
    game[[1]] > game[[2]], p1wins,
    True, p2wins
    ] + game[[3]] * count
    ),
    n
    ]
    ],
    CompilationTarget -> "C" (* this option requires C compiler installed *)
    ];

    cf[ 10, 10^6]; // AbsoluteTiming

    (* {0.922876, Null} *)


    Maybe more is possible with parallelization.






    share|improve this answer



















    • 2




      @TeM Ok, Compile brings this down to around 1 sec.
      – gwr
      Nov 27 at 13:55








    • 3




      1 + RandomInteger is equivalent to RandomInteger[{1, 2}]
      – Okkes Dulgerci
      Nov 27 at 14:40










    • @Okkes Thanks, indeed that is more concise.
      – gwr
      Nov 27 at 14:54















    up vote
    7
    down vote













    Some improvement with Compile and a slightly different "take" on the problem using NestWhile:



    cf = Compile[
    {
    { m, _Integer },
    { n, _Integer }
    },
    Module[
    {
    game, (* vector to track a single game: { P1 tokens, P2 tokens, tosses } *)
    p1wins = {1, 0, 0, 0},
    p2wins = {0, 1, 0, 0},
    draw = {0, 0, 1, 0},
    count = {0, 0, 0, 1}
    },
    (* function returns vector: { # P1 wins, #P2 wins, # draws, # tosses } *)
    Total @ Table[
    (
    (* play game until at least one player has m or more tokens *)
    game = NestWhile[
    # + { RandomInteger @ {1,2}, RandomInteger @ {1,2} , 1 } &,
    {0, 0, 0},
    #[[1]] < m && #[[2]] < m &
    ];
    (* keep score *)
    Which[
    game[[1]] >= m && game[[2]] >= m, draw,
    game[[1]] > game[[2]], p1wins,
    True, p2wins
    ] + game[[3]] * count
    ),
    n
    ]
    ],
    CompilationTarget -> "C" (* this option requires C compiler installed *)
    ];

    cf[ 10, 10^6]; // AbsoluteTiming

    (* {0.922876, Null} *)


    Maybe more is possible with parallelization.






    share|improve this answer



















    • 2




      @TeM Ok, Compile brings this down to around 1 sec.
      – gwr
      Nov 27 at 13:55








    • 3




      1 + RandomInteger is equivalent to RandomInteger[{1, 2}]
      – Okkes Dulgerci
      Nov 27 at 14:40










    • @Okkes Thanks, indeed that is more concise.
      – gwr
      Nov 27 at 14:54













    up vote
    7
    down vote










    up vote
    7
    down vote









    Some improvement with Compile and a slightly different "take" on the problem using NestWhile:



    cf = Compile[
    {
    { m, _Integer },
    { n, _Integer }
    },
    Module[
    {
    game, (* vector to track a single game: { P1 tokens, P2 tokens, tosses } *)
    p1wins = {1, 0, 0, 0},
    p2wins = {0, 1, 0, 0},
    draw = {0, 0, 1, 0},
    count = {0, 0, 0, 1}
    },
    (* function returns vector: { # P1 wins, #P2 wins, # draws, # tosses } *)
    Total @ Table[
    (
    (* play game until at least one player has m or more tokens *)
    game = NestWhile[
    # + { RandomInteger @ {1,2}, RandomInteger @ {1,2} , 1 } &,
    {0, 0, 0},
    #[[1]] < m && #[[2]] < m &
    ];
    (* keep score *)
    Which[
    game[[1]] >= m && game[[2]] >= m, draw,
    game[[1]] > game[[2]], p1wins,
    True, p2wins
    ] + game[[3]] * count
    ),
    n
    ]
    ],
    CompilationTarget -> "C" (* this option requires C compiler installed *)
    ];

    cf[ 10, 10^6]; // AbsoluteTiming

    (* {0.922876, Null} *)


    Maybe more is possible with parallelization.






    share|improve this answer














    Some improvement with Compile and a slightly different "take" on the problem using NestWhile:



    cf = Compile[
    {
    { m, _Integer },
    { n, _Integer }
    },
    Module[
    {
    game, (* vector to track a single game: { P1 tokens, P2 tokens, tosses } *)
    p1wins = {1, 0, 0, 0},
    p2wins = {0, 1, 0, 0},
    draw = {0, 0, 1, 0},
    count = {0, 0, 0, 1}
    },
    (* function returns vector: { # P1 wins, #P2 wins, # draws, # tosses } *)
    Total @ Table[
    (
    (* play game until at least one player has m or more tokens *)
    game = NestWhile[
    # + { RandomInteger @ {1,2}, RandomInteger @ {1,2} , 1 } &,
    {0, 0, 0},
    #[[1]] < m && #[[2]] < m &
    ];
    (* keep score *)
    Which[
    game[[1]] >= m && game[[2]] >= m, draw,
    game[[1]] > game[[2]], p1wins,
    True, p2wins
    ] + game[[3]] * count
    ),
    n
    ]
    ],
    CompilationTarget -> "C" (* this option requires C compiler installed *)
    ];

    cf[ 10, 10^6]; // AbsoluteTiming

    (* {0.922876, Null} *)


    Maybe more is possible with parallelization.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 27 at 15:15

























    answered Nov 27 at 13:23









    gwr

    7,20122457




    7,20122457








    • 2




      @TeM Ok, Compile brings this down to around 1 sec.
      – gwr
      Nov 27 at 13:55








    • 3




      1 + RandomInteger is equivalent to RandomInteger[{1, 2}]
      – Okkes Dulgerci
      Nov 27 at 14:40










    • @Okkes Thanks, indeed that is more concise.
      – gwr
      Nov 27 at 14:54














    • 2




      @TeM Ok, Compile brings this down to around 1 sec.
      – gwr
      Nov 27 at 13:55








    • 3




      1 + RandomInteger is equivalent to RandomInteger[{1, 2}]
      – Okkes Dulgerci
      Nov 27 at 14:40










    • @Okkes Thanks, indeed that is more concise.
      – gwr
      Nov 27 at 14:54








    2




    2




    @TeM Ok, Compile brings this down to around 1 sec.
    – gwr
    Nov 27 at 13:55






    @TeM Ok, Compile brings this down to around 1 sec.
    – gwr
    Nov 27 at 13:55






    3




    3




    1 + RandomInteger is equivalent to RandomInteger[{1, 2}]
    – Okkes Dulgerci
    Nov 27 at 14:40




    1 + RandomInteger is equivalent to RandomInteger[{1, 2}]
    – Okkes Dulgerci
    Nov 27 at 14:40












    @Okkes Thanks, indeed that is more concise.
    – gwr
    Nov 27 at 14:54




    @Okkes Thanks, indeed that is more concise.
    – gwr
    Nov 27 at 14:54










    up vote
    6
    down vote













    I wrote something similar to @Okkes (+1), but with a general maximum m.



    TeMgame = Compile[{{m, _Integer}},
    Block[{r = Range[m]},
    Sign[
    First[ Pick[r, UnitStep[Accumulate[RandomInteger[{1, 2}, m]] - m], 1]] -
    First[ Pick[r, UnitStep[Accumulate[RandomInteger[{1, 2}, m]] - m], 1]]
    ]], CompilationTarget -> "C", Parallelization -> True]


    It is faster than cf from @gwr when m is larger. For example,



    AbsoluteTiming[Sort@Tally[Table[TeMgame[200], {10^6}]]]



    {10.4598, {{-1, 463391}, {0, 72762}, {1, 463847}}}




    ParallelTable on 8 kernels takes 2.5 seconds.



    Update



    Write TeMgame3 to save the numbers of flips.



    TeMgame3 = Compile[{{m, _Integer}},
    Block[{r},
    r = Range[m];
    {First[Pick[r, UnitStep[Accumulate[RandomInteger[{1, 2}, m]] - m], 1]],
    First[Pick[r, UnitStep[Accumulate[RandomInteger[{1, 2}, m]] - m], 1]]}
    ], CompilationTarget -> "C", Parallelization -> True]


    Now run the following to count the total number of flips, as well as the wins, draws, and losses.



    AbsoluteTiming[
    With[{t = ParallelTable[TeMgame3[200], {i, 1, 10^6}]},
    {Total[Map[Min, t]], Sort[Tally[Sign[Subtract @@@ t]]]}
    ]]



    {2.74122, {131388986, {{-1, 463096}, {0, 73098}, {1, 463806}}}}




    Your second question refers to a draw being achieved "only when both players have the same number of coins". I currently do not see how it can be otherwise...






    share|improve this answer























    • I'm amazed at the speed !! I have a couple of questions! Is it possible to print the number of tosses made? If the draw is achieved only when both players have the same number of coins, could you adapt your code in some way? Thank you!
      – TeM
      Nov 27 at 16:19










    • Suppose, for simplicity, the case in which the tokens to accumulate are 100. CASE A: the draw is when at the end of the game the two players have the same number of coins (both 100 or both 101). CASE B: the draw occurs when at the end of the game the two players have accumulated at least 100 tokens. The code that I have reported here is CASE B, that produces your own results.
      – TeM
      Nov 27 at 20:39















    up vote
    6
    down vote













    I wrote something similar to @Okkes (+1), but with a general maximum m.



    TeMgame = Compile[{{m, _Integer}},
    Block[{r = Range[m]},
    Sign[
    First[ Pick[r, UnitStep[Accumulate[RandomInteger[{1, 2}, m]] - m], 1]] -
    First[ Pick[r, UnitStep[Accumulate[RandomInteger[{1, 2}, m]] - m], 1]]
    ]], CompilationTarget -> "C", Parallelization -> True]


    It is faster than cf from @gwr when m is larger. For example,



    AbsoluteTiming[Sort@Tally[Table[TeMgame[200], {10^6}]]]



    {10.4598, {{-1, 463391}, {0, 72762}, {1, 463847}}}




    ParallelTable on 8 kernels takes 2.5 seconds.



    Update



    Write TeMgame3 to save the numbers of flips.



    TeMgame3 = Compile[{{m, _Integer}},
    Block[{r},
    r = Range[m];
    {First[Pick[r, UnitStep[Accumulate[RandomInteger[{1, 2}, m]] - m], 1]],
    First[Pick[r, UnitStep[Accumulate[RandomInteger[{1, 2}, m]] - m], 1]]}
    ], CompilationTarget -> "C", Parallelization -> True]


    Now run the following to count the total number of flips, as well as the wins, draws, and losses.



    AbsoluteTiming[
    With[{t = ParallelTable[TeMgame3[200], {i, 1, 10^6}]},
    {Total[Map[Min, t]], Sort[Tally[Sign[Subtract @@@ t]]]}
    ]]



    {2.74122, {131388986, {{-1, 463096}, {0, 73098}, {1, 463806}}}}




    Your second question refers to a draw being achieved "only when both players have the same number of coins". I currently do not see how it can be otherwise...






    share|improve this answer























    • I'm amazed at the speed !! I have a couple of questions! Is it possible to print the number of tosses made? If the draw is achieved only when both players have the same number of coins, could you adapt your code in some way? Thank you!
      – TeM
      Nov 27 at 16:19










    • Suppose, for simplicity, the case in which the tokens to accumulate are 100. CASE A: the draw is when at the end of the game the two players have the same number of coins (both 100 or both 101). CASE B: the draw occurs when at the end of the game the two players have accumulated at least 100 tokens. The code that I have reported here is CASE B, that produces your own results.
      – TeM
      Nov 27 at 20:39













    up vote
    6
    down vote










    up vote
    6
    down vote









    I wrote something similar to @Okkes (+1), but with a general maximum m.



    TeMgame = Compile[{{m, _Integer}},
    Block[{r = Range[m]},
    Sign[
    First[ Pick[r, UnitStep[Accumulate[RandomInteger[{1, 2}, m]] - m], 1]] -
    First[ Pick[r, UnitStep[Accumulate[RandomInteger[{1, 2}, m]] - m], 1]]
    ]], CompilationTarget -> "C", Parallelization -> True]


    It is faster than cf from @gwr when m is larger. For example,



    AbsoluteTiming[Sort@Tally[Table[TeMgame[200], {10^6}]]]



    {10.4598, {{-1, 463391}, {0, 72762}, {1, 463847}}}




    ParallelTable on 8 kernels takes 2.5 seconds.



    Update



    Write TeMgame3 to save the numbers of flips.



    TeMgame3 = Compile[{{m, _Integer}},
    Block[{r},
    r = Range[m];
    {First[Pick[r, UnitStep[Accumulate[RandomInteger[{1, 2}, m]] - m], 1]],
    First[Pick[r, UnitStep[Accumulate[RandomInteger[{1, 2}, m]] - m], 1]]}
    ], CompilationTarget -> "C", Parallelization -> True]


    Now run the following to count the total number of flips, as well as the wins, draws, and losses.



    AbsoluteTiming[
    With[{t = ParallelTable[TeMgame3[200], {i, 1, 10^6}]},
    {Total[Map[Min, t]], Sort[Tally[Sign[Subtract @@@ t]]]}
    ]]



    {2.74122, {131388986, {{-1, 463096}, {0, 73098}, {1, 463806}}}}




    Your second question refers to a draw being achieved "only when both players have the same number of coins". I currently do not see how it can be otherwise...






    share|improve this answer














    I wrote something similar to @Okkes (+1), but with a general maximum m.



    TeMgame = Compile[{{m, _Integer}},
    Block[{r = Range[m]},
    Sign[
    First[ Pick[r, UnitStep[Accumulate[RandomInteger[{1, 2}, m]] - m], 1]] -
    First[ Pick[r, UnitStep[Accumulate[RandomInteger[{1, 2}, m]] - m], 1]]
    ]], CompilationTarget -> "C", Parallelization -> True]


    It is faster than cf from @gwr when m is larger. For example,



    AbsoluteTiming[Sort@Tally[Table[TeMgame[200], {10^6}]]]



    {10.4598, {{-1, 463391}, {0, 72762}, {1, 463847}}}




    ParallelTable on 8 kernels takes 2.5 seconds.



    Update



    Write TeMgame3 to save the numbers of flips.



    TeMgame3 = Compile[{{m, _Integer}},
    Block[{r},
    r = Range[m];
    {First[Pick[r, UnitStep[Accumulate[RandomInteger[{1, 2}, m]] - m], 1]],
    First[Pick[r, UnitStep[Accumulate[RandomInteger[{1, 2}, m]] - m], 1]]}
    ], CompilationTarget -> "C", Parallelization -> True]


    Now run the following to count the total number of flips, as well as the wins, draws, and losses.



    AbsoluteTiming[
    With[{t = ParallelTable[TeMgame3[200], {i, 1, 10^6}]},
    {Total[Map[Min, t]], Sort[Tally[Sign[Subtract @@@ t]]]}
    ]]



    {2.74122, {131388986, {{-1, 463096}, {0, 73098}, {1, 463806}}}}




    Your second question refers to a draw being achieved "only when both players have the same number of coins". I currently do not see how it can be otherwise...







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 27 at 20:09

























    answered Nov 27 at 15:45









    KennyColnago

    12k1754




    12k1754












    • I'm amazed at the speed !! I have a couple of questions! Is it possible to print the number of tosses made? If the draw is achieved only when both players have the same number of coins, could you adapt your code in some way? Thank you!
      – TeM
      Nov 27 at 16:19










    • Suppose, for simplicity, the case in which the tokens to accumulate are 100. CASE A: the draw is when at the end of the game the two players have the same number of coins (both 100 or both 101). CASE B: the draw occurs when at the end of the game the two players have accumulated at least 100 tokens. The code that I have reported here is CASE B, that produces your own results.
      – TeM
      Nov 27 at 20:39


















    • I'm amazed at the speed !! I have a couple of questions! Is it possible to print the number of tosses made? If the draw is achieved only when both players have the same number of coins, could you adapt your code in some way? Thank you!
      – TeM
      Nov 27 at 16:19










    • Suppose, for simplicity, the case in which the tokens to accumulate are 100. CASE A: the draw is when at the end of the game the two players have the same number of coins (both 100 or both 101). CASE B: the draw occurs when at the end of the game the two players have accumulated at least 100 tokens. The code that I have reported here is CASE B, that produces your own results.
      – TeM
      Nov 27 at 20:39
















    I'm amazed at the speed !! I have a couple of questions! Is it possible to print the number of tosses made? If the draw is achieved only when both players have the same number of coins, could you adapt your code in some way? Thank you!
    – TeM
    Nov 27 at 16:19




    I'm amazed at the speed !! I have a couple of questions! Is it possible to print the number of tosses made? If the draw is achieved only when both players have the same number of coins, could you adapt your code in some way? Thank you!
    – TeM
    Nov 27 at 16:19












    Suppose, for simplicity, the case in which the tokens to accumulate are 100. CASE A: the draw is when at the end of the game the two players have the same number of coins (both 100 or both 101). CASE B: the draw occurs when at the end of the game the two players have accumulated at least 100 tokens. The code that I have reported here is CASE B, that produces your own results.
    – TeM
    Nov 27 at 20:39




    Suppose, for simplicity, the case in which the tokens to accumulate are 100. CASE A: the draw is when at the end of the game the two players have the same number of coins (both 100 or both 101). CASE B: the draw occurs when at the end of the game the two players have accumulated at least 100 tokens. The code that I have reported here is CASE B, that produces your own results.
    – TeM
    Nov 27 at 20:39










    up vote
    4
    down vote













    Edit:



    m = 10;
    n = 100;
    Table[Sign@
    Differences@
    Flatten[FirstPosition[#, 1] & /@
    UnitStep[Accumulate /@ RandomInteger[{1, 2}, {2, m}] - m]], n]


    Original answer



    Here is more compact one but slow, it might be improved. ${+1,0,-1}={text{p1 wins},text{draw},text{p2 wins}}$



       n=100;
    Table[Sign@
    Differences[
    First@Flatten@Position[#, 10 | 11] & /@
    Accumulate /@ RandomInteger[{1, 2}, {2, 10}]], n]





    share|improve this answer



























      up vote
      4
      down vote













      Edit:



      m = 10;
      n = 100;
      Table[Sign@
      Differences@
      Flatten[FirstPosition[#, 1] & /@
      UnitStep[Accumulate /@ RandomInteger[{1, 2}, {2, m}] - m]], n]


      Original answer



      Here is more compact one but slow, it might be improved. ${+1,0,-1}={text{p1 wins},text{draw},text{p2 wins}}$



         n=100;
      Table[Sign@
      Differences[
      First@Flatten@Position[#, 10 | 11] & /@
      Accumulate /@ RandomInteger[{1, 2}, {2, 10}]], n]





      share|improve this answer

























        up vote
        4
        down vote










        up vote
        4
        down vote









        Edit:



        m = 10;
        n = 100;
        Table[Sign@
        Differences@
        Flatten[FirstPosition[#, 1] & /@
        UnitStep[Accumulate /@ RandomInteger[{1, 2}, {2, m}] - m]], n]


        Original answer



        Here is more compact one but slow, it might be improved. ${+1,0,-1}={text{p1 wins},text{draw},text{p2 wins}}$



           n=100;
        Table[Sign@
        Differences[
        First@Flatten@Position[#, 10 | 11] & /@
        Accumulate /@ RandomInteger[{1, 2}, {2, 10}]], n]





        share|improve this answer














        Edit:



        m = 10;
        n = 100;
        Table[Sign@
        Differences@
        Flatten[FirstPosition[#, 1] & /@
        UnitStep[Accumulate /@ RandomInteger[{1, 2}, {2, m}] - m]], n]


        Original answer



        Here is more compact one but slow, it might be improved. ${+1,0,-1}={text{p1 wins},text{draw},text{p2 wins}}$



           n=100;
        Table[Sign@
        Differences[
        First@Flatten@Position[#, 10 | 11] & /@
        Accumulate /@ RandomInteger[{1, 2}, {2, 10}]], n]






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 27 at 16:34

























        answered Nov 27 at 15:30









        Okkes Dulgerci

        3,6281716




        3,6281716






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Mathematica Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            Use MathJax to format equations. MathJax reference.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f186766%2fspeed-up-code-to-numerically-simulate-a-game-of-coin-tossing%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            QoS: MAC-Priority for clients behind a repeater

            Ивакино (Тотемский район)

            Can't locate Autom4te/ChannelDefs.pm in @INC (when it definitely is there)