यदि किसी सरणी के दो अधिकतम तत्व हैं?
इस कोड में यदि उपयोगकर्ता 2, दो बार और 1, दो बार टाइप करता है। फिर दो अधिकतम तत्व हैं और किंडर और ट्विक्स दोनों को मुद्रित किया जाना चाहिए। पर कैसे ? मैं शायद अगर विधि के साथ ऐसा कर सकता हूं, लेकिन इससे मेरा कोड और भी लंबा हो जाएगा। कोई शांत संस्करण? क्या मैं ऐसा सिर्फ एक के साथ कर सकता हूं?
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
जवाब
सवाल वास्तव में सरणी a
के निर्माण के साथ कुछ नहीं करना है।
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"]
देखें Array # मान_at ।
यह वैकल्पिक रूप से एक पास में किया जा सकता है।
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"]
एक तरीका इस प्रकार होगा:
सबसे पहले, इनपुट-जमा को गिनती से अलग करें, इसलिए हम इस चरण में इनपुट एकत्र करेंगे:
inputs = []
loop do
input = gets.chomp.to_i
break if input.zero?
inputs << input
end
अब हम इनपुट्स को टैली कर सकते हैं। यदि आपके पास रूबी 2.7 है तो आप बस counts_by_input = inputs.tally
प्राप्त करने के लिए कर सकते हैं { "Twix" => 2, "Kinder" => 2 }
। अन्यथा, मेरा पसंदीदा तरीका ट्रांसफॉर्म_वेल्यूज़ के साथ group_by का उपयोग करना है :
counts_by_input = inputs.group_by(&:itself).transform_values(&:count)
# => { "Twix" => 2, "Kinder" => 2 }
अब, क्योंकि हम उनकी गिनती के आधार पर मान निकाल रहे हैं, हम चाहते हैं कि गिनती के रूप में हो। आम तौर पर हम हैश उल्टा कर सकते हैं , लेकिन यह इस मामले में काम नहीं करेगा क्योंकि यह हमें प्रति कुंजी केवल एक मूल्य देगा, और आपको इसकी आवश्यकता नहीं होगी:
inputs_by_count = counts_by_input.invert
# => { 2 => "Kinder" }
# This doesn't work, it removed one of the values
इसके बजाय, हम एक group_by
और का उपयोग कर सकते हैं transform_values
(कारण मुझे इन विधियों को पसंद है क्योंकि वे बहुत बहुमुखी हैं ...):
inputs_by_count = counts_by_input.
group_by { |input, count| count }.
transform_values { |keyvals| keyvals.map(&:first) }
# => { 2 => ["Twix", "Kinder"] }
यहां transform_values
कोड शायद थोड़ा भ्रमित करने वाला है, लेकिन समझने के लिए एक महत्वपूर्ण बात यह है कि कई बार, हैश पर एन्युमरेबल तरीकों को कॉल करना उन्हें [[key1, val1], [key2, val2]]
सरणियों में परिवर्तित करता है :
counts_by_input.group_by { |input, count| count }
# => { 2 => [["Twix", 2], ["Kinder", 2]] }
यही कारण है कि हम transform_values { |keyvals| keyvals.map(&:first) }
अपने वांछित प्रारूप को प्राप्त करने के लिए बाद में कॉल करते हैं{ 2 => ["Twix", "Kinder"] }
वैसे भी, इस समय हमारा परिणाम प्राप्त करना बहुत आसान है:
inputs_by_count[inputs_by_count.keys.max]
# => ["Twix", "Kinder"]
मुझे पता है कि यह सब शायद थोड़ा पागल लगता है, लेकिन जब आप एन्युमरेबल तरीकों से परिचित हो जाते हैं तो आप इस तरह के डेटा ट्रांसफ़ॉर्मेशन को बहुत तेज़ी से कर पाएंगे।
टीएल; डॉ।, मुझे कोडज़ दें
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"]
इस जैसे किसी और के बारे में क्या राय है:
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']
यदि आपके पास है
a = [2, 2, 0,]
b = ['Kinder', 'Twix', 'Mars']
आप इसके a
माध्यम से अधिकतम मूल्य की गणना कर सकते हैं :
max = a.max #=> 2
और उस मान के अनुसार सभी तत्वों को खोजें:
b.select.with_index { |_, i| a[i] == max }
#=> ["Kinder", "Twix"]