Studying with CodeWar (ruby) ⑤ proc

About this article

Little by little output of what I learned through the recently started Codewar

problem

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.

Example

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

My answer

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 withreturn`.

best practice

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

Explanation ①

 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.

Who is map (&: to_i)?

In ʻeachandmap`, 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 **

What is proc?

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&isproc`.

Explanation ②

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.

Finally

I'm not sure if the codes are recognized correctly, so if there are any differences, please point them out.

Recommended Posts

Studying with CodeWar (ruby) ⑤ proc
Studying with CodeWar (ruby) ④ case ~ when
Studying at CodeWar (ruby) ②
Studying at CodeWar (ruby) ⑥ inject
Studying at CodeWar (ruby) ③ squeeze, gsub
Start studying Ruby
Studying at CodeWar
Install Ruby 3.0.0 with asdf
Getting Started with Ruby
11th, Classification with Ruby
Evolve Eevee with Ruby
Ruby version switching with rbenv
Solve Google problems with Ruby
I tried DI with Ruby
GraphQL Client starting with Ruby
Ruby: Send email with Starttls
Leap year judgment with Ruby
Format Ruby with VS Code
Integer check method with ruby
Ruby Learning # 8 Working With String
[Ruby] problem with if statement
Use Ruby with Google Colab
[Ruby] REPL-driven development with pry
Getting Started with Ruby Modules
[ruby] Method call with argument
Install Ruby on MSYS2 with pacman
Make electronic music with randomness with Ruby
Ruby Scraping-Move Selenium Headless with VPS.
Learning Ruby with AtCoder 6 [Contest 168 Therefore]
Let's use Amazon Textract with Ruby
[Ruby] Extracting elements with slice method
[Ruby] Handle instance variables with instance methods
Handle DatePicker with Ruby / gtk3 + glade3
Impressions of making BlackJack-cli with Ruby
Install ruby on Ubuntu 20.04 with rbenv
<First post> I started studying Ruby
Make a typing game with ruby