Little by little output of what I learned through the recently started Codewar
Bob is preparing to pass IQ test. The most frequent task in this test is to find out which one of the given numbers differs from the others. Bob observed that one number usually differs from the others in evenness. Help Bob — to check his answers, he needs a program that among the given numbers finds one that is different in evenness, and return a position of this number. ! Keep in mind that your task is to help Bob solve a real IQ test, which means indexes of the elements start from 1 (not 0)
I'll create a method that finds out-of-group numbers and returns those values.
If it is below, ʻiq_test ("2 4 7 8 10") `will return 3 which is the number obtained by adding +1 to the index number because only 7 is odd.
iq_test ("1 2 1 1") causes 2 to return 2 from the minority.
iq_test("2 4 7 8 10") => 3 // Third number is odd, while the rest of the numbers are even
iq_test("1 2 1 1") => 2 // Second number is even, while the rest of the numbers are odd
def iq_test(numbers)
numbers = numbers.split().map{|num| num.to_i}
even_count = numbers.select {|num| num.even?}.count
odd_count = numbers.select {|num| num.odd?}.count
numbers.each_with_index do |num, i|
if even_count > odd_count
return i + 1 if num.odd?
else
return i + 1 if num.even?
end
end
end
(1) Convert the data passed as an argument to an array with split
, and convert the elements of the array to numbers with to_i
with map
.
(2) Use select
to extract only even-numbered data and count how many there are with the count
method.
③ Count odd numbers in the same way as ②
④ Pass the array containing the numbers with ʻeach_with_indexnot only the elements but also the index numbers. ⑤ In conditional branching, compare which of even and odd numbers is the minority and return the minority with
return`.
It's still a short chord. .. ..
def iq_test(numbers)
nums = numbers.split.map(&:to_i).map(&:even?)
nums.count(true) > 1 ? nums.index(false) + 1 : nums.index(true) + 1
end
nums = numbers.split.map(&:to_i).map(&:even?)
Make numbers into an array with split
, convert the numbers with map
as it is, then evaluate whether it is even with the second map
and put the result of true / false in nums
ing.
In ʻeachand
map`, the following patterns are often used using blocks.
["1", "2", "3"].map{|v| v.to_i}
=> [1, 2, 3]
At this point, programmers realized the idea of "I want to be able to write shorter" and could write shorter by combining & operators
.
#normal
["1", "2", "3"].map{|v| v.to_i}
=> [1, 2, 3]
nums = numbers.split.map(&:to_i).map{|num| num.even?}
#&use
["1", "2", "3"].map(&:to_i)
=> [1, 2, 3]
nums = numbers.split.map(&:to_i).map(&:even?)
https://www.xmisao.com/2014/02/09/ruby-array-map-idiom-symbol-to-proc.html The map method is a method with a block, and of course you need to pass a block as an argument of the method with a block. ** But if you put & in front of an object that has a to_proc method, it will be interpreted as a block **
The object of the block is proc
.
Blocks can only be used when calling methods like ʻeach or
mapand cannot be treated as objects. Therefore, the object of the block using
&is
proc`.
nums.count(true) > 1 ? nums.index(false) + 1 : nums.index(true) + 1
Evaluate each number with nums = numbers.split.map (&: to_i) .map (&: even?)
, Put true / false in nums
, and the number of true is 1 or more. If so, it means that there are more even numbers and less odd numbers.
If there are many even numbers, the odd index number +1 is returned, and if the even numbers are not more than 1, the even index number +1 is returned.
I'm not sure if the codes are recognized correctly, so if there are any differences, please point them out.
Recommended Posts