since the each iterates with the indexes and you are deleting an element in the inner loop the every other element in the next iteration. if you increase the number of elements and including the current index of the iteration in the loop you'll be able see the bigger picture.
arr = [1,2,3,4,5,6,7,8,9]
arr.each_with_index do |x,ix|
puts "loop1: #{arr.inspect}, x: #{x}, ix: #{ix}"
arr.each_with_index do |y, iy|
puts "loop2: #{arr.inspect}, y: #{y}, iy: #{iy}"
puts "#{arr.delete(y)}"
end
end
result
loop1: [1, 2, 3, 4, 5, 6, 7, 8, 9], x: 1, ix: 0
loop2: [1, 2, 3, 4, 5, 6, 7, 8, 9], y: 1, iy: 0
1
loop2: [2, 3, 4, 5, 6, 7, 8, 9], y: 3, iy: 1
3
loop2: [2, 4, 5, 6, 7, 8, 9], y: 5, iy: 2
5
loop2: [2, 4, 6, 7, 8, 9], y: 7, iy: 3
7
loop2: [2, 4, 6, 8, 9], y: 9, iy: 4
9
loop1: [2, 4, 6, 8], x: 4, ix: 1
loop2: [2, 4, 6, 8], y: 2, iy: 0
2
loop2: [4, 6, 8], y: 6, iy: 1
6
=> [4, 8]
since you are deleting during the loop and after each iteration the index is incremented but the array is one element short, so, it deletes the next (and all the) matching element(s) available and at the end the loop compares and stops the loop when index >= length