Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby Koans Scoring Project

Tags:

ruby

I'm working through the Ruby Koans, and I'm having a bit of trouble figuring out what is going wrong with a method I've written. I'm in about_scoring_project.rb, and I've written the score method for the dice game:

def score(dice)
  return 0 if dice == []
  sum = 0
  rolls = dice.inject(Hash.new(0)) { |result, element| result[element] += 1; result; }
  rolls.each { |key, value| 
    # special condition for rolls of 1
    if key == 1  
      sum += 1000 | value -= 3 if value >= 3
      sum += 100*value
      next
    end
    sum += 100*key | value -= 3 if value >= 3
    sum += 50*value if key == 5 && value > 0
  }
  return sum
end

For those unfamiliar with the exercise:

Greed is a dice game where you roll up to five dice to accumulate points. The following "score" function will be used to 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.

I run into trouble when I try to run the last test in the file: assert_equal 550, score([5,5,5,5])

For some reason I am returning 551 instead of 550. Thanks for your help!

like image 415
Max Gillett Avatar asked Oct 22 '25 16:10

Max Gillett


2 Answers

My approach uses two lookup tables - one containing the scores for triples, the other for singles. I work out the score for each number using the tables, and accumulate the total using inject:

def score(dice)
  triple_scores = [1000, 200, 300, 400, 500, 600]
  single_scores = [100, 0, 0, 0, 50, 0]
  (1..6).inject(0) do |score, number|
    count = dice.count(number)
    score += triple_scores[number - 1] * (count / 3)
    score += single_scores[number - 1] * (count % 3)
  end
end
like image 77
user200783 Avatar answered Oct 25 '25 18:10

user200783


Here is my approach:

def score(dice)
  # Count how many what
  clusters = dice.reduce(Hash.new(0)) {|hash, num| hash[num] += 1; hash }

  # Since 1's are special, handle them first
  ones = clusters.delete(1) || 0
  score = ones % 3 * 100 + ones / 3 * 1000

  # Then singular 5's
  score += clusters[5] % 3 * 50

  # Then the triples other than triple-one
  clusters.reduce(score) {|s, (num, count)| s + count / 3 * num * 100 }
end
like image 39
Aetherus Avatar answered Oct 25 '25 17:10

Aetherus



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!