Speed up code to numerically simulate a game of coin tossing
up vote
8
down vote
favorite
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
|
show 4 more comments
up vote
8
down vote
favorite
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
4
Possible description of the algorithm, in natural language?
– Αλέξανδρος Ζεγγ
2 days ago
2
Preallocatestorage
and write into it instead of expanding it successively withJoin
; eachJoin
requires a copy operation. ReplaceFor
byDo
. Leave awayMonitor
. AndCompile
everything in the end.
– Henrik Schumacher
2 days ago
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
2 days ago
1
But you are getting+1
for each throw and+1
conditional upon the result in your code above?
– gwr
2 days ago
1
@gwr: thank you very much, very kind, the next time I'll try to set it all up like this! =)
– TeM
2 days ago
|
show 4 more comments
up vote
8
down vote
favorite
up vote
8
down vote
favorite
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
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
performance-tuning programming
edited 2 days ago
gwr
7,20122457
7,20122457
asked 2 days ago
TeM
1,775618
1,775618
4
Possible description of the algorithm, in natural language?
– Αλέξανδρος Ζεγγ
2 days ago
2
Preallocatestorage
and write into it instead of expanding it successively withJoin
; eachJoin
requires a copy operation. ReplaceFor
byDo
. Leave awayMonitor
. AndCompile
everything in the end.
– Henrik Schumacher
2 days ago
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
2 days ago
1
But you are getting+1
for each throw and+1
conditional upon the result in your code above?
– gwr
2 days ago
1
@gwr: thank you very much, very kind, the next time I'll try to set it all up like this! =)
– TeM
2 days ago
|
show 4 more comments
4
Possible description of the algorithm, in natural language?
– Αλέξανδρος Ζεγγ
2 days ago
2
Preallocatestorage
and write into it instead of expanding it successively withJoin
; eachJoin
requires a copy operation. ReplaceFor
byDo
. Leave awayMonitor
. AndCompile
everything in the end.
– Henrik Schumacher
2 days ago
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
2 days ago
1
But you are getting+1
for each throw and+1
conditional upon the result in your code above?
– gwr
2 days ago
1
@gwr: thank you very much, very kind, the next time I'll try to set it all up like this! =)
– TeM
2 days ago
4
4
Possible description of the algorithm, in natural language?
– Αλέξανδρος Ζεγγ
2 days ago
Possible description of the algorithm, in natural language?
– Αλέξανδρος Ζεγγ
2 days ago
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
2 days ago
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
2 days ago
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
2 days ago
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
2 days ago
1
1
But you are getting
+1
for each throw and +1
conditional upon the result in your code above?– gwr
2 days ago
But you are getting
+1
for each throw and +1
conditional upon the result in your code above?– gwr
2 days ago
1
1
@gwr: thank you very much, very kind, the next time I'll try to set it all up like this! =)
– TeM
2 days ago
@gwr: thank you very much, very kind, the next time I'll try to set it all up like this! =)
– TeM
2 days ago
|
show 4 more comments
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.
2
@TeM Ok,Compile
brings this down to around 1 sec.
– gwr
2 days ago
3
1 + RandomInteger
is equivalent toRandomInteger[{1, 2}]
– Okkes Dulgerci
2 days ago
@Okkes Thanks, indeed that is more concise.
– gwr
2 days ago
add a comment |
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...
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
2 days ago
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
2 days ago
add a comment |
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]
add a comment |
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.
2
@TeM Ok,Compile
brings this down to around 1 sec.
– gwr
2 days ago
3
1 + RandomInteger
is equivalent toRandomInteger[{1, 2}]
– Okkes Dulgerci
2 days ago
@Okkes Thanks, indeed that is more concise.
– gwr
2 days ago
add a comment |
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.
2
@TeM Ok,Compile
brings this down to around 1 sec.
– gwr
2 days ago
3
1 + RandomInteger
is equivalent toRandomInteger[{1, 2}]
– Okkes Dulgerci
2 days ago
@Okkes Thanks, indeed that is more concise.
– gwr
2 days ago
add a comment |
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.
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.
edited 2 days ago
answered 2 days ago
gwr
7,20122457
7,20122457
2
@TeM Ok,Compile
brings this down to around 1 sec.
– gwr
2 days ago
3
1 + RandomInteger
is equivalent toRandomInteger[{1, 2}]
– Okkes Dulgerci
2 days ago
@Okkes Thanks, indeed that is more concise.
– gwr
2 days ago
add a comment |
2
@TeM Ok,Compile
brings this down to around 1 sec.
– gwr
2 days ago
3
1 + RandomInteger
is equivalent toRandomInteger[{1, 2}]
– Okkes Dulgerci
2 days ago
@Okkes Thanks, indeed that is more concise.
– gwr
2 days ago
2
2
@TeM Ok,
Compile
brings this down to around 1 sec.– gwr
2 days ago
@TeM Ok,
Compile
brings this down to around 1 sec.– gwr
2 days ago
3
3
1 + RandomInteger
is equivalent to RandomInteger[{1, 2}]
– Okkes Dulgerci
2 days ago
1 + RandomInteger
is equivalent to RandomInteger[{1, 2}]
– Okkes Dulgerci
2 days ago
@Okkes Thanks, indeed that is more concise.
– gwr
2 days ago
@Okkes Thanks, indeed that is more concise.
– gwr
2 days ago
add a comment |
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...
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
2 days ago
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
2 days ago
add a comment |
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...
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
2 days ago
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
2 days ago
add a comment |
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...
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...
edited 2 days ago
answered 2 days ago
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
2 days ago
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
2 days ago
add a comment |
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
2 days ago
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
2 days ago
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
2 days ago
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
2 days ago
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
2 days ago
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
2 days ago
add a comment |
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]
add a comment |
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]
add a comment |
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]
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]
edited 2 days ago
answered 2 days ago
Okkes Dulgerci
3,6281716
3,6281716
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
4
Possible description of the algorithm, in natural language?
– Αλέξανδρος Ζεγγ
2 days ago
2
Preallocate
storage
and write into it instead of expanding it successively withJoin
; eachJoin
requires a copy operation. ReplaceFor
byDo
. Leave awayMonitor
. AndCompile
everything in the end.– Henrik Schumacher
2 days ago
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
2 days ago
1
But you are getting
+1
for each throw and+1
conditional upon the result in your code above?– gwr
2 days ago
1
@gwr: thank you very much, very kind, the next time I'll try to set it all up like this! =)
– TeM
2 days ago