S'il y a deux éléments maximum d'un tableau?
Dans ce code, si l'utilisateur tapez 2, deux fois et 1, deux fois. Ensuite, il y a deux éléments maximum et Kinder et Twix doivent être imprimés. Mais comment ? Je peux probablement le faire avec la méthode if mais cela rendra mon code encore plus long. Une version cool? Puis-je faire cela avec un seul si?
a = [0, 0, 0,]
b = ["Kinder", "Twix", "Mars"]
while true
input = gets.chomp.to_i
if input == 1
a[0] += 1
elsif input == 2
a[1] += 1
elsif input == 3
a[2] += 1
elsif input == 0
break
end
end
index = a.index(a.max)
chocolate = b[index] if index
print a.max,chocolate
Réponses
La question n'a vraiment rien à voir avec la façon dont le tableau a
est construit.
def select_all_max(a, b)
mx = a.max
b.values_at(*a.each_index.select { |i| a[i] == mx })
end
b = ["Kinder", "Twix", "Mars"]
p select_all_max [0, 2, 1], b
["Twix"]
p select_all_max [2, 2, 1], b
["Kinder", "Twix"]
Voir Array # values_at .
Cela pourrait également être fait en un seul passage.
def select_all_max(a, b)
b.values_at(
*(1..a.size-1).each_with_object([0]) do |i,arr|
case a[i] <=> arr.last
when 0
arr << i
when 1
arr = [i]
end
end
)
end
p select_all_max [0, 2, 1], b
["Twix"]
p select_all_max [2, 2, 1], b
["Kinder", "Twix"]
p select_all_max [1, 1, 1], b
["Kinder", "Twix", "Mars"]
Une façon serait la suivante:
Tout d'abord, séparez simplement la collecte des entrées du comptage, nous allons donc simplement collecter les entrées dans cette étape:
inputs = []
loop do
input = gets.chomp.to_i
break if input.zero?
inputs << input
end
Nous pouvons maintenant compter les entrées. Si vous avez Ruby 2.7, vous pouvez simplement le faire counts_by_input = inputs.tally
pour obtenir { "Twix" => 2, "Kinder" => 2 }
. Sinon, mon approche préférée est d'utiliser group_by avec transform_values :
counts_by_input = inputs.group_by(&:itself).transform_values(&:count)
# => { "Twix" => 2, "Kinder" => 2 }
Maintenant, puisque nous allons extraire des valeurs en fonction de leur nombre, nous voulons que les nombres soient des clés. Normalement, nous pourrions inverser le hachage, mais cela ne fonctionnera pas dans ce cas car cela ne nous donnera qu'une valeur par clé, et nous avons besoin de plusieurs:
inputs_by_count = counts_by_input.invert
# => { 2 => "Kinder" }
# This doesn't work, it removed one of the values
Au lieu de cela, nous pouvons en utiliser un autre group_by
et transform_values
(la raison pour laquelle j'aime ces méthodes est qu'elles sont très polyvalentes ...):
inputs_by_count = counts_by_input.
group_by { |input, count| count }.
transform_values { |keyvals| keyvals.map(&:first) }
# => { 2 => ["Twix", "Kinder"] }
Le transform_values
code ici est probablement un peu déroutant, mais une chose importante à comprendre est que souvent, l'appel des méthodes Enumerable sur les hachages les convertit en [[key1, val1], [key2, val2]]
tableaux:
counts_by_input.group_by { |input, count| count }
# => { 2 => [["Twix", 2], ["Kinder", 2]] }
C'est pourquoi nous appelons transform_values { |keyvals| keyvals.map(&:first) }
ensuite pour obtenir le format souhaité{ 2 => ["Twix", "Kinder"] }
Quoi qu'il en soit, à ce stade, obtenir notre résultat est très simple:
inputs_by_count[inputs_by_count.keys.max]
# => ["Twix", "Kinder"]
Je sais que tout cela semble probablement un peu insensé, mais lorsque vous vous familiariserez avec les méthodes Enumerable, vous serez capable de faire ce type de transformation de données assez couramment.
Tl; dr, donne-moi le codez
inputs = []
loop do
input = gets.chomp.to_i
break if input.zero?
inputs << input
end
inputs_by_count = inputs.
group_by(&:itself).
transform_values(&:count).
group_by { |keyvals, count| count }.
transform_values { |keyvals| keyvals.map(&:first) }
top_count = inputs_by_count.keys.max
inputs_by_count[top_count]
# => ["Twix", "Kinder"]
Que diriez-vous quelque chose comme ça:
maximum = a.max # => 2
top_selling_bars = a.map.with_index { |e, i| b[i] if e == maximum }.compact # => ['Kinder', 'Twix']
p top_selling_bars # => ['Kinder', 'Twix']
Si tu as
a = [2, 2, 0,]
b = ['Kinder', 'Twix', 'Mars']
Vous pouvez calculer la valeur maximale a
via:
max = a.max #=> 2
et retrouvez tous les éléments correspondant à cette valeur via:
b.select.with_index { |_, i| a[i] == max }
#=> ["Kinder", "Twix"]