There's a perl module called Set::IntSpan which already does this (it was originally written in 1996 to collapse lists of article numbers for .newsrc files, which could be enormous).
There is also a similar module for python called intspan, but I haven't used it.
Anyway, with perl and Set::IntSpan (and tr to get the input data into comma-separated format, and tr again to munge the output), this is trivial.
$ tr $'\n' ',' < input.txt |
perl -MSet::IntSpan -lne 'print Set::IntSpan->new($_)' |
tr ',-' $'\n,'
2,3
9,12
24
28,29
33
Set::IntSpan is packaged for debian and ubuntu as libset-intspan-perl, for fedora as perl-Set-IntSpan, and probably for other distros too. Also available on CPAN, of course.