4/10/2011

Learning Ruby with Ruby Koans

I've gotten through more than half of the Ruby Koans in the past few weeks. Around the 174th test, the developer is asked to implement a method that solves a trivial problem. I would have liked to make the solution more simple, but this is what I could come up with, based on my current Ruby skill level.

# Greed is a dice game where you roll up to five dice to accumulate
# points.  The following "score" function will be used calculate the
# score of a single roll of the dice.
#
# A greed roll is scored as follows:
#
# * A set of three ones is 1000 points
#
# * A set of three numbers (other than ones) is worth 100 times the
#   number. (e.g. three fives is 500 points).
#
# * A one (that is not part of a set of three) is worth 100 points.
#
# * A five (that is not part of a set of three) is worth 50 points.
#
# * Everything else is worth 0 points.
#
#
# Examples:
#
# score([1,1,1,5,1]) => 1150 points
# score([2,3,4,6,2]) => 0 points
# score([3,4,5,3,3]) => 350 points
# score([1,5,1,2,4]) => 250 points
#
# More scoring examples are given in the tests below:
#
# Your goal is to write the score method.

def get_score_for_matching_roll(potential_roll, dice)
single_scores = {1=>100, 5=>50}
  triple_score_multipliers = {1=>1000}
  single_scores.default = 0
  triple_score_multipliers.default = 100
  triples_singles = dice.find_all { |roll| roll == potential_roll }.size.divmod(3)
  triples_singles[0]*triple_score_multipliers[potential_roll]*potential_roll +
          triples_singles[1]*single_scores[potential_roll]
end

def score(dice)
  # You need to write this method
  score = dice.uniq.inject(0) { |score, potential_roll|
    score + get_score_for_matching_roll(potential_roll, dice)
  }
end

No comments: