你能帮我重构一下我为Ruby Koans#182提出的解决方案吗?这是你在其中写一个分数方法来计算贪婪游戏的分数的公案。以下代码工作,所有测试都通过。
然而,它感觉很长而且没有红宝石般的感觉。我怎样才能让它变得更好?
def score(dice)
rollGreedRoll = Hash.new
rollRollCount = Hash.new
(1..6).each do |roll|
rollGreedRoll[roll] = roll == 1 ? GreedRoll.new(1000, 100) :
GreedRoll.new( 100 * roll, roll == 5 ? 50 : 0)
rollRollCount[roll] = dice.count { |a| a == roll }
end
score =0
rollRollCount.each_pair do |roll, rollCount|
gr = rollGreedRoll[roll]
if rollCount < 3
score += rollCount * gr.individualPoints
else
score += gr.triplePoints + ((rollCount - 3) * gr.individualPoints)
end
end
return score
end
class GreedRoll
attr_accessor :triplePoints
attr_accessor :individualPoints
def initialize(triplePoints, individualPoints)
@triplePoints = triplePoints
@individualPoints = individualPoints
end
end
答案 0 :(得分:6)
我在https://gist.github.com/1091265进行了重构演练。最终解决方案如下:
def score(dice)
(1..6).collect do |roll|
roll_count = dice.count(roll)
case roll
when 1 : 1000 * (roll_count / 3) + 100 * (roll_count % 3)
when 5 : 500 * (roll_count / 3) + 50 * (roll_count % 3)
else 100 * roll * (roll_count / 3)
end
end.reduce(0) {|sum, n| sum + n}
end
请注意:
.reduce
是.inject
答案 1 :(得分:3)
你可以把rollRollCount放在第一个“每个”里面,不是吗?然后你不必迭代(1..6)两次。
答案 2 :(得分:2)
这是对它的另一种看法,将方法提取到自己的类中。有点长啰嗦,但易于阅读和理解:
def score(dice)
GreedScore.new(dice).calculate
end
实施:
class GreedScore
def initialize(dice)
@values = dice.sort
end
def calculate
@score = 0
score_triples
score_singles
@score
end
private
def score_triples
(1..6).each do |match|
if @values.count(match) >= 3
@score += match * (match == 1 ? 1000 : 100)
@values = @values.drop(3)
end
end
end
def score_singles
@values.each do |value|
@score += 100 if value == 1
@score += 50 if value == 5
end
end
end
答案 3 :(得分:1)
这是我的方法。假设骰子的数量很大,我使用散列表示性能。另外,我喜欢尽可能使用inject
。
def score(dice)
tally = 0
return tally if dice.length == 0
hash = dice.inject(Hash.new(0)) { |h,v| h[v] += 1; h }
(1..6).collect do |roll|
case roll
when 5
tally += (hash[roll] / 3) * 500 + (hash[roll] % 3) * 50
when 1
tally += (hash[roll] / 3) * 1000 + (hash[roll] % 3) * 100
else
tally += (hash[roll] / 3) * roll * 100
end
end
ap "dice = #{dice}, " + "hash = #{hash}, " + "tally = #{tally}"
tally
end