S
Sander Land
class Array
def score
sort.inject(0){|s,c| s+c > 21 && c==11 ? s+1 : s+c }
end
end
That has the some bug Eric found in Dennis's code:
=> 22[10, 11, 11].score
Thanks. I should have thought of this considering Dennis' results matched mine.
Here's my corrected solution. I renamed the ace to "1" for a more
elegant solution.
class Array
def score
(s=inject+)) <= 11 && index(1) ? s+10 : s
end
end
unless ARGV[0]
(1..10).each{|n| puts `ruby1.9 #{__FILE__} #{n}`}
exit
end
puts "upcard: #{upcard = ARGV[0].to_i}"
NDECKS = (ARGV[1]||2).to_i
CARDS = (((1..10).to_a+[10]*3)*4*NDECKS).tap{|c| c.delete_at c.index(upcard)}
score_count = [0]*27
cards = []
N=(ARGV[2]||1_000_000).to_i
N.times{
cards = CARDS.dup.shuffle if cards.size < 17
dealer = [upcard]
dealer << cards.pop while dealer.score < 17
score_count[dealer.score] += 1
}
puts %w[17 18 19 20 21 bust].join(' ')
puts (score_count[17..21] << score_count[22..-1].inject+)).map{|x|
'%-4.1f%% ' % (100.0*x / N )}.join
Results match Eric's results now.
upcard: 1
17 18 19 20 21 bust
12.8% 13.1% 13.0% 13.1% 36.3% 11.6%
upcard: 2
17 18 19 20 21 bust
14.0% 13.4% 13.1% 12.3% 11.9% 35.3%
upcard: 3
17 18 19 20 21 bust
13.3% 13.2% 12.5% 12.2% 11.5% 37.3%
upcard: 4
17 18 19 20 21 bust
13.1% 12.1% 12.1% 11.6% 11.3% 39.8%
upcard: 5
17 18 19 20 21 bust
12.2% 12.3% 11.7% 10.8% 10.7% 42.2%
upcard: 6
17 18 19 20 21 bust
16.6% 10.7% 10.7% 10.1% 9.8 % 42.1%
upcard: 7
17 18 19 20 21 bust
36.9% 13.9% 7.8 % 7.9 % 7.4 % 26.0%
upcard: 8
17 18 19 20 21 bust
12.9% 36.0% 12.9% 6.9 % 7.0 % 24.3%
upcard: 9
17 18 19 20 21 bust
12.1% 11.2% 35.3% 12.1% 6.1 % 23.1%
upcard: 10
17 18 19 20 21 bust
11.2% 11.2% 11.3% 33.6% 11.3% 21.3%