Ruby Koan 182 - 贪婪骰子 [英] Ruby Koan 182 - Greed Dice

查看:25
本文介绍了Ruby Koan 182 - 贪婪骰子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很快得出结论,我不能成为一名程序员.尽管在 Ruby Koans 中做了大量笔记并练习了所有内容,除了三遍 Codecademy 上的 Ruby 课程之外,目前我正在阅读 Chris Pine 的书,平均每天学习 6 小时……这个当前的 Koan 是一个练习沮丧和意识到并非每个人都可以成为程序员.

I'm quickly coming to the conclusion that I can't be a programmer. Despite taking ample notes and practicing everything in Ruby Koans up to this point on top of going through the Ruby course on Codecademy three times and currently making my way through Chris Pine's book averaging 6hrs a day studying...this current Koan is an exercise in frustration and the realization that not everyone can be a programmer.

练习如下

# 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.

def score(dice)
end

所以乍一看,我假设测试将通过 dice 提供随机数功能?还是需要我自己写?现在我必须限制掷骰子的范围?然后我所要做的就是获取数字并将它们放入一个数组中,但最多只能有 5 个位置(比如 而数组有 5 个或更少的条目? 然后我需要定义点系统的工作方式. 所以像score[0] = 100, score[2]= 200?但是现在我已经对分数进行了硬编码,如果第一个位置不是1而是5怎么办?然后这个数字是 50.那么 if/else 语句怎么样?类似

So looking at everything on first glance, I'm assuming the test will provide the random num functionality via dice? Or do I need to write that myself? Now I have to limit the range the dice rolls? Then all I have to do is get the numbers and put them into an array but only up to 5 positions (so like while array has 5 or less entries? I then need to define how the point system works. So something like score[0] = 100, score[2]= 200? But now I've hardcoded the scores, what if the first position isn't a 1 but is a 5? Then the number would be 50. So how about an if/else statement? something like

if score[0] == 1
  point = 100
elsif score[0] == 5
  point = 50
else point = 0

然后我对位置 [1]-[4] 重复这个?

Then I repeat this for positions [1]-[4]?

尽管非常想知道,但我不想简单地在谷歌上搜索答案,我宁愿因为找不到更好的词而得到某种指导.

Despite wanting to very badly, I don't want to simply google the answer, I'd rather get some kind of direction for lack of a better word.

希望这不是一个太笼统的问题,但您如何处理这样的问题?也许我应该先从头到尾通读 Pine 的书,然后再解决这个问题?

Hopefully this isn't too general of a question but how do you even approach something like this? Perhaps I should go through Pine's book from beginning to end first before tackling this?

推荐答案

你可以编写你的方法:

def score(d1,d2,d3,d4,d5)
  ...
end

您需要做的第一件事是确定五个值中的三个是否相同.如果三个相同,您将需要知道它们是 1 还是其他值,并且您需要知道其他两个值是什么.如果至多两个值相同,您也需要知道这一点.这才是问题的关键.所以让我们写一个方法:

The first thing you need to do is determine if three of five values are the same. If three are the same you will need to know if they are all 1's or some other value, and you will need to know what the other two values are. If at most two values are the same, you need to know that as well. That's really the crux of the problem. So lets write a method:

def partition(d1,d2,d3,d4,d5)
  ...
end

score 调用,如下所示:

which is called from score like this:

three_value, other_values = partition(d1,d2,d3,d4,d5)

哪里:

  • three_value 等于三个相等值组的公共值 (1-6) 或(比如说)nil 如果没有三个相等值的组;和
  • other_values[d1,d2,d3,d4,d5] 中排除三个相等值的两个值的数组(如果有一组三个相等的值)或 [d1,d2,d3,d4,d5](如果没有三个相等的值的组).
  • three_value equals the common value of the group of three equal values (1-6) or (say) nil if there is no group of three equal values; and
  • other_values is an array of the two values from [d1,d2,d3,d4,d5] that exclude the three equal values (if there is a group of three equal values) or [d1,d2,d3,d4,d5] (if there is no group of three equal values).

例如

three_value, other_values = partition(1,3,4,3,6)
  #=> [nil, [1, 3, 4, 3, 6]] 
three_value, other_values = partition(1,3,4,3,3)
  #=> [3, [1, 4]] 
three_value, other_values = partition(1,3,3,3,3)
  #=> [3, [1, 3]] 
three_value, other_values = partition(3,3,3,3,3)
  #=> [3, [3, 3]] 

一旦我们有了方法 partition,方法 score 如果非常简单:

Once we have the method partition, the method score if pretty straightforward:

def score(d1,d2,d3,d4,d5)
  three_value, other_values = partition(d1,d2,d3,d4,d5)

  total = case three_value
          when 1   then 1000
          when nil then    0
          else          three_value * 1000
          end

  other_values.each do |i|
    total += case i
             when ...
               ...
             when ...
               ...
             end
  end
end

在我们进入方法partition之前,我们可以将score简化如下:

Before we get on to the method partition, we can simplify score as follows:

def score(*d)
  three_value, other_values = partition(*d)

  total = case three_value
          when 1   then 1000
          when nil then    0
          else          three_value * 1000
          end

  other_values.each do |i|
    total += case i
             when ...
               ...
             when ...
               ...
             end
  end
end

使用splat"运算符 * 很方便,因为我们不关心骰子的滚动顺序.在调用scorepartition方法时,如果d = [1,3,4,3,3]score(*d) 等同于:

Using the "splat" operator, *, is convenient, because we don't care about the order of the rolls of the die. In calling the method score or partition, if d = [1,3,4,3,3], score(*d) is identical to:

score(1,3,4,3,3)    

(看看为什么 * 被称为splat"?)

(Do to see why * is called "splat"?)

在上面的方法 score 中,d(不是 *d)是一个包含五个值的数组.

In the method score above, d (not *d) is an array of five values.

现在让我们看看方法partition.我们需要计算每个结果 (1-6) 出现的次数.对于散列来说,这是一项很好的工作:

Now let's look at the method partition. We need to count the number of times each outcome (1-6) occurs. That's a good job for a hash:

def partition(*d)
  counts = {}
  d.each do |i|
    if counts.key?(i)
      counts[i] += 1
    else
      counts[i] = 1
    end
  end
  ...
end

假设 d = [1,3,4,3,3].然后

counts #=> {1=>1, 3=>3, 4=>1}

我们现在需要找到具有最大值的键.为此,我们可以使用 Enumerable#max_by:

We now need to find the key with the largest value. For that we could use Enumerable#max_by:

k, v = counts.max_by { |k,v| v }
  #=> [3, 3]
k #=> 3
v #=> 3

然后我们可以像这样计算other_values:

We can then calculate other_values like so:

other_values = case v
               when 3
                 d - [k]
               when 4
                 (d - [k]) << k
               when 5
                 (d - [k]) << k << k
               else
                 d
               end

注意 Array#- 是数组差分法.

Note Array#- is the array difference method.

最后,

 three_value = (v >= 3) ? k : nil

partition 将返回:

 [three_value, other_values]

你能把所有这些放在一起吗?

Can you put all this together?

[您可能不想阅读以下内容,直到您拥有可运行的代码.]

一旦您获得了 Ruby 的经验,您将能够按如下方式编写 partition:

Once you gain experience with Ruby you will be able to write partition as follows:

def partition(*d)
  k,v = d.each_with_object(Hash.new(0)) { |i,h| h[i]+=1 }.max_by(&:last)
  (v < 3)) ? [nil, d] : [k, d - [k] + [k]*(v-3)]
end                      

旁白:我想看到一个核心方法Array#difference,我定义并详细说明了此处.这将允许表示 partition 正文的最后一行:

Aside: I would like to see a core method Array#difference, which I define and elaborate here. This would allow the last line of the body of partition to be expressed:

(v < 3)) ? [nil, d] : [k, d.difference([k,k,k])]

这篇关于Ruby Koan 182 - 贪婪骰子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆