Terminology | Meaning |
---|---|
CNR | Count with No Replacement |
BJcore | core of the Blackjack application |
Commonly we find the pattern P(event(e1,e2)) = P((f(e1) && g(e2)) || (f(e2) && g(e1))), in which f
and g
are boolean functions.
So, we write this pattern with high-order functions.
function isCombination(f, g, e1, e2)
if (f(e1) && g(e2)) || (f(e2) && g(e1))
true
else
false
end
end
# isBJ
function isBJ(e1, e2)
isCombination(BJcore.isA, BJcore.isTens, e1, e2)
end
Let’s suppose we just started a hand, 6 decks of 52 cards.
The probability to have a ten and an ace is of:
In which, N(A;10s)
.
P = 2*((6*4)*(6*4*4))/((6*52)*(6*52-1))
Therefore, the probability is ~0.0475.
include("src/noreplace-histogram.jl")
N = 10^5
cnt = 0
for i in 1:N
event = CNR.CardEventNR(3, 6)
if (isA(event[1]) && isTens(event[3]) || isA(event[3]) && isTens(event[1]))
cnt += 1
end
end
P_BJ = cnt / N # => 0.0480
Therefore, P(BJ)=~0.0480, at first hand, using Monte Carlo Method.
In which, the helper functions isA
and isTens
are defined as:
function isA(event)
if event == "A"
true
else
false
end
end
function isTens(event)
if event == "10" || event == "Q" || event == "J" || event == "K"
true
else
false
end
end
function cardEvent()
hit = rand(1:pcards)
if deck[hit].first == "A"
deck[hit].first
else
return string(deck[hit].second[1])
end
end
- Q&A (Stack Overflow)
using DataStructures
N = 10^3
frequency2 = [cardEvent() for _ in 1:N]
anim = @animate for i = 1:N
if i < 10
f = counter(frequency2[1:i])
P = [j / sum(f) for j in values(f)]
bar([keys(f)...], P, title=L"\mathbf{retiradas}")
elseif mod(i, 10) == 0
f = counter(frequency2[1:i])
P = [j / sum(f) for j in values(f)]
bar([keys(f)...], P, title=L"\mathbf{retiradas}")
end
end
gif(anim, "mygif.gif", fps=1)
function cardEventNR(n=1, dks=6, r=false)
c = repeat(cards, 4 * dks) # 4 cards per number of decks per card-type
hits = sample(c, n, replace=r)
return hits
end
frequency3 = cardEventNR(312, 6)
anim3 = @animate for i = 1:(13*6*4)
f = counter(frequency3[1:i])
P = [j / sum(f) for j in values(f)]
title = "$i retiradas"
bar([keys(f)...], P, title=title)
end
gif(anim3, "mygif-noreplace.gif", fps=10)
preferences
must follow the structure Vector{Pair{String,Int64}}
, e.i., [“A” => 3, “K”=>3].
Given the chosen n
decks, we have
We take m
, divide by 4, and take the floor. Thus, we have of many complete decks are emptied by that card-type. Further, we take the modulus mod(m,4)
, so we have how many cards have to be depleted from a deck. Finally, we removed all cards of this type with the given quantity asked.
We have the following, when we calculate the probability of getting a blackjack at first play - for context,
function P_BJ(n=10^6)
N = n
cnt = 0
for i in 1:N
event = CNR.CardEventNR(3, 6)
if ((BJcore.isA(event[1]) && BJcore.isTens(event[3])) || (BJcore.isA(event[3]) && BJcore.isTens(event[1])))
cnt += 1
end
end
P_BJ = cnt / N # => ~0.0475
print("Probability of BJ, at first hand: $(P_BJ)")
end
end
We notice that, on the line,
if ((BJcore.isA(event[1]) && BJcore.isTens(event[3])) || (BJcore.isA(event[3]) && BJcore.isTens(event[1])))
There is a pattern that is common on calculating probabilities for any event that doesn’t depend on order. That is, f(a).g(b) + f(b).g(a).
macro isCombination(f,g,e1,e2)
return :( ( f(e1) && g(e2) ) || ( f(e2) && g(e1) ) )
end
function make_expr2(op, opr1, opr2)
opr1f, opr2f = map(x -> isa(x, Number) ? 2*x : x, (opr1, opr2))
retexpr = Expr(:call, op, opr1f, opr2f)
return retexpr
end
https://docs.julialang.org/en/v1/manual/metaprogramming/#Functions-on-Expressions
julia> function make_expr2(op, opr1, opr2)
opr1f, opr2f = map(x -> isa(x, Number) ? 2*x : x, (opr1, opr2))
retexpr = Expr(:call, op, opr1f, opr2f)
return retexpr
end
make_expr2 (generic function with 1 method)
julia> make_expr2(:+, 1, 2)
:(2 + 4)
julia> ex = make_expr2(:+, 1, Expr(:call, :*, 5, 8))
:(2 + 5 * 8)
julia> eval(ex)
42
ffmpeg -i mygif.gif -c:v libx264 -profile:v baseline -level 3.0 -pix_fmt yuv420p working.mp4