A format for expressing an ordered list of integers is to use a comma separated list of either:
- individual integers
- a range of integers denoted by the starting integer separated from the end integer in the range by a dash,
-
. - the range includes all integers in the interval including both endpoints. It is not considered a range unless it spans at least 3 numbers. For example
12, 13, 15-17
Complete the solution so that it takes a list of integers in increasing order and returns a correctly formatted string in the range format.
Example:
solution([-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20])
returns (-6,-3-1,3-5,7-11,14,15,17-20)
This challenge comes from jhoffner on CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!
Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!
Top comments (11)
I've challenged myself to come up with another JS solution. Highly functional, with sorting of the output but without the sort function.
Here it comes, including test cases:
lolol, when ES6 looks like Haskell 🤓
Did anybody ask for some ugly code?
How does it work? Well it's a oneshot, I didn't take any time before writing it, I guess it should be way easier:
r[]
: Initialize the result arraya.map
: In this one, a ternary operation is used in order to handle two cases:i && !(a[i-1]+1-e)
is true : We are not in the first element, and the previous one is equal to "current one minus 1". In this case, with somepop/concat/push
, take the last array of the result array and add the current element to iti && !(a[i-1]+1-e)
is false : Initialize the next element in the result array: an array with the current element ([e]
)r
is equal to this value at this stage:[[-6], [-3, -2, -1, 0, 1], [3, 4, 5], [7, 8, 9, 10, 11], [14, 15], [17, 18, 19, 20]]
, we need to format itr.map
: In this one,e
will be equal to each array. We will need to differentiate array with a length of 1 and the others, as their notation is different (-6
vs7-11
). To do this, we will use another ternary:e.length-1
is true : The current element has more than one element, build a string with the first and last elemente.length-1
is false : The current element has only one element, return a string with the array (''+[-6] will return"-6"
)You are grouping groups of 2. You should only be grouping 3 or more consecutive numbers.
Also, you are not sorting the list, so it will fail on unordered lists.
The problem states that the list will always go in increasing order
OK, I see now.
Of course solve can be re-written as one-liner if you feel the need for that.
This is my take on this one, longer code, hopefully easy to read...
And since I am a sucker for benchmarking, I compared it (Chrome 77, Win10) with the other solutions posted so far, 10 000 runs, average of 5 tests with the sample test data:
154 ms for erwzwanderman (first)
59 ms for erwzwanderman (second)
57 ms for La blatte
11 ms for Anders
(NOTE: I added a .join() to La blattes solution as it returns an array, not a string)
Hi,
It's possible also for [number, string] with combination of delimiters ?
I get with order of input only
Input => solution([1.1,1.2,1.3,1.5]);
Output=> 1.1,1.2,1.3,1.5
Ex. Output=> 1.1-1.3,1.5
Examples are given below:
Case 1 ==> [1.1, 1.2, 1.3, 1.4, 1.5]
Case 2 ==> [1-1, 1-2, 1-3, 1-4, 1-5]
Case 3 ==> [1-1.1, 1-1.2, 1-1.3, 1-2.1, 1-3.1]
Gaps and islands. I've done something similar in sql once, hope I can find that SO post tomorrow.
Well, I did find that SO post - had to change the solution a bit for the "group must contain more than two members" rule, but that was easy enough - So here's a pure T-SQL solution.
First, table setup:
Then, a cte to group the consecutive values together:
And finally query that cte:
Try it online!