36 lines
1.3 KiB
Ruby
36 lines
1.3 KiB
Ruby
def range_extract(l)
|
|
# pad the list with a big value, so that the last loop iteration will
|
|
# append something to the range
|
|
sorted, range = l.sort.concat([Float::MAX]), []
|
|
canidate_number = sorted.first
|
|
|
|
# enumerate over the sorted list in pairs of current number and next by index
|
|
sorted.each_cons(2) do |current_number, next_number|
|
|
# if there is a gap between the current element and its next by index
|
|
if current_number.succ < next_number
|
|
# if current element is our first or our next by index
|
|
if canidate_number == current_number
|
|
# put the first element or next by index into our range as a string
|
|
range << canidate_number.to_s
|
|
else
|
|
# if current element is not the same as the first or next
|
|
# add [first or next, first or next equals current add , else -, current]
|
|
seperator = canidate_number.succ == current_number ? "," : "-"
|
|
range << "%d%s%d" % [canidate_number, seperator, current_number]
|
|
end
|
|
# make the first element the next element
|
|
canidate_number = next_number
|
|
end
|
|
end
|
|
range.join(',')
|
|
end
|
|
|
|
lst = [
|
|
0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
|
|
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
|
25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
|
|
37, 38, 39
|
|
]
|
|
|
|
p rng = range_extract(lst)
|