If this is [code-golf] then the winner should be the shortest program.
–
GarethOct 3 '12 at 16:42

1

Will we ever have input sequences that are not constantly increasing, for example: 4-9,1-2 or 1-3,9-6?
–
MattOct 3 '12 at 17:16

Or overlapping? Does the output have to be sorted and not contain duplicates?
–
Peter TaylorOct 3 '12 at 17:24

@Gareth Yes, this is a code-golf, then please vote-up for the shortest answer. Matt and Peter, I edited the question, please check it. Thanks!
–
BernaMarianoOct 3 '12 at 17:33

@BernaMariano With code-golf the shortest answer should win regardless of when it's posted (as long as it's within any given deadline). Your idea of everyone voting for the shortest answer when they look at the answers penalises anyone who doesn't post an answer quickly.
–
GarethOct 3 '12 at 18:14

6 Answers
6

GolfScript (24 chars)

I actually have four 24-char solutions, but I chose this one because it doesn't have any alphanumeric characters.

How it works

# On the stack: a string such as "1,3-5,9,16,18-23"
','/
# Split on commas to get ["1" "3-5" "9" "16" "18-23"]
{
# This is executed for each of those strings in a map
# So stack holds e.g. "1" or "3-5"
# Evaluate the string.
# If it's a single number, this puts the number on the stack.
# Otherwise it's parsed as a positive number followed by a negative number.
~
# Stack holds e.g. 1 or 3 -5
# Duplicate the last element on the stack and make a list of that length.
# If it's negative or zero, the list will be empty
.,
# Negate. An empty list => 1; a non-empty list => 0
!
# If the string was a single number "n", the stack now holds n 0
# If the string was a range "m-n", the stack now holds m -n 1
# The following block will be executed 0 times for "n" and once for "m-n"
{
# Here we rely on twos-complement numbers satisfying ~n = -n -1
# Stack: m -n
~))
# Stack: m -(-n)-1+2 = m n+1
,
# Stack: m [0 1 2 ... n]
>
# Stack: [m m+1 ... n]
~
# Stack: m m+1 ... n
}*
}%
# On the stack: e.g. [1 3 4 5 9 16 18 19 20 21 22 23]
','*
# Joined by , to give the desired output

{...}:r; # makes a function block ... and names it r
','/ # slices the top element of stack from each ','
# so we get ["1" "3-5" "9" "16" "18-23"]
{...}% # makes a function block ... and calls it for
# each element in the list
'-'/{~}% # slices the list by '-' and evals each element
# from string to int. ["1"] becomes [1],
# ["3-5"] becomes [3 5]
.,1- # adds the length of the list -1 on top of the stack
# so for [1] the stack becomes [1] 0, for [3 5]
# it becomes [3 5] 1
# next we add two function blocks, they, like the 0/1 just before
# are used by an if clause a tiny bit later. First block is for
# lists that have a 1 on top of them, the latter for ones with 0.
# First block, we have something like [3 5]
))+ # pops the top element of the array, increments
# it and puts back. [3 6]
## It seems {...}%~ is same as {...}/
## this is why these two are not in the code any more
{,}% # , makes a list from 0 to n-1, where n is the parameter
# so we get [[0 1 2] [0 1 2 3 4 5]]
~ # Dumps the outer array, [0 1 2] [0 1 2 3 4 5]
\ # swaps the two arrays
- # set complement [3 4 5]
~ # dumps the array, so the elements are left in the stack
# Second block, we have something like [16]
~ # just dumps the array, 16
# Blocks end
if # takes the top three elements of the stack, evaluates the
# first (0 or 1), runs second if true (anything but
# [], "", 0 or {} ), otherwise the third.
","* # joins an array with ","

edit 1: changed the last {}%~ to {}/, also my description was likely wrong.

+1, because anyone doing a program in GolfScript has earned it.
–
GarethOct 3 '12 at 21:37

@Gareth Thanks. I first thought I'd just do it the perl way: change - to .. and evaluate it. Then I couldn't find any sane way to build any arrays so I did this. I'm sure someone will come around with a ~20 char solution with golfscript.
–
shionaOct 3 '12 at 22:20

I have 24 at the moment, so I'll take 20 as a challenge ;) You can save a few quite easily, though. The problem asks for a program, not a function, so you can lose the initial { and the final }:r; and you can also save one by replacing 1- with (. (Incidentally, IIRC that's one trick I also missed in my first GolfScript program)
–
Peter TaylorOct 3 '12 at 22:32

PS There is a subtle difference between {...}%~ and {...}/. If you're accessing something further down the stack using integer $ then the first one is simpler, because you don't have to adjust the integer each time to compensate for whatever you're leaving on the stack.
–
Peter TaylorOct 3 '12 at 22:34