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?
– Αλέξανδρος Ζεγγ
Nov 27 at 9:43
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
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
|
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 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
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
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
|
show 4 more comments
4
Possible description of the algorithm, in natural language?
– Αλέξανδρος Ζεγγ
Nov 27 at 9:43
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
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
|
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
Nov 27 at 13:55
3
1 + RandomInteger
is equivalent toRandomInteger[{1, 2}]
– Okkes Dulgerci
Nov 27 at 14:40
@Okkes Thanks, indeed that is more concise.
– gwr
Nov 27 at 14:54
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
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
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
Nov 27 at 13:55
3
1 + RandomInteger
is equivalent toRandomInteger[{1, 2}]
– Okkes Dulgerci
Nov 27 at 14:40
@Okkes Thanks, indeed that is more concise.
– gwr
Nov 27 at 14:54
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
Nov 27 at 13:55
3
1 + RandomInteger
is equivalent toRandomInteger[{1, 2}]
– Okkes Dulgerci
Nov 27 at 14:40
@Okkes Thanks, indeed that is more concise.
– gwr
Nov 27 at 14:54
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 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 toRandomInteger[{1, 2}]
– Okkes Dulgerci
Nov 27 at 14:40
@Okkes Thanks, indeed that is more concise.
– gwr
Nov 27 at 14:54
add a comment |
2
@TeM Ok,Compile
brings this down to around 1 sec.
– gwr
Nov 27 at 13:55
3
1 + RandomInteger
is equivalent toRandomInteger[{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
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
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
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
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
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 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
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
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
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 Nov 27 at 16:34
answered Nov 27 at 15:30
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?
– Αλέξανδρος Ζεγγ
Nov 27 at 9:43
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
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