Skip to content

Instantly share code, notes, and snippets.

@Dispader
Last active August 3, 2016 17:26
Show Gist options
  • Save Dispader/5ae1e102ae2a8dbd2e8e to your computer and use it in GitHub Desktop.
Save Dispader/5ae1e102ae2a8dbd2e8e to your computer and use it in GitHub Desktop.
one proposed solution to the greed.rb problem, proposed in [Ian Whitney's Ruby Brown Bag](https://github.com/IanWhitney/ruby_brownbag}, for comment — please, please comment: I'm a Ruby tyro, and could use the help. (And many thanks to Ian for his great session, and Chris Crosby-Schmidt for inspiring the approach!)
class Greed
def self.score(dice)
# initialize a score
score = 0
# create a hash of the roll (face values) and the number of times rolled
rolls = dice.inject(Hash.new(0)) {|hash, roll| hash[roll] += 1; hash }
# for each set of 1s, add 1000 points to the score
if rolls[1]/3 > 0
score += ( rolls[1]/3 ) * 1000 # award 1000 points per set of 1s
rolls[1] -= ( rolls[1]/3 ) * 3 # remove each set from the roll count
end
# for each other set, add 100 points per set face value
(2..6).each { |roll|
if rolls[roll]/3 > 0
score += ( rolls[roll]/3 ) * ( 100 * roll) # award 100 * roll per set
rolls[roll] -= ( rolls[roll]/3 ) * 3 # remove sets from count
end
}
# TODO: FIX dry violation for above two methods
# for each (single) roll that has a pont value, award points to the score
{ 1 => 100, 5 => 50 }.each { |roll, points_per_roll|
score += points_per_roll * rolls[roll]
}
# yield the score
score
end
end
@Dispader
Copy link
Author

So— the first problem is probably that this is hella-not-DRY. But a close second in my mind is that the if rolls[roll]/3 > 0 et. al. is almost unreadable.

Would it be crazytown to use some kind of ( rolls[roll]/3 ).times here, or does that just make matters worse?

@enebo
Copy link

enebo commented Apr 11, 2016

I just saw your irb/completion thing on G+ and noticed this brown bag problem. Here is my soln. I feel it has some good aspects but it is somewhat golfed (although I could have killed it if I used enumerator and mixed scrore in):

class Greed
  SET_POINTS = [1000, 200, 300, 400, 500, 600]
  SINGLE_POINTS = [100, 0, 0, 0, 50, 0] 

  def self.score(rolls)
    counts = rolls.each_with_object(Array.new(6){0}) {|die, sum| sum[die-1] += 1 }
    sets_and_singles = counts.map { |die| die.divmod 3 }
    score = 0
    sets_and_singles.each_with_index do |(sets, singles), i|
      score += sets * SET_POINTS[i] + singles * SINGLE_POINTS[i]
    end
    score
  end
end

p Greed.score([1,1,1,5,1])
p Greed.score([3,4,5,3,3])

@enebo
Copy link

enebo commented Apr 11, 2016

@Dispader Holy crap am I getting old: http://stackoverflow.com/questions/4749973/ruby-greed-koan-how-can-i-improve-my-if-then-soup/13552277#13552277

I really did not remember this and this solution is not like the one I just wrote...How many times have I written greed in my life? I have no idea :)

@Dispader
Copy link
Author

@enebo Har— and I like all your approaches better than my first whack at it. I'm going through this weird re-transition, going back to getting my (client/caller) code functional.

Have you had a look at http://exercism.io/ yet? Pretty cool for the morning pushups.

(Hrm— and GitHub doesn't seem to notify me when I'm mentioned in Gists. Just happened to see your comment, there.)

@enebo
Copy link

enebo commented Aug 3, 2016

@Dispader ... nor me :) I have not checked exercism but I have a tab open and will check it out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment