Check if all elements within Ruby submatrix are identical
Trying to check if all elements in sub-arrays are the same. For example, I have a 5x5 board and I want to know if one of the arrays contains everything x's
:
board = [[47, 44, 71, 8, 88],
['x', 'x', 'x', 'x', 'x'],
# [83, 85, 97, 'x', 57],
[83, 85, 97, 89, 57],
[25, 31, 96, 68, 51],
[75, 70, 54, 80, 83]]
I currently have:
def check_x
board.each do |x|
return true if x.include?('x')
end
return false
end
But that will just check if one is integers x
and not all. Any suggestions would be greatly appreciated.
A little more idiomatic:
board.one? { |row| row.all? { |item| item == 'x' } }
Easier than it board.map { |row| row.uniq.count == 1 }
will do
#=> [false, true, false, false, false]
uniq
returns unique elements in an array. map
here is iterating over your array and passing one line at a time to the block. It will return true
for cases where all elements of the array are the same ( ['x', 'x', 'x', 'x', 'x'].uniq #=> ['x']
which length is 1)
If you just want to check if the any string on the board has all the duplicate elements, Ruby only has a function. Guess what? any?
... Just change above one liner any?
like:
board.any? { |row| row.uniq.count == 1 } #=> true
If you want to know which rows have / have all duplicates and which are duplicates:
board.each.with_index.select { |row, index| row.uniq.count == 1 }
#=> [[["x", "x", "x", "x", "x"], 1]], where 1 is index.
Pure awesomeness of Ruby.
if all elements are the same in the array, which means that the maximum and minimum values are equal. for your board you can find the index of the required submatrix with this one line
board.each {|b| puts board.index(b) if b.max == b.min}
or just replace x.include?("x")
with x.min == x.max
in your function for true / false result
Assuming all items board
(board rows) are the same size, which seems like a reasonable assumption, you can do it like this:
x_row = ['x']*board.first.size
#=> ["x", "x", "x", "x", "x"]
board.any? { |row| row == x_row }
#=> true
Assuming it is always a fixed length array, your method could simply be:
def full_row
board.each do |row|
return true if (row.uniq.count == 1) && (row[0] == 'x')
end
return false
end
It can be boiled down to fewer lines, but I hate line wrapping in vim: p