Line.split with some complicating factors

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