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

Untitled

By: a guest on May 4th, 2012  |  syntax: None  |  size: 4.54 KB  |  hits: 10  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
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