Hi all,
I’ve been thinking about this for a while but cant figure out an
efficient (or any actually) way to do the following:
a line contains a list of coordinates (specifying a range) separated by
a “,” like so:
50586…50639,50795…51859,60005…60058,60256…61236
Pulling out the separate coordinates via split is of course rather
simple. But, here’s the catch…
I not only need the given ranges, but also the stretches in between (I
am pulling the coordinates out of a large text file, so there is no good
way to manipulate the source). So the whole range is in reality
everything between the first and the last number…However, I have to
treat the originally given ranges and the stretches in between
differently. The given ranges are printed in upcase, the parts not
specified in downcase. Now, a way this could look like would be:
E50586…50639,50640…50795,E50795…51859,…
The “E” at the beginning is then used to identify the original ranges
and as a condition for printing in upcase.
So, my point being…I have absolutely no clue how to do this. The
procedure would have to split the given ranges but also immediately
write the missing ranges in the correct order.
If anyone has an idea how to approach this, I could really need some
advice here.
Cheers,
Marc
edit: by up- and downcase I am referring to the way I want to puts the
result, not the format of the source…there it is all downcase, so no
way to use that to distinguish anything
Hi –
On Fri, 20 Jul 2007, Marc H. wrote:
Pulling out the separate coordinates via split is of course rather
The “E” at the beginning is then used to identify the original ranges
and as a condition for printing in upcase.
So, my point being…I have absolutely no clue how to do this. The
procedure would have to split the given ranges but also immediately
write the missing ranges in the correct order.
If anyone has an idea how to approach this, I could really need some
advice here.
I’m not sure if this is an exact fit but see if it helps. This is
based on the first string (no E characters, etc.):
ranges = str.scan(/(\d+)…(\d+)/).map {|a,b| a.to_i…b.to_i }
betweens = str.scan(/(\d+),(\d+)/).map {|a,b| (a.to_i+1)…b.to_i-1 }
David
Marc H. wrote:
ranges = str.scan(/(\d+)…(\d+)/).map {|a,b| a.to_i…b.to_i }
betweens = str.scan(/(\d+),(\d+)/).map {|a,b| (a.to_i+1)…b.to_i-1 }
David
Took me a bit, but got it working - perfect, thanks a lot!
an alternate way which might be clearer would
a = 50586…50639,50795…51859,60005…60058,60256…61236
b = []
0.upto(a.size - 2) do |i|
c = a[i].last + 1
d = a[i+1].first - 1
b << (c…d)
end
p a =>
[50586…50639, 50795…51859, 60005…60058, 60256…61236]
p b =>
[50640…50794, 51860…60004, 60059…60255]
ranges = str.scan(/(\d+)…(\d+)/).map {|a,b| a.to_i…b.to_i }
betweens = str.scan(/(\d+),(\d+)/).map {|a,b| (a.to_i+1)…b.to_i-1 }
David
Took me a bit, but got it working - perfect, thanks a lot!
Marc H. wrote:
a line contains a list of coordinates (specifying a range) separated by
a “,” like so:
50586…50639,50795…51859,60005…60058,60256…61236
Now, a way this could look like would be:
E50586…50639,50640…50795,E50795…51859,…
I see that the problem is already solved, but in Ruby I always have the
feeling, that there must be something like a “one-liner” for nearly all
problems.
Unfortunately I ended only with “something” like a one-liner.
code >>>>>
intxts = [ “50586…50639,50795…51859,60005…60058,60256…61236”,
“0…10,50000…50100,50101…51000,60005…60058,60059…61236” ]
def put(a);(a = a.push(a.shift))[0];end
intxts.each do |intxt|
pre = [’’, ‘E’]
p intxt.split(’,’).collect{|e|e.split(’…’).collect{|v|Integer(v)}}.
inject([[],0]){|c,e|
c[1]==0 ? (c[0]<<e;c[1]=e[1]+1) : (
c[1]==e[0] ? (c[0]<<[0,0]<<e) : (c[0]<<[c[1],e[0]-1]<<e)
c[1]=e[1]+1);c
}.at(0).collect{|r|put(pre)+r.join(’…’)}.join(’,’).gsub(/0…0,/,’’)
end
result >>>>>
“E50586…50639,50640…50794,E50795…51859,51860…60004,E60005…60058,60059…60255,E60256…61236”
“E0…10,11…49999,E50000…50100,E50101…51000,51001…60004,E60005…60058,E60059…61236”
end of example >>>>>
Sorry, but it is a Ruby generated addiction…
Wolfgang Nádasi-Donner
Wolfgang Nádasi-donner wrote:
def put(a);(a = a.push(a.shift))[0];end
:oops: - overhead…
def put(a);a.push(a.shift)[0];end