Вы удаляете элементы из коллекции, перебирая ее - ожидайте, что случится что-то плохое. Короче говоря, не делайте этого, если вы не хотите, чтобы такие проблемы, см .:
> arr = [1,2,1]
# => [1, 2, 1]
> arr.each {|x| puts x; arr.delete(x) }
# 1
# => [2]
Мы никогда не получим 2
в нашей итерации.
Простое решение, представляющее собой небольшой вариант вашего кода, может выглядеть следующим образом:
def sock_merchant(ar)
ar.uniq.sum do |item|
ar.count(item) / 2
end
end
Который в основном находит все уникальные носки, а затем подсчитывает пары для каждого из них.
Обратите внимание, что его сложность составляет n^2
, поскольку для каждого уникального элемента n
массива необходимо пройти весь массив, чтобы найти все элементы, равные n
.
Альтернатива: сначала сгруппируйте все носки, затем проверьте, сколько у нас пар каждого типа:
ar.group_by(&:itself).sum { |k,v| v.size / 2 }
Как ar.group_by(&:itself)
, сокращение от ar.group_by { |x| x.itself }
будет перебирать массив и создавать хеш, похожий на это:
{"50"=>["50", "50"], "49"=>["49", "49", "49", "49"], "38"=>["38"], ...}
И, вызвав sum
, мы переберем его, суммируя количество найденных элементов (/2
).