Ruby - Сравнение чисел с использованием многомерного массива

Я работаю над проблемой, когда мне нужно сравнить число с массивом чисел, если 3 из 4 чисел совпадают.

Например:

winning_numbers = [["2537"], ["1294"], ["5142"]]

my_number = "1234"

Если сравнение имеет 3 сопоставимых числа, верните true. Если сравнение имеет менее 3 или точное совпадение возвращает false.

Из того, что я прочитал, я использую многомерный массив, однако я не понимаю, как циклически перебирать каждый массив по одному числу во времени, чтобы я мог сравнить его с моим номером.

Любая помощь будет принята с благодарностью.

Ответ 1

Вы можете сделать что-то вроде этого, которое возвращает все соответствующие числа:

winning_numbers.select do |number| 
  (number.first.split(//) & my_number.split(//)).size >= 3
end
#=> [["1294"], ["5142"]]

Возможно, вы захотите использовать find вместо select, когда вас интересует только первое сопоставление winning_number.

Ответ 2

Если бы не было повторяющихся цифр, мы могли бы использовать пересечение массива:

def triple?(winning_numbers, my_number)
  my_number_arr = my_number.chars
  winning_numbers.any? { |(w)| w.chars & my_number_arr).size == 3 }
end

winning_numbers = [["2537"], ["1294"], ["5142"]]
my_number = "1234"

triple?(winning_numbers, my_number) #=> true, matches "1294"

В качестве альтернативы вместо w.chars & my_number_arr).size == 3 мы могли бы написать

(w.chars - my_number_arr).size == 1 # (4-3=1)

Это не работает, однако, когда строки имеют повторяющиеся цифры, которые, конечно же, должны учитываться.

I предложили, чтобы метод Array#difference принимался как основной метод Ruby. Это было бы идеально для этой проблемы. См. Мой ответ в Array # difference для примеров его использования.

def triple?(winning_numbers, my_number)
  my_number_arr = my_number.chars
  winning_numbers.any? { |(w)| puts my_number_arr.difference(w.chars).size == 1 }
end

winning_numbers = [["2537"], ["1294"], ["5142"]]
my_number = "1234"

triple?(winning_numbers, my_number) #=> true, matches "1294"

Другой пример, который включает в себя повторяющиеся цифры:

winning_numbers = [["1551"], ["1594"], ["1141"]]

triple?(winning_numbers, my_number) # matches "1141"

и пример, где нет трехзначных совпадений:

winning_numbers = [["1551"], ["1594"], ["1561"]]

triple?(winning_numbers, my_number) #=> false (no match)