Ruby Koans得分项目

4
我正在解决Ruby Koans问题,但我遇到了一些困难,不知道我编写的方法出了什么问题。我现在在about_scoring_project.rb文件中,我已经为骰子游戏编写了score方法。
def score(dice)
  return 0 if dice == []
  sum = 0
  rolls = dice.inject(Hash.new(0)) { |result, element| result[element] += 1; result; }
  rolls.each { |key, value| 
    # special condition for rolls of 1
    if key == 1  
      sum += 1000 | value -= 3 if value >= 3
      sum += 100*value
      next
    end
    sum += 100*key | value -= 3 if value >= 3
    sum += 50*value if key == 5 && value > 0
  }
  return sum
end

对于不熟悉该练习的人:
贪心是一个骰子游戏,您可以掷最多五个骰子来累积点数。以下“得分”函数将用于计算单次掷骰子的得分。
贪心掷骰的得分如下: - 三个一的组合值1000分。 - 三个数字(不是一)的组合值为该数字乘以100。例如,三个五的组合值为500分。 - 不在三个数字组合中的一的得分是100分。 - 不在三个数字组合中的五的得分是50分。 - 其他所有情况都为0分。
举例: - score([1,1,1,5,1]) => 1150分 - score([2,3,4,6,2]) => 0分 - score([3,4,5,3,3]) => 350分 - score([1,5,1,2,4]) => 250分
更多的得分示例在下面的测试中提供了。 您的目标是编写得分方法。
当我尝试运行文件中的最后一个测试时,遇到了麻烦:assert_equal 550, score([5,5,5,5]) 由于某种原因,我返回的是551而不是550。感谢您的帮助!

我也在那个测试中遇到了麻烦。 ;) - isomorphismes
19个回答

6

我的方法使用两个查找表——一个包含三元组的分数,另一个包含单个数字的分数。我使用这些表计算每个数字的分数,并使用 inject 累加总分:

def score(dice)
  triple_scores = [1000, 200, 300, 400, 500, 600]
  single_scores = [100, 0, 0, 0, 50, 0]
  (1..6).inject(0) do |score, number|
    count = dice.count(number)
    score += triple_scores[number - 1] * (count / 3)
    score += single_scores[number - 1] * (count % 3)
  end
end

5
这是我的方法:
def score(dice)
  # Count how many what
  clusters = dice.reduce(Hash.new(0)) {|hash, num| hash[num] += 1; hash }

  # Since 1's are special, handle them first
  ones = clusters.delete(1) || 0
  score = ones % 3 * 100 + ones / 3 * 1000

  # Then singular 5's
  score += clusters[5] % 3 * 50

  # Then the triples other than triple-one
  clusters.reduce(score) {|s, (num, count)| s + count / 3 * num * 100 }
end

虽然你的代码在 koans 中成功了,但是在 [1,5,1,5,1] 这样的情况下却失败了。通过简单地计算 1 的数量,假设任何三个 1 的价值都是 1000,而实际上,在这种情况下它们每个的价值只有 100,因此答案应该是 400,但是你的代码给出了 1100。 - RivieraKid
2
规则并没有规定三个必须是连续的。 :-) - Nigel Atkinson

4

我选择了

def score(dice)
  dice.uniq.map do |die|
    count = dice.count die
    if count > 2
      count -= 3
      die == 1 ? 1000 : 100 * die
    else 0
    end + case die
          when 1 then count * 100
          when 5 then count * 50
          else 0
          end
  end.inject(:+) || 0
end

3

这是因为您实际上是将一个 | 运算符(按位或)的结果添加到总分中:

sum += 100*key | value -= 3 if value >= 3 # This is 501 in your case

证明:
irb(main):004:0> value = 4
=> 4
irb(main):005:0> 100 * 5 | value -= 3 # This should be read as (500) | 1 which is 501
=> 501

那么将其改写为:

if value >= 3
  sum += 100 * key
  value -= 3
end

2
我的方法:
     def score(dice)
        score = 0
        score += dice.count(1) >= 3? (1000+ (dice.count(1) -3)*100): dice.count(1) * 100
        score += dice.count(5) >= 3 ? (500 + (dice.count(5) -3)*50): dice.count(5) * 50
       [2,3,4,6].each {|x| dice.count(x) >=3? score+= x*100:0}
       return score
    end

2
这是我的答案:
def score(dice)
  frequency = dice.inject(Hash.new(0)) do |h, el|
    h[el] += 1
    h
  end

  score_triples = { 1 => 1000 }
  score_singles = { 1 => 100, 5 => 50 }

  score = 0
  frequency.each do |k, v|
    score += v / 3 * score_triples.fetch(k, 100 * k)
    score += v % 3 * score_singles.fetch(k, 0)
  end
  score
end

2
这是我自己写的第一段代码(当然,离不开stackoverflow的帮助)。在看完其他答案后,我意识到它有些过度,特别是因为它适用于9个数字的骰子(这种存在吗?)
  def score(dice)
    
  if dice.empty?
    return 0
  end

  var_score = 0

  conteo = (0..9).to_a.each.map { |x| dice.count(x)} 
  
  #Evaluating 1
  if ( conteo[1] / 3 ) >= 0
    multiplier1 = conteo[1]/3
    var_score += multiplier1 * 1000
  end

  if ( conteo[1] % 3 ) != 0
    var_score += (conteo[1] % 3)*100
  end
  
  #Evaluating 5
  if ( conteo[5] % 3 ) != 0
    var_score += (conteo[5] % 3)* 50
  end

  #Evaluating numbers x 3    
  if (conteo[2..9].count { |x| x >= 3 }) > 0
    triplets = conteo[2..9].map {|x| x / 3}
    array_multiplicator = triplets.each_with_index.select {|num,index| (num > 0)}.map {|x| x[0]}
    product_triplets = triplets.each_with_index.select {|num,index| (num > 0)}.map {|x| x[1]}.map {|x| (x+2)*100}
    var_score += array_multiplicator.zip(product_triplets).map{|x| x.inject(&:*)}.sum
  end

  var_score
end

2

它用了29行,但这是我的第一个Ruby程序

    def score(dice)
      return 0 if dice == [] 
      sums = Array.new  # To hold number of occurrences 1 - 6
      for i in 0..6     # Initialize to 0... note [0] is not used 
        sums[i] = 0
      end
      total = 0   # To hold total
      dice.each do |dots|   # Number of dots showing on dice
        sums[dots] += 1     # Increment the array members 1 - 6
      end 
        if sums[1] > 2 then # If 3 1's
          total += 1000 
          sums[1] -= 3   # Remove the 3 you took, in case there's more
        end
        if sums[2] > 2  then total += 200  # If 3 2's
        end
        if sums[3] > 2  then total += 300   #If 3 3's
        end
        if sums[4] > 2  then total += 400    #If 3 4's
        end
        if sums[5] > 2  then total += 500     #If 3 5's
          sums[5] -= 3                        #Remove the 5's you took
        end
        if sums[6] > 2  then total += 600  #If 3 6's
        end
     total += (sums[1] * 100)   # If any ones are left
     total += (sums[5] * 50)    # Same for fives
     return total
end

1
我的方法是:
def score(dice)
  calculator = ->(no, group_multipler, individual_multipler) { (no / 3 * group_multipler) + (no % 3 * individual_multipler) }
  dice.group_by {|i| i % 7 }.inject(0) do |total, (value, scores)|
    group_multipler, individual_multipler = case value
    when 1
      [1000, 100]
    when 5
      [500, 50]
    else 
      [value * 100, 0]
    end
    total += calculator.call(scores.size, group_multipler, individual_multipler)
  end
end

1

我的方法使用整数除法和模数除法:

def score(dice)
    points = 1000 * (dice.count(1) / 3)
    points += 100 * (dice.count(1) % 3)
    points += 50 * (dice.count(5) % 3)
    (2..6).each do |i|
        points += (100 * i) * (dice.count(i) / 3)
    end
    points
end

我觉得这段代码会失败,给定“[1, 2, 1, 2, 1, 2]”,分数将是1100,但实际上应该是300。所有的count函数所做的就是计算某个东西出现的次数:# 如果有一个块被给出,计算块返回true值的元素的数量。 # # ary = [1, 2, 4, 2] # ary.count #=> 4 # ary.count(2) #=> 2 # ary.count { |x| x%2 == 0 } #=> 3 - CodyEngel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接