Interesting problem from Balatro, from a hand of 8 without any pairs, if you discard n
and draw n
from the remaining deck of 44 cards. What’s the optimum n
to maximize your chance of obtaining at least a pair?
I am sure many of you are obsessed by Balatro. So I wrote some code to simulate this. For 1m simulations it ran in about 0.077s per n
.
Anyone wanna challenge my algorithm?
Edit: maximum n is 5
Edit: bug fix
Summary
const WEIGHTS = vcat(fill(3, 5), fill(4, 8))
function init_draw(discard)
# draw is the initial hand
WEIGHTS .= 4
@inbounds for i in 1:8
WEIGHTS[i] = 3
end
# for 1 to 8 there are 3 cards left
# for 9 to 13 there are 4 cards left
# if any of the first 3 cars is selected then done
l = 52 - 8
for i in 1:discard
# if it's one of the non-discarded cards
j = rand(1:l)
j <= 3*(8-discard) ? (return true) : (l -= 1)
# so it's not one of the non-discarded cards
# how many cards to skip
k = j - 3 * (8 - discard)
k1 = 8 - discard + 1
@inbounds while k > 0
k = k - WEIGHTS[k1]
k1 = k1 + 1
end
k1 = k1 - 1
@inbounds if k1 <= 8
WEIGHTS[k1]==2 ? (return true) : (WEIGHTS[k1] -= 1)
else
WEIGHTS[k1]==3 ? (return true) : (WEIGHTS[k1] -= 1)
end
end
return false
end
@code_warntype init_draw(5)
@time x5 = [init_draw(5) for _ in 1:1_000_000]; # 0.77586
@time x4 = [init_draw(4) for _ in 1:1_000_000];
@time x3 = [init_draw(3) for _ in 1:1_000_000];
@time x2 = [init_draw(2) for _ in 1:1_000_000];
@time x1 = [init_draw(1) for _ in 1:1_000_000];
sum(x5)/1_000_000
sum(x4)/1_000_000
sum(x3)/1_000_000
sum(x2)/1_000_000
sum(x1)/1_000_000