Don't like ads? PRO users don't see any ads ;-)

# Untitled

By: a guest on May 4th, 2012  |  syntax: None  |  size: 4.54 KB  |  hits: 10  |  expires: Never
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
1. require 'benchmark'
2.
3. class Gary
4.   # https://gist.github.com/1089115
5.   def score(dice)
6.     score_counts(dice).inject(0) {|score, pair| score + frequency_score(pair)}
7.   end
8.
9.   def frequency_score(pair)
10.     triple_score(pair) + single_score(pair)
11.   end
12.
13.   def triple_score(pair)
14.     (pair[:count] / 3) * triple_multiplier(pair[:score])
15.   end
16.
17.   def triple_multiplier(score)
18.     score == 1 ? 1000 : score * 100
19.   end
20.
21.   def single_score(pair)
22.     (pair[:count] % 3) * single_multiplier(pair[:score])
23.   end
24.
25.   def single_multiplier(score)
26.     case score
27.     when 1; 100
28.     when 5; 50
29.     else  ; 0
30.     end
31.   end
32.
33.   def score_counts(dice)
34.     (1..6).map do |score|
35.       {:score => score, :count => dice.select{|d| d == score}.size}
36.     end
37.   end
38. end
39.
40. class Jak
41.   # https://gist.github.com/1088610
42.   def score(dice)
43.     score = 0
44.     return score if dice.empty?
45.     counts = [0,0,0,0,0,0]
46.     dice.each {|d| counts[d-1] += 1 }
47.
48.     ones, twos, threes, fours, fives, sixes = counts
49.
50.     if ones >= 3 then
51.       score += 1000 + ((ones-3) * 100)
52.     else
53.       score += (ones * 100)
54.     end
55.
56.     if fives >= 3 then
57.       score += 500 + ((fives-3) * 50)
58.     else
59.       score += fives * 50
60.     end
61.
62.     score += 200 if twos >= 3
63.     score += 300 if threes >= 3
64.     score += 400 if fours >= 3
65.     score += 600 if sixes >= 3
66.
67.     score
68.   end
69. end
70.
71. class Serbrech
72.   # https://gist.github.com/906429
73.   def triple?(dice, val)
74.    dice.count {|die| die == val} >= 3
75.   end
76.
77.   def handle_triples(dice)
78.     return 0 if dice.empty?
79.     return 350 if triple? dice, 5
80.     return 700 if triple? dice, 1
81.     return_value = 0
82.     (2..6).each do |item|
83.       return_value = item * 100 if triple? dice, item
84.     end
85.     return return_value
86.   end
87.
88.   def score(dice)
89.     total = handle_triples dice
90.     dice.each do |die|
91.       total += 50 if die == 5
92.       total += 100 if die == 1
93.     end
94.     total
95.   end
96. end
97.
98. class Kevin
99.   # https://gist.github.com/1088913
100.   def score(dice)
101.     # Hash holds values seen in the roll and the number of duplicates for each
102.     h = Hash.new(0)
103.     dice.each { | d | h.store(d, h[d]+1) }
104.
105.     score = 0
106.
107.     score += h[1] * 100
108.     score += 700 if h[1] >= 3 # 1000 bonus points, minus the 3 * 100 points for the 1's in the set
109.
110.     score += 200 if h[2] >= 3
111.     score += 300 if h[3] >= 3
112.     score += 400 if h[4] >= 3
113.
114.     score += h[5] * 50
115.     score += 350 if h[5] >= 3 # 500 bonus points, minus the 3 * 50 points for the 5's in the set
116.
117.     score += 600 if h[6] >= 3
118.
119.     score
120.   end
121. end
122.
123. class Glebm
124.   # answer by Glebm at http://codereview.stackexchange.com/questions/423/is-this-good-ruby-ruby-koans-greed-task
125.   def score(dice)
126.     score = 0
127.
128.     # Below is equivalent to:
129.     #   counts = dice.inject(Hash.new(0)) { |h, x| h[x] += 1; h }
130.     counts = Hash.new(0)
131.     dice.each do |x|
132.       counts[x] += 1
133.     end
134.
135.     (1..6).each do |i|
136.       if counts[i] >= 3
137.         if i == 1
138.           score += 1000
139.         else
140.           score += 100 * i
141.         end
142.
143.         counts[i] = [counts[i] - 3, 0].max
144.       end
145.
146.       if i == 1
147.         score += 100 * counts[i]
148.       elsif i == 5
149.         score += 50 * counts[i]
150.       end
151.     end
152.
153.     score
154.   end
155. end
156.
157. class Felix
158.   # from Felix Alcala  http://codereview.stackexchange.com/questions/423/is-this-good-ruby-ruby-koans-greed-task
159.   def score(dice)
160.     patterns = {[1,1,1]=>1000, [2,2,2]=>200, [3,3,3]=>300, [4,4,4]=>400,
161.                 [5,5,5]=>500,  [6,6,6]=>600, 1=>100, 5=>50}
162.     sorted = dice.sort
163.
164.     triple = patterns[sorted[0..2]]
165.     single = patterns[sorted[0]]
166.     if triple
167.       partial_score = triple
168.       rest = sorted[3..-1]
169.     elsif single
170.       partial_score = single
171.       rest = sorted[1..-1]
172.     else
173.       partial_score = 0
174.       rest = sorted[1..-1]
175.     end
176.
177.     if rest
178.       partial_score + score(rest)
179.     else
180.       partial_score
181.     end
182.   end
183. end
184.
185. n = 500000
186. jak = Jak.new
187. serbrech = Serbrech.new
188. gary = Gary.new
189. kevin = Kevin.new
190. glebm = Glebm.new
191. felix = Felix.new
192.
193. [[], [5], [1], [1,5,5,1], [2,3,4,6], [1,1,1]].each do |to_score|
194.   Benchmark.bm do |x|
195.     puts "Results for: " + to_score.inspect
196.     x.report("jak:     ") { for i in 1..n; jak.score(to_score); end }
197.     x.report("serbrech:") { for i in 1..n; serbrech.score(to_score); end }
198.     x.report("gary:    ") { for i in 1..n; gary.score(to_score); end }
199.     x.report("kevin:   ") { for i in 1..n; kevin.score(to_score); end }
200.     x.report("glebm:   ") { for i in 1..n; glebm.score(to_score); end }
201.     x.report("felix:   ") { for i in 1..n; felix.score(to_score); end }
202.     puts "-----------------------------------------------------"
203.   end
204. end