ruby 如何从数组中取出最大值并将其值加倍

ui7jx7zq  于 2023-02-03  发布在  Ruby
关注(0)|答案(1)|浏览(130)

我有一些代码可以给我一些组合,我想从每个组合中找到最高的 driver_points 值,然后将其值加倍。
下面是我目前的代码:

# DRIVER AND TEAM ARRAYS
     driver_points = { "john" => 18.1, "mike" => 19.3, "paul" => 15.6, "mark" => 1.1 }
     driver_price = { "john" => 4.0, "mike" => 5.0, "paul" => 6.0, "mark" => 2.1 }
     team_points = { "cowboys" => 20.1, "bears" => 19.3, "lions" => 15.6, "united" => 2.8 }
     team_price = { "cowboys" => 1.0, "bears" => 2.0, "lions" => 3.0, "united" => 2.4 }

    # DEFINE VARIABLE AND TARGET
     teams = team_price.keys
     drivers = driver_price.keys
     target = 13.5

    # CREATE METHOD TO SUM BOTH PRICES AND POINTS FOR GIVEN COMBINATION
    def add_up(combo, ht, hd)
      t, d = combo
      ht[t] + hd.values_at(*d).sum
    end

    # ALL POSSIBLE COMBINATIONS OF TEAM AND DRIVERS
    all_driver_combos = drivers.combination(3).to_a
    all_combos = teams.product(all_driver_combos)

    # SHOW ALL COMBOS WHERE SUM DOES NOT EXCEED TARGET
    valid_combos = all_combos.select do |c|
      add_up(c, team_price, driver_price) <= target
    end

    # SORT VALID COMBOS BY SUM OF POINTS FOR EACH ELEMENT
    ordered = valid_combos.sort_by do |c|
      -add_up(c, team_points, driver_points)
    end

    #OUTPUT
    @combo = ordered.map do |c|
      { c.join(" ")=>{ price: add_up(c, team_price, driver_price),
             points: add_up(c, team_points, driver_points).round(2) } }
    end

其当前基于目标值输出组合(1支车队和3名车手),但按最高点排序:
[{"cowboys john mike mark"=>{:price=>12.1, :points=>58.6}}, {"bears john mike mark"=>{:price=>13.1, :points=>57.8}}, {"cowboys john paul mark"=>{:price=>13.1, :points=>54.9}}, {"united john mike mark"=>{:price=>13.5, :points=>41.3}}]
我希望能够找到最高的驱动程序,根据最高的 * 驱动程序_点 * 从每个组合,并加倍其点值。
例如,在我输出的第一个组合中:{"cowboys john mike mark"=>{:price=>12.1, :points=>58.6}}
我希望能够找到三个得分最高的车手-这将是约翰,迈克和马克之一,因为我不想包括车队。答案是迈克,因为他有19.3分。然后加倍迈克的车手积分,然后应该更新 :points=〉 sum。给出新的总积分77.9。此外,我希望能够移动最高积分车手开始的车手组合的目的,在视图中的样式。
所以我想要的输出是这样的:
| 团队|双倍|组合|价格|点数|
| - ------|- ------|- ------|- ------|- ------|
| 牛仔|传声器|约翰马克|十二、一|七十七点九|

1cklez4t

1cklez4t1#

你已经计算过

valid_combos
  #=> [["cowboys", ["john", "mike", "mark"]],
  #    ["cowboys", ["john", "paul", "mark"]],
  #    ["bears",   ["john", "mike", "mark"]],
  #    ["united",  ["john", "mike", "mark"]]]

考虑组合

c = ["cowboys", ["john", "mike", "mark"]]
        20.1      18.1    19.3     1.1

其中,"cowboys"的车队积分和该组合中三名车手的车手积分如下所示(有人需要和马克谈谈)。
该组合的总点数为

add_up(c, team_points, driver_points)
  #=> 58.6

为此,我们希望添加19.3积分,这是"Mike"的车手积分,因为他在组合的三名车手中拥有最多的积分:

58.6 + 19.3
  #=> 77.9

我们可以用如下代码来实现这一点。

def add_dbl(combo, team_points, driver_points)
  t, ds = combo
  dmax = ds.max_by { |d| driver_points[d] }
  driver_points[dmax] + add_up(combo, team_points, driver_points)
end

对于上面定义的组合c

add_dbl(c, team_points, driver_points)
  #=> 77.9

我们现在可以使用add_dbl代替add_up来对组合进行排序。

ordered = valid_combos.sort_by do |c|
  -add_dbl(c, team_points, driver_points)
end
  #=> [["cowboys", ["john", "mike", "mark"]],
  #    ["bears", ["john", "mike", "mark"]],
  #    ["cowboys", ["john", "paul", "mark"]],
  #    ["united", ["john", "mike", "mark"]]]

下面的代码重新排列驱动程序,以便在ordered中的每个驱动程序数组中,驱动程序点数最高的驱动程序显示在最前面。

ordered.each do |_t,ds|
  imax = ds.each_index.max_by { |i| driver_points[ds[i]] }  
  ds.unshift(ds.delete_at(imax))
end
  #=> [["cowboys", ["mike", "john", "mark"]],
  #    ["bears", ["mike", "john", "mark"]],
  #    ["cowboys", ["john", "paul", "mark"]],
  #    ["united", ["mike", "john", "mark"]]]

请参阅Array#each_index、Enumerable#max_by、Array#unshift和Array#delete_at。注意,Array#each返回其接收方(ordered),但我们正在修改该数组。
为了仅仅从最高到最低的驾驶员点对驾驶员进行排序,将上述表达式修改如下。

ordered.each do |_t,ds|
  ds.sort_by! { |d| -driver_points[d] }
end
  #=> [["cowboys", ["mike", "john", "mark"]],
  #    ["bears", ["mike", "john", "mark"]],
  #    ["cowboys", ["john", "paul", "mark"]],
  #    ["united", ["mike", "john", "mark"]]]

巧合的是,这些驱动程序阵列与上面的驱动程序阵列没有什么不同。
请参见数组#sort_by!。

相关问题