我正在研究Ruby Koans,以便尝试学习Ruby,到目前为止,这非常好.我已经得到了贪婪的koan,在写这篇文章的时候是183.我有一个有效的解决方案,但我觉得我只拼凑了一堆if/then逻辑而且我不是拥抱Ruby模式.
在下面的代码中,您是否有方法指出我更全面地接受Ruby模式?(我的代码包含在"MY CODE [BEGINS | ENDS] HERE"评论中.
# 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.
# MY CODE BEGINS HERE
def score(dice)
# set up basic vars to handle total points and count of each number
total = 0
count = [0, 0, 0, 0, 0, 0]
# for each die, make sure we've counted how many occurrencess there are
dice.each do |die|
count[ die - 1 ] += 1
end
# iterate over each, and handle points for singles and triples
count.each_with_index do |count, index|
if count == 3
total = doTriples( index + 1, total )
elsif count < 3
total = doSingles( index + 1, count, total )
elsif count > 3
total = doTriples( index + 1, total )
total = doSingles( index + 1, count % 3, total )
end
end
# return the new point total
total
end
def doTriples( number, total )
if number == 1
total += 1000
else
total += ( number ) * 100
end
total
end
def doSingles( number, count, total )
if number == 1
total += ( 100 * count )
elsif number == 5
total += ( 50 * count )
end
total
end
# MY CODE ENDS HERE
class AboutScoringProject < EdgeCase::Koan
def test_score_of_an_empty_list_is_zero
assert_equal 0, score([])
end
def test_score_of_a_single_roll_of_5_is_50
assert_equal 50, score([5])
end
def test_score_of_a_single_roll_of_1_is_100
assert_equal 100, score([1])
end
def test_score_of_multiple_1s_and_5s_is_the_sum_of_individual_scores
assert_equal 300, score([1,5,5,1])
end
def test_score_of_single_2s_3s_4s_and_6s_are_zero
assert_equal 0, score([2,3,4,6])
end
def test_score_of_a_triple_1_is_1000
assert_equal 1000, score([1,1,1])
end
def test_score_of_other_triples_is_100x
assert_equal 200, score([2,2,2])
assert_equal 300, score([3,3,3])
assert_equal 400, score([4,4,4])
assert_equal 500, score([5,5,5])
assert_equal 600, score([6,6,6])
end
def test_score_of_mixed_is_sum
assert_equal 250, score([2,5,2,2,3])
assert_equal 550, score([5,5,5,5])
end
end
Run Code Online (Sandbox Code Playgroud)
非常感谢您提供的任何帮助,因为我试图了解Ruby.
Noa*_*man 41
哇!这里有很多非常酷的方法.我喜欢每个人的创造力.但是,我在这里提出了所有答案的教学问题.("教育学是对......教学过程的研究." - 维基百科)
从前几个koans(回到about_asserts.rb)可以明显看出,启发之路并不需要Ruby的任何先验/外部知识.似乎相当清楚,Path甚至不需要先前的编程经验.所以,从教育的角度来看,这公案必须回答的只使用方法,语言结构,并在早期koans教编程技术.这意味着:
Enumerable#each_with_indexEnumerable#countEnumerable#sortHash.new(0) 指定默认值Numeric#absNumeric#divmodcase when现在,我并不是说你不允许在你的实现中使用这些东西,但是koan不能要求使用它们.有必须是仅使用事先koans导入的构建的解决方案.
此外,由于模板只是
def score(dice)
# You need to write this method
end
Run Code Online (Sandbox Code Playgroud)
似乎暗示解决方案不应该定义其他方法或类.也就是说,你应该只更换# You need to write this method线.
这是一个符合我的哲学要求的解决方案:
def score (dice)
sum = 0
(1..6).each do |i|
idice = dice.select { |d| d == i }
count = idice.size
if count >= 3
sum += (i==1 ? 1000 : i*100)
end
sum += (count % 3) * 100 if i == 1
sum += (count % 3) * 50 if i == 5
end
sum
end
Run Code Online (Sandbox Code Playgroud)
这里的方法/结构在以下koan文件中介绍:
Enumerable#each about_iteration.rb
Enumerable#select about_iteration.rb
Array#size about_arrays.rb
a ? b : c about_control_statements.rb
% about_control_statements.rb
Run Code Online (Sandbox Code Playgroud)
相关StackOverflow问题:
ben*_*hor 22
一名学生问Joshu,"我如何编写算法来计算骰子游戏的分数?"
约瑟用棍子击打了学生并说道:"使用计算器."
def score(dice)
score = [0, 100, 200, 1000, 1100, 1200][dice.count(1)]
score += [0, 50, 100, 500, 550, 600][dice.count(5)]
[2,3,4,6].each do |num|
if dice.count(num) >= 3 then score += num * 100 end
end
score
end
Run Code Online (Sandbox Code Playgroud)
我经历了一次,每次通过一次测试.不确定这是一个非常"红宝石"的解决方案,但我确实很清楚每个部分正在做什么以及没有多余的值声明
def score(dice)
## score is set to 0 to start off so if no dice, no score
score = 0
## setting the 1000 1,1,1 rule
score += 1000 if (dice.count(1) / 3) == 1
## taking care of the single 5s and 1s here
score += (dice.count(5) % 3) * 50
score += (dice.count(1) % 3) * 100
## set the other triples here
[2, 3, 4, 5, 6].each do |num|
score += num * 100 if (dice.count(num) / 3 ) == 1
end
score
end
Run Code Online (Sandbox Code Playgroud)
看起来不错。我可能写的有些东西略有不同,比如:
def do_triples number, total
total + (number == 1 ? 1000 : number * 100)
end
Run Code Online (Sandbox Code Playgroud)
如果你想做一些除了 Ruby 之外很少有语言可以做的事情,我想在交替的星期二的 DIE 和 DRY 下,以下内容可能是合理的,但我不认为这些 Ruby 格言真的适用于常见的子表达式消除。反正:
def do_triples number, total
total +
if number == 1
1000
else
number * 100
end
end
def do_triples number, total
if number == 1
1000
else
number * 100
end + total
end
Run Code Online (Sandbox Code Playgroud)