The challenge
The program must return all numbers included into a group (comma and hyphen separated sequence) of numbers.
Rules
sis the sequence string;- all numbers included in
sare positive; - numbers will always increase;
- numbers will never repeat
- when you answer, show the output for
s="1,3-5,9,16,18-23"
Examples
input(s) outputs
-----------------
1 1
1,2 1,2
1-4 1,2,3,4
1-4,6 1,2,3,4,6
1-4,8-11 1,2,3,4,8,9,10,11
Good luck. =)
31 Answers 31
Perl (削除) 25 (削除ここまで) (削除) 26 (削除ここまで) 25
$_ is the sequence string
s/-/../g;$_=join",",eval
Sample session:
[~/] $ perl -M5.010 -pe 's/-/../g;$_=join",",eval' <<< "1,3-5,9,16,18-23"
1,3,4,5,9,16,18,19,20,21,22,23
Added 1 character to the character count for the (削除) -n (削除ここまで)-p option (thanks Gareth, ..kinda).
-
\$\begingroup\$ I've probably done the character counting wrong (with the command line options). Feel free to correct my counting, please \$\endgroup\$ardnew– ardnew2012年10月03日 18:57:58 +00:00Commented Oct 3, 2012 at 18:57
-
\$\begingroup\$ Going by the answer to this question on meta, you only need to add 1 character for the
noption. \$\endgroup\$Gareth– Gareth2012年10月03日 19:03:08 +00:00Commented Oct 3, 2012 at 19:03 -
\$\begingroup\$ Remove
-M5.010and exchange-efor-E\$\endgroup\$Brad Gilbert b2gills– Brad Gilbert b2gills2015年11月28日 19:31:12 +00:00Commented Nov 28, 2015 at 19:31
GolfScript (24 chars)
','/{~.,!{~)),>~}*}%','*
E.g.
$ golfscript.rb expand.gs <<<"1,3-5,9,16,18-23"
1,3,4,5,9,16,18,19,20,21,22,23
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
-
\$\begingroup\$ How can you expand 3-5 into 3,4,5 without using a single the character
-? \$\endgroup\$user5403– user54032012年10月04日 20:20:32 +00:00Commented Oct 4, 2012 at 20:20 -
\$\begingroup\$ @BernaMariano, sorry, I somehow missed your question. I'll expand the answer with a detailed explanation. \$\endgroup\$Peter Taylor– Peter Taylor2012年11月09日 21:53:07 +00:00Commented Nov 9, 2012 at 21:53
golfscript, (削除) 46 (削除ここまで) 45
My first ever golf script program, took hours to complete.
{','/{'-'/{~}%.,1-{))+{,}/\-~}{~}if}%","*}:r;
# call:
"1,3-5,9,16,18-23"r
# return:
1,3,4,5,9,16,18,19,20,21,22,23
You can try it at http://golfscript.apphb.com/
My best throw at explaining this atrocity:
{...}: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.
-
2\$\begingroup\$ +1, because anyone doing a program in GolfScript has earned it. \$\endgroup\$Gareth– Gareth2012年10月03日 21:37:10 +00:00Commented Oct 3, 2012 at 21:37
-
\$\begingroup\$ @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. \$\endgroup\$shiona– shiona2012年10月03日 22:20:44 +00:00Commented Oct 3, 2012 at 22:20
-
\$\begingroup\$ 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 replacing1-with(. (Incidentally, IIRC that's one trick I also missed in my first GolfScript program) \$\endgroup\$Peter Taylor– Peter Taylor2012年10月03日 22:32:54 +00:00Commented Oct 3, 2012 at 22:32 -
\$\begingroup\$ PS There is a subtle difference between
{...}%~and{...}/. If you're accessing something further down the stack usinginteger $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. \$\endgroup\$Peter Taylor– Peter Taylor2012年10月03日 22:34:34 +00:00Commented Oct 3, 2012 at 22:34
R, 44 bytes
`-`=seq;eval(parse(t=c("c(",scan(,""),")")))
Redefine - to mean seq (i.e. :), surround the input with c() and evaluate the corresponding expression.
Jelly, 9 bytes
)-ryṣ",VF
y Replace
)-r hyphens with the letter r,
ṣ", split on commas,
V evaluate every element,
F and flatten.
The range dyad r takes two arguments on either side of it and produces an inclusive range between them.
Wolfram Language (Mathematica), 57 bytes
{Plus=##&@@#~Range~-#2&}~Block~ToExpression["{"<>#<>"}"]&
"{"<>#<>"}" wrap in {}
{Plus=##&@@#~Range~-#2&}~Block~ interpret - as spliced range:
ToExpression[ ] parse
K, 47
","/:,/${x+!1+y-x}.'2#'a,'a:"I"$'"-"\:'","\:0:0
Test case
k)","/:,/${x+!1+y-x}.'2#'a,'a:"I"$'"-"\:'","\:0:0
1,3-5,9,16,18-23
"1,3,4,5,9,16,18,19,20,21,22,23"
-
\$\begingroup\$
","/:,ドル/{{x+!1+y-x}. 2#"J"$"-"\:x}'","\:0:0for 43 bytes \$\endgroup\$mkst– mkst2019年07月19日 21:45:27 +00:00Commented Jul 19, 2019 at 21:45
05AB1E, 10 bytes
',¡ε'-¡Ÿ} ̃
Input as a string; output as a list of integers.
Try it online or verify all test cases.
Explanation:
',¡ '# Split the (implicit) input-string on ","
ε # Map over each substring:
'-¡ '# Split the substring on "-"
Ÿ # Convert the pair to a list in that range
# (if it's a singleton, it'll remain as is)
} ̃ # After the map: flatten the list of lists
# (after which the result is output implicitly)
Retina, 32 bytes
\d+
*
vr`(?<!1円)-(_+)
,1ドル
_+
$.0
Don't really feel good about this, but after spinning my wheels on it on and off basically all morning I'd feel even worse not posting...
Explanation:
\d+
*
Convert each run of digits to unary with underscores as the digit.
vr`(?<!1円)-(_+)
,1ドル
Take overlapping RtL matches of a hyphen and a run of underscores (possibly non-maximal--overlapping RtL tries matching leftwards from each position, such that e.g. vr`.+ matches every prefix), provided that the hyphen is NOT directly preceded by that many or more underscores (not part of the match), and substitute the underscores after a comma. Overlapping matches are weird and I'm not entirely sure how to describe the behavior here, but the way I understand it is more or less anything that none of them match is a "separator" and the match substitutions and separators just get smushed back together in the order of their starting positions.
_+
$.0
Convert each run of underscores to its length in decimal.
-
\$\begingroup\$ On further inspection of the docs (i.e. actually reading them instead of skimming), the way separators are determined with overlapping matches is a little different (it's possible for something to be part of both a match and a separator so long as the match isn't one of the pair of matches it separates), but there's no difference to this program because the matches form a poset w.r.t. substring-ness. \$\endgroup\$Unrelated String– Unrelated String2024年12月23日 14:34:31 +00:00Commented Dec 23, 2024 at 14:34
Perl (37)
$_=<>;s/^/say join',',/;s/-/../g;eval
-
\$\begingroup\$ - when you answer, show the output for
s="1,3-5,9,16,18-23", thanks \$\endgroup\$user5403– user54032012年10月03日 17:40:22 +00:00Commented Oct 3, 2012 at 17:40 -
\$\begingroup\$ How about
say join",",eval<>=~s/-/../grat 29 bytes \$\endgroup\$Brad Gilbert b2gills– Brad Gilbert b2gills2015年11月28日 19:15:35 +00:00Commented Nov 28, 2015 at 19:15
J, (削除) 53 (削除ここまで) (削除) 43 (削除ここまで) (削除) 41 (削除ここまで) (削除) 39 (削除ここまで) 38 characters
;(}.[:i.1+])/&.>".'- ,;'charsub 1!:1[1
Takes input from the keyboard:
;(}.[:i.1+])/&.>".'- ,;'charsub 1!:1[1
1-4,8-11
1 2 3 4 8 9 10 11
Output for the requested test case:
;(}.[:i.1+])/&.>".'- ,;'charsub 1!:1[1
1,3-5,9,16,18-23
1 3 4 5 9 16 18 19 20 21 22 23
Hassium, 173 Bytes
This was pretty long and might not be competing since there is a trailing , at the end.
func main(){p="1,2,3,5-8".split(",")for(c=0;c<p.length;c++){e=p[c]if(e.contains("-")){p=e.split("-")for(x=p[0].toInt();x<=p[1].toInt()print(x++ +",")){}}else print(e+",")}}
Run online and see expanded here
Python 2.7, (削除) 147 (削除ここまで) 138 Bytes
z,f=input().split(','),[]
for i in z:
x=i.split('-')
if len(x)>1:f+=range(int(x[0]),int(x[1])+1)
else:f+=[int(x[0])]
print str(f)[1:-1]
Usage:
>>>python nums.py "1,3-5,9,16,18-23" 1, 3, 4, 5, 9, 16, 18, 19, 20, 21, 22, 23
Not the best program...
-
1\$\begingroup\$ Welcome to PPCG. I think you can make your answer shorter by using 1 space for indents. \$\endgroup\$intrepidcoder– intrepidcoder2015年11月26日 02:42:03 +00:00Commented Nov 26, 2015 at 2:42
-
\$\begingroup\$ Thanks @intrepidcoder, I didn't know that you could use single space indents. \$\endgroup\$Alex– Alex2015年11月27日 01:26:16 +00:00Commented Nov 27, 2015 at 1:26
PowerShell, (削除) 79 (削除ここまで) 71 bytes
('('+($args[0]-replace'-','..'-replace',','),(')+')'|iex|%{$_})-join','
The inner part changes "1,5-9,12" into a "(1),(5..9),(12)" format that PowerShell understands, then executes that with iex, which creates an array of arrays. Then iterate through each inner array, then finally join all outer array elements together
Borrows code from my "Help Me Manage My Time" answer
Usage
PS C:\Tools\Scripts\golfing> .\return-each-number-from-a-group-of-numbers.ps1 '1,3-5,9,16,18-23'
1,3,4,5,9,16,18,19,20,21,22,23
-8 bytes thanks to Veskah
-
\$\begingroup\$ You're doing redundant joins, 71 bytes \$\endgroup\$Veskah– Veskah2019年06月24日 19:24:23 +00:00Commented Jun 24, 2019 at 19:24
K (oK), (削除) 40 (削除ここまで) 31 bytes
Solution
,/{{x+!1+y-x}. 2#.:'"-"\x}'","\
Explanation:
Managed more golfing whilst adding the explanation...
,/{{x+!1+y-x}. 2#.:'"-"\x}'","\ / the solution
","\ / split input on ","
{ }' / apply lambda to each
"-"\x / split x on "-"
.:' / value (.:) each (')
2# / 2 take (dupe if only 1 element)
{ }. / diadic lambda, 2 args x and y
y-x / y subtract x
1+ / add 1
! / range 0..n
x+ / add x
,/ / flatten
Wolfram Language (Mathematica), 108 bytes
Flatten[If[StringContainsQ[#,"-"],Range@@ToExpression@StringSplit[#,"-"],FromDigits@#]&/@StringSplit[s,","]]
Pyth, 17 bytes
.nm.U}bZvcd\-cz,円
Explanation:
.nm.U}bZvcd\-cz,円
cz,円 => split on commas
m => map
vcd\- => split on hypens and parse each
.U => reduce
}bZ => [A, A+1, ..., B]
.n => flatten list
Kotlin, 105 bytes
{it.split(",").joinToString(","){it.split("-").run{(first().toInt()..last().toInt()).joinToString(",")}}}
val f:(String)->String= is the header. Just splits the string with the , delimiter, and for every element it can only be 1 or 2 elements after it's split by -
After that, it creates the range of numbers, using first() and last() allows it to work whether it has one or two elements, and then just joins the characters again with , and joined again by , after all ranges are processed
Red, 150 bytes
func[s][replace/all s","" "replace/all s"-"" - "b: make bitset! t: to[]load s
u: copy""repeat n v: last t[if b/:n[append u n if n < v[append u","]]]u]
The input is very close to the way Red constructs bitset!datatype - the difference is that the numbers must be separated by spaces and not commas, and the hyphen also must be enclosed in spaces - for example [1 - 4 6]. When this is done we can simply make bitset! from the loaded block. Then we need to iterate over the range from 1 to the last numebr and check if the current value is set in our bitset!. The last thing is to format the output - a siginficant part of the program is dealing with joining the values with commas :)
Zsh +sed, 64 bytes
eval echo `sed -E 's/,/ /g;s/([0-9]+)-([0-9]+)/{1円..2円}/g'<<<1ドル`
sed -E converts string 1,3-5,9,16,18-23 into 1 {3..5} 9 16 {18..23} so that Zsh can apply brace expansion.
MATLAB, 47 bytes
disp(eval(['[',strrep(input(''),'-',':'),']']))
This snippet reads a string input from the command window, replaces '-' by ':', adds square brackets to the string and then evaluates it, so that the input will be expanded to a full array of numbers.
Example input:
'1,3-5,9,16,18-23'
Example output:
1 3 4 5 9 16 18 19 20 21 22 23
I believe this output is allowed, as the challenge only say that all numbers in a group should be displayed.
-
\$\begingroup\$ comma-separated output would be nicer, though i can se a 5-spaces-separated pattern, thats cool for me :) \$\endgroup\$user5403– user54032015年11月27日 14:05:30 +00:00Commented Nov 27, 2015 at 14:05
Clojure, 110 bytes
#(clojure.string/join","(for[s(.split %",")[a b][(map read-string(.split s"-"))]r(if b(range a(inc b))[a])]r))
Dealing with strings isn't much fun :(
-
\$\begingroup\$ Can you replace
c@with£? \$\endgroup\$Oliver– Oliver2019年07月19日 20:07:43 +00:00Commented Jul 19, 2019 at 20:07 -
\$\begingroup\$ @Oliver, as it's an old challenge that doesn't specify its I/O format, I erred on the side of caution, taking input as a comma delimited string and outputting as a flattened array. Normally, though, yes, I'd have specified input as an array of strings, output as a multi-dimensional array and just used
£in place of the first 5 bytes. \$\endgroup\$Shaggy– Shaggy2019年07月19日 20:49:09 +00:00Commented Jul 19, 2019 at 20:49
Python 2, 90 bytes
lambda s:sum((range(u[0],u[-1]+1)for u in[map(int,t.split('-'))for t in s.split(',')]),[])
Lua (126 bytes)
Just for fun:
(("1,3-5,9,16,18-23"):gsub("(%d+)-(%d+)",function(a,b)t={}for i=a,b do t[#t+1]=math.ceil(i)end return table.concat(t,",")end))
4-9,1-2or1-3,9-6? \$\endgroup\$