In ruby: def groups(from, to, max) size = to - from + 1 undivisable = (size % max).to_f group_step = (size.to_f / max).floor + (undivisable / max).floor leftovers = undivisable % max result = [] last_num = 0 max.times do next_num = last_num + group_step if leftovers > 0 next_num += 1 leftovers -= 1 end range = (last_num + 1)..(next_num) last_num = next_num result.push range end result end puts groups(1, 7, 5).inspect puts groups(1, 9, 5).inspect puts groups(1, 19, 5).inspect [1..2, 3..4, 5..5, 6..6, 7..7] [1..2, 3..4, 5..6, 7..8, 9..9] [1..4, 5..8, 9..12, 13..16, 17..19]