Я не знаю, полностью ли это ваш случай, но если они всегда являются диапазонами чисел с интервалом 1, а не произвольным массивом, решение может быть оптимизировано до O (1), в отличие от других методов, использующих to_a
по крайней мере O (n). Другими словами, если у вас есть БОЛЬШОЙ диапазон, эти решения с массивами будут сильно подавляться.
Предполагая, что вы всегда будете использовать возрастающий диапазон чисел с интервалом 1, это означает, что вы можете считать их, просто используя size
(count
будет нашим врагом в этой ситуации).
С учетом сказанного, используя простую математику, вы можете сначала проверить, могут ли диапазоны пересекаться, если нет, просто вернуть 0. В противном случае вы можете наконец, вычислите новый интервал диапазона и получите его размер.
def range_intersection_count(x, y)
return 0 if x.last < y.first || y.last < x.first
([x.begin, y.begin].max..[x.max, y.max].min).size
end
Это будет считать количество элементов, которые пересекаются в двух диапазонах в O (1). Вы можете протестировать этот код с помощью чего-то вроде
range_intersection_count(5000000..10000000000, 3000..1000000000000)
, а затем попробовать тот же ввод с другими методами и наблюдать зависание вашей программы.
Окончательное решение будет выглядеть примерно так:
constant_range = (240..960)
sample_range = (540..1015)
inside_count = range_intersection_count(constant_range, sample_range) # = 421
outside_count = sample_range.size - inside_count # = 55