{"id":115,"date":"2009-08-17T21:56:59","date_gmt":"2009-08-18T01:56:59","guid":{"rendered":"http:\/\/www.peteonsoftware.com\/?p=115"},"modified":"2024-03-02T17:21:06","modified_gmt":"2024-03-02T22:21:06","slug":"the-greed-ruby-koan","status":"publish","type":"post","link":"https:\/\/www.peteonsoftware.com\/index.php\/2009\/08\/17\/the-greed-ruby-koan\/","title":{"rendered":"The Greed Ruby Koan"},"content":{"rendered":"<p>This post is an extension of my <a href=\"https:\/\/www.peteonsoftware.com\/index.php\/2009\/08\/16\/ruby-koans\/\" alt=\"Last Ruby Koan Post\" title=\"Last Ruby Koan Post\">last post<\/a> on the Ruby Koans.  Today, I tackled the next Ruby Koan on the block, which was to score dice throws on a simplified version of the game <em>Greed<\/em>.  The first thing I noticed was that the Koans that I got from EdgeCase had a typo in it.  It suggested that the following was true:<\/p>\n<pre>\r\ndef test_score_of_mixed_is_sum\r\n    assert_equal 50, score([2,5,2,2,3])\r\n    assert_equal 550, score([5,5,5,5])\r\n  end\r\n<\/pre>\n<p>That first assert should actually total 250, as the 3 2&#8217;s are worth 200 and the 5 is worth 50.  I searched the web to make sure that I wasn&#8217;t crazy and the version of this file <a href=\"http:\/\/code.google.com\/p\/codeincubator\/source\/browse\/Samples\/timwingfield\/RubySandbox\/koans\/about_scoring_project.rb?spec=svn104&#038;r=104\" alt=\"Corrected Greed Koan\" title=\"Corrected Greed Koan\">checked in to Google Code<\/a> by <a href=\"http:\/\/blog.timwingfield.com\/\" alt=\"Tim Wingfield's Blog\" title=\"Tim Wingfield's Blog\">Tim Wingfield<\/a> agreed with me, so I forged on.<\/p>\n<p>The hardest part of this one for me was figuring out the best way to even work this out in English.  I play the Farkle game on Facebook quite a bit, so I was really comfortable with scoring the dice, but I just couldn&#8217;t figure out a good step-by-step way to do this.  I eventually decided on a Hash to tally up the number of each dice present.  This choice was made even easier when I found that Hash had an each_pair method that enumerated over the collection.<\/p>\n<p>After that, I tried my best to implement the logic (this code passes the tests, I don&#8217;t promise it is bug-free) and have now put this up for criticism.  Last time, I learned some great lessons from Nathan Kelley who shared his code in the comments of my <a href=\"https:\/\/www.peteonsoftware.com\/index.php\/2009\/08\/16\/ruby-koans\/#comments\" alt=\"Last Ruby Koan Post\" title=\"Last Ruby Koan Post\">last post<\/a>.  If you have any questions, comments, criticisms, or rebukes of this code, let me know and I&#8217;d love to hear them.  <\/p>\n<p>I definitely am guilty of writing C# in Ruby and had to undo a lot of code where I started to go down that path, so I welcome comments from Ruby enthusiasts on my code.<\/p>\n<pre>\r\nrequire 'edgecase'\r\n\r\n# Greed is a dice game where you roll up to five dice to accumulate\r\n# points.  The following \"score\" function will be used calculate the\r\n# score of a single roll of the dice.\r\n#\r\n# A greed roll is scored as follows:\r\n#\r\n# * A set of three ones is 1000 points\r\n#   \r\n# * A set of three numbers (other than ones) is worth 100 times the\r\n#   number. (e.g. three fives is 500 points).\r\n#\r\n# * A one (that is not part of a set of three) is worth 100 points.\r\n#\r\n# * A five (that is not part of a set of three) is worth 50 points.\r\n#\r\n# * Everything else is worth 0 points.\r\n#\r\n#\r\n# Examples:\r\n#\r\n# score([1,1,1,5,1]) =&gt; 1150 points\r\n# score([2,3,4,6,2]) =&gt; 0 points\r\n# score([3,4,5,3,3]) =&gt; 350 points\r\n# score([1,5,1,2,4]) =&gt; 250 points\r\n#\r\n# More scoing examples are given in the tests below:\r\n#\r\n# Your goal is to write the score method.\r\n\r\nSTANDARD_TRIPLET_MULTIPLIER = 100\r\nONES_TRIPLET_MULTIPLIER = 1000\r\nONES_VALUE = 100\r\nFIVES_VALUE = 50\r\n\r\ndef score(dice)\r\n  # You need to write this method\r\n  result = 0  \r\n  return result if invalid_dice?(dice)\r\n  \r\n  dice_sort = {1=&gt;0, 2=&gt;0, 3=&gt;0, 4=&gt;0, 5=&gt;0, 6=&gt;0}\r\n  \r\n  # Increment the tally, using the die face as the hash key\r\n  # by iterating over the passed in array of dice\r\n  dice.each do | die |\r\n      dice_sort[die] += 1 \r\n    end\r\n  \r\n  # Iterate over the pairs and score them up  \r\n  dice_sort.each_pair do |key, value|\r\n      if non_single_score?(key)\r\n        result += key*STANDARD_TRIPLET_MULTIPLIER if value&gt;= 3\r\n      else\r\n        # I LOVE Multiple assignments\r\n        groups_of_three, remainder = value\/3, value%3\r\n        \r\n        result += (ONES_TRIPLET_MULTIPLIER * groups_of_three) + (ONES_VALUE * remainder) if key == 1\r\n        result += (key * STANDARD_TRIPLET_MULTIPLIER * groups_of_three) + (FIVES_VALUE * remainder) if key == 5\r\n      end      \r\n  end \r\n      \r\n  result      \r\nend\r\n    \r\ndef non_single_score?(die)\r\n  return true if die != 1 and die != 5\r\nend\r\n\r\ndef invalid_dice?(dice)\r\n  return true if dice.length == 0\r\nend\r\n\r\nclass AboutScoringAssignment &lt; EdgeCase::Koan\r\n  def test_score_of_an_empty_list_is_zero\r\n    assert_equal 0, score([])\r\n  end\r\n\r\n  def test_score_of_a_single_roll_of_5_is_50\r\n    assert_equal 50, score([5])\r\n  end\r\n\r\n  def test_score_of_a_single_roll_of_1_is_100\r\n    assert_equal 100, score([1])\r\n  end\r\n\r\n  def test_score_of_mulitple_1s_and_5s_is_the_sum\r\n    assert_equal 300, score([1,5,5,1])\r\n  end\r\n\r\n  def test_score_of_single_2s_3s_4s_and_6s_are_zero\r\n    assert_equal 0, score([2,3,4,6])\r\n  end\r\n\r\n  def test_score_of_a_triple_1_is_1000\r\n    assert_equal 1000, score([1,1,1])\r\n  end\r\n\r\n  def test_score_of_other_triples_is_100x\r\n    assert_equal 200, score([2,2,2])\r\n    assert_equal 300, score([3,3,3])\r\n    assert_equal 400, score([4,4,4])\r\n    assert_equal 500, score([5,5,5])\r\n    assert_equal 600, score([6,6,6])\r\n  end\r\n\r\n  def test_score_of_mixed_is_sum\r\n    assert_equal 250, score([2,5,2,2,3])\r\n    assert_equal 550, score([5,5,5,5])\r\n  end\r\nend\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>This post is an extension of my last post on the Ruby Koans. Today, I tackled the next Ruby Koan on the block, which was to score dice throws on a simplified version of the &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[41],"tags":[45,105],"class_list":["post-115","post","type-post","status-publish","format-standard","hentry","category-ruby","tag-koans","tag-ruby"],"_links":{"self":[{"href":"https:\/\/www.peteonsoftware.com\/index.php\/wp-json\/wp\/v2\/posts\/115","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.peteonsoftware.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.peteonsoftware.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.peteonsoftware.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.peteonsoftware.com\/index.php\/wp-json\/wp\/v2\/comments?post=115"}],"version-history":[{"count":0,"href":"https:\/\/www.peteonsoftware.com\/index.php\/wp-json\/wp\/v2\/posts\/115\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.peteonsoftware.com\/index.php\/wp-json\/wp\/v2\/media?parent=115"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.peteonsoftware.com\/index.php\/wp-json\/wp\/v2\/categories?post=115"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.peteonsoftware.com\/index.php\/wp-json\/wp\/v2\/tags?post=115"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}