On Mon, Sep 20, 2010 at 7:10 PM, F. Senault <fred / lacave.net> wrote:
> Hello everybody.
>
> I've written a method to solve a little problem, but I find my solution
> really ugly. =A0So, I'm trying to find ways to improve it.
>
> The method takes one argument, an array containing a sorted list of
> strings representing episodes numbers. =A0The episodes numbers are either
> a number ('1', '12') or prefixed with a letter ('S1' for special 1). =A0M=
y
> goal is to find sequences in the numbers and join them with dashes :
>
>>> RAniDBTools.format_episodes_list([ '1', '2', '3', '4', '6', '7', '9', '=
S1', 'S2' ])
> =3D> "1-4, 6-7, 9, S1-S2"
>>> RAniDBTools.format_episodes_list([ '1', '2', 'S3', 'S4', 'S5', 'O6' ])
> =3D> "1-2, S3-S5, O6"
>
> Here's the code ; what can I do to improve this ?
>
> module RAniDBTools
> =A0def RAniDBTools.format_episodes_list(list)
> =A0 =A0lt =3D []
> =A0 =A0le =3D []
> =A0 =A0list.each do |epno|
> =A0 =A0 =A0if ('0'..'9').include? epno[0,1]
> =A0 =A0 =A0 =A0t =3D ''
> =A0 =A0 =A0 =A0e =3D epno.to_i
> =A0 =A0 =A0else
> =A0 =A0 =A0 =A0t =3D epno[0..0]
> =A0 =A0 =A0 =A0e =3D epno[1..-1].to_i
> =A0 =A0 =A0end
> =A0 =A0 =A0if lt.last =3D=3D t
> =A0 =A0 =A0 =A0max =3D le.last.max rescue le.last
> =A0 =A0 =A0 =A0min =3D le.last.min rescue le.last
> =A0 =A0 =A0 =A0if e =3D=3D max + 1
> =A0 =A0 =A0 =A0 =A0le[-1] =3D (min..e)
> =A0 =A0 =A0 =A0else
> =A0 =A0 =A0 =A0 =A0le << e
> =A0 =A0 =A0 =A0 =A0lt << t
> =A0 =A0 =A0 =A0end
> =A0 =A0 =A0else
> =A0 =A0 =A0 =A0le << e
> =A0 =A0 =A0 =A0lt << t
> =A0 =A0 =A0end
> =A0 =A0end
> =A0 =A0f =3D []
> =A0 =A0le.each_with_index do |e, i|
> =A0 =A0 =A0if e.is_a? Range
> =A0 =A0 =A0 =A0f << "#{lt[i]}#{e.min}-#{lt[i]}#{e.max}"
> =A0 =A0 =A0else
> =A0 =A0 =A0 =A0f << "#{lt[i]}#{e}"
> =A0 =A0 =A0end
> =A0 =A0end
> =A0 =A0f.join(', ')
> =A0end
> end

I have no time to propose a complete solution. I'll leave to you
adding the "Sx" and "Ox" processing. This is how I'd do it it they
were all numbers:

irb(main):004:0> list =3D [1,2,3,4,6,7,9,16,17]
=3D> [1, 2, 3, 4, 6, 7, 9, 16, 17]
irb(main):018:0> result =3D [[list.first]]
=3D> [[1]]
irb(main):023:0> list.each_cons(2) do |x,y|
irb(main):024:1* if (x+1) =3D=3D y
irb(main):025:2> result.last << y
irb(main):026:2> else
irb(main):027:2* result << [y]
irb(main):028:2> end
irb(main):029:1> end
=3D> nil
irb(main):030:0> result
=3D> [[1, 2, 3, 4], [6, 7], [9], [16, 17]]
irb(main):031:0> s =3D ""
=3D> ""
irb(main):034:0> res =3D result.map {|x| x.size =3D=3D 1 ? x.to_s :
"#{x.first}-#{x.last}"}
=3D> ["1-4", "6-7", "9", "16-17"]
irb(main):035:0> res.join(",")
=3D> "1-4,6-7,9,16-17"

For the other stuff, I would have a flag that tells me if I'm in the
middle of a number, "S" or "O" run, and act accordingly.

Hope this helps,

Jesus.