Compact a comma delimited number list into ranges

Viewed 2650

I'm looking for a clever way to do the following operation:

Take a list of numbers:

1, 2, 3, 4, 5, 12, 13, 14, 19

and compact it into a string like so:

1-5, 12-14, 19

With the following rule: only compress into a range (i.e. use a dash) when the count of numbers in the range is 3 or more.

I.e.: 1, 2, 4, 5 would result in: 1, 2, 4, 5 and NOT: 1-2, 4-5

7 Answers

This is array range compacting. Here is a Python solution:

" """"considering input as "1,2,3,4,5,6,11,13,11,23" """" "


arr=list(map(int,input().strip().split(',')))
arr=list(set(arr))
arr.sort()
l2=[arr[0]]
for i in range(len(arr)):
    if i+1<len(arr) and i-1>-1:
        if arr[i]-arr[i-1]==1 and  arr[i+1]-arr[i]==1 :
            if  l2[-1]!='-':
                l2+=['-']
            else:
                l2=l2
        else:
                l2+=[arr[i]]
if len(arr)>1:
    l2+=[arr[len(arr)-1]]       
st=str(l2[0])
for i in range(1,len(l2)):
    if str(type(l2[i]))!=str(type(l2[i-1])):
        st+=str(l2[i])
    else:
        st+=','+str(l2[i])
print(st,sep='\n')

I know this is very bad code and not so optimum one yet. If someone needs help he can refer to this one. Edits are welcome, to make the code in Python using good data structure.

I have tried to make it as simple as possible, you need to first initialise a start value, a start position variable and an end position variable. Keep on incrementing the start variable if it is consecutive, or else make start and end position as the current position variable and append the result. In case the difference in position of start and end is zero, just append one value of that position. In case the value is one, add both the values individually. In case it is greater than one, add the start and end position variables to the result separated by a dash.


nums = [1, 2, 3, 4, 5, 12, 13, 14, 19]
nums.sort()
print(nums)
res = []


# Initialise the values for start and end position variables along with the start
start = nums[0]
sPos = 0
ePos = 0

for i in range(1,len(nums)):
    if nums[i] == start+1:
        # Keep incrementing ePos and start if the numbers are consecutive
        ePos = i
        start=start+1
    else:
        # In case there is a break in the sequence, calculate the difference between start and end
        if sPos == ePos:
            # If both pointing at same place add the element
            res.append(nums[sPos])
        elif ePos - sPos == 1:
            # In case there are just 2 numbers then add both of them
            res.append(nums[sPos])
            res.append(nums[ePos])
        else:
            # In case there are more than 2 numbers, then add the start and end with dash in between
            res.append(str(nums[sPos])+"-"+str(nums[ePos]))
        start = nums[i]
        sPos = i
        ePos = i
# Finally just check in the same manner for the last elements
if sPos == ePos:
    res.append(nums[sPos])
elif ePos - sPos == 1:
    res.append(nums[sPos])
    res.append(nums[ePos])
else:
    res.append(str(nums[sPos])+"-"+str(nums[ePos]))
start = nums[i]
sPos = i
ePos = i
print(res)
Related