|
|
|
#1 |
|
Messages: n/a
Hébergeur: |
Hi,
I'm trying to convert an array like [2,3,3,5,4,4] in [2,[3,3,[[5],4,4]]], but I really can't figure how to this. Is there any way to achieve this in Ruby? Thanks in advance. -- Posted via http://www.ruby-forum.com/. |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
Chris Morales wrote:
> Hi, > > I'm trying to convert an array like [2,3,3,5,4,4] in > [2,[3,3,[[5],4,4]]], but I really can't figure how to this. > Is there any way to achieve this in Ruby? > > Thanks in advance. I once asked a question about multidimensional arrays and I received a solution like this irb(main):001:0> array = [] => [] irb(main):002:0> new_array = [1,2,3] => [1, 2, 3] irb(main):003:0> array << new_array => [[1, 2, 3]] irb(main):004:0> array << 3 => [[1, 2, 3], 3] irb(main):005:0> array[0] << 5 => [1, 2, 3, 5] irb(main):006:0> array => [[1, 2, 3, 5], 3] irb(main):007:0> array[0] << [5] => [1, 2, 3, 5, [5]] irb(main):008:0> array => [[1, 2, 3, 5, [5]], 3] irb(main):009:0> I wish this s regards -- Posted via http://www.ruby-forum.com/. |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
Chris Morales wrote:
> Hi, > > I'm trying to convert an array like [2,3,3,5,4,4] in > [2,[3,3,[[5],4,4]]], but I really can't figure how to this. > Is there any way to achieve this in Ruby? I don't really get the question... do you want to do this automatically? If yes, how should the mapping look like (i.e. what decides that 3 is 1 level deep, 5 is 4 level deep etc.)? Cheers, Peter ___ http://www.rubyrailways.com http://scrubyt.org |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
> I don't really get the question... do you want to do this automatically?
> If yes, how should the mapping look like (i.e. what decides that 3 is 1 > level deep, 5 is 4 level deep etc.)? Sorry, my question was missing some important details. 1/ it's array of numbers only 2/ the first number is the base depth 3/ for every number increase a depth of array is added so [1,2,4,2] => [1,[2,[[4]],2]] and [5,5,6] => [5,5,[6]] 4/ and it would be wonderful if it were automatic, by extending the Array class if possible. The image is a kind of opposite of flatten. for now I'm trying with the insert/slice! couple, no cute at all & not really working class Array def depthen base_depth = self[0] range = [0,0] in_flag, out_flag = false, false self.each_index{ |i| if self[i]>base_depth && !in_flag in_flag = true; range[0] = i end if self[i] <= base_depth && !out_flag out_flag = true range[1] = i-1 end } self.insert(range[0], self.slice!(eval(range.join('..'))) ) end end p [2,3,3,5,4,4].depthen => [2,[3,3,5,4,4]] I hope I'm on the good way, but the code is *really* ugly Thank you in advance, Chris. -- Posted via http://www.ruby-forum.com/. |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
Okay, I made it kinda works, clunky and ugly though...
class Array def max max = 0; self.each{ |i| max = i>max ? i : max } max end def min min = 9999; self.each{ |i| min = i<min ? i : min } min end def depthen base_depth = self.min range = [0,0] in_flag, out_flag = false, false self.each_index{ |i| if self[i]>base_depth && !in_flag in_flag = true; range[0] = i end if self[i] <= base_depth && !out_flag out_flag = true range[1] = i-1 end } to_insert = self.slice!(eval(range.join('..'))) to_insert.depthen if to_insert.max>to_insert.min self.insert( range[0], to_insert ) end end p [2,3,3,5,4,4].depthen => [2,[3,3,[[5],4,4]]] I will be really thankful if anybody could me improve this monster with nice ruby tricks. Thank you in advance, Chris. -- Posted via http://www.ruby-forum.com/. |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
On Nov 22, 2007 10:28 AM, Chris Morales <primo.tertio@gmail.com> wrote:
> Okay, I made it kinda works, clunky and ugly though... > > > class Array > def max > max = 0; > self.each{ |i| max = i>max ? i : max } > max > end > def min > min = 9999; > self.each{ |i| min = i<min ? i : min } > min > end > def depthen > base_depth = self.min > range = [0,0] > in_flag, out_flag = false, false > self.each_index{ |i| > if self[i]>base_depth && !in_flag > in_flag = true; > range[0] = i > end > if self[i] <= base_depth && !out_flag > out_flag = true > range[1] = i-1 > end > } > to_insert = self.slice!(eval(range.join('..'))) > to_insert.depthen if to_insert.max>to_insert.min > self.insert( range[0], to_insert ) > end > end > > p [2,3,3,5,4,4].depthen => [2,[3,3,[[5],4,4]]] > > I will be really thankful if anybody could me improve this monster > with nice ruby tricks. With your code: [2,3,5,3].depthen # => [2, [3, [[5], 3]]] Shouldn't this be: [2, [3, [[5]], 3]] ? I'm trying to think of an elegant solution, but I'm kind of slow today... Jesus. |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
On Nov 22, 2007 3:03 PM, Jes=FAs Gabriel y Gal=E1n <jgabrielygalan@gmail.co=
m> wrote: > On Nov 22, 2007 10:28 AM, Chris Morales <primo.tertio@gmail.com> wrote: > > p [2,3,3,5,4,4].depthen =3D> [2,[3,3,[[5],4,4]]] > > > > I will be really thankful if anybody could me improve this monster > > with nice ruby tricks. > > > With your code: > > [2,3,5,3].depthen # =3D> [2, [3, [[5], 3]]] > > Shouldn't this be: > > [2, [3, [[5]], 3]] > > ? > > I'm trying to think of an elegant solution, but I'm kind of slow today... I managed to get some time at work and this is my first try, I use a stack to maintain the arrays for each level when you are going upwards, so you can add to the same array when you go downwards (makes any sense?): class Array def depthen depth =3D self[0] result =3D [] stack =3D [] current =3D result each do |x| case depth <=3D> x when 0 current << x when -1 diff =3D x - depth value =3D [x] tmp =3D value (diff - 1).times do value =3D [value] stack.push value end current << value current =3D tmp stack.push current when 1 diff =3D depth - x + 1 diff.times {current =3D stack.pop} current =3D result if current.nil? current << x end depth =3D x end result end end a =3D [[2,3,3,4,5,4,4], [2,3,5,3, 2]] a.each {|x| p x.depthen} [2, [3, 3, [4, [5], 4, 4]]] [2, [3, [[5]], 3], 2] Have fun, Jesus. |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
Others, including Chris Morales, have interpreted the task as follows:
> p [2,3,3,5,4,4].depthen => [2,[3,3,[[5],4,4]]] But that doesn't seem right to me, since the element 2 is at a depth of 1 and not 2. I would think the result should be: [[2,[3,3,[[5],4,4]]]] Anyway, here's a solution which handles my interpretation: class Array def depthen result = [] self.each do |depth| array_end = result (depth - 1).times do array_end << [] unless array_end.last.kind_of? Array array_end = array_end.last end array_end << depth end result end end And here's what it does: p [2, 3, 3, 5, 4, 1, 4, 6, 10, 2].depthen # => [[2, [3, 3, [[5], 4]]], 1, [[[4, [[6, [[[[10]]]]]]]], 2]] To change it to the other interpretation, just change "depth - 1" to "depth - 2". And then, presumably, the array depthen is called on shouldn't have any "1"s in it (although even they're handled "gracefully" with the depthen method provided). Eric ==== Are you interested in on-site Ruby training that uses well-designed, real-world, hands-on exercises? http://LearnRuby.com |
|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
Eric I. wrote:
> Others, including Chris Morales, have interpreted the task as follows: > > p [2,3,3,5,4,4].depthen => [2,[3,3,[[5],4,4]]] > > But that doesn't seem right to me, since the element 2 is at a depth > of 1 and not 2. quoth Chris Morales: >>>> the first number is the base depth -- NP: Moonsorrow - 1065: Aika Jabber: sepp2k@jabber.org ICQ: 205544826 |
|
|
|
#10 |
|
Messages: n/a
Hébergeur: |
On Nov 22, 1:39 pm, Sebastian Hungerecker <sep...@googlemail.com>
wrote: > quoth Chris Morales: > > >>>> the first number is the base depth Thank you, Sebastian! I lost track of that. OK, here we go, then: class Array def depthen base_depth = first result = [] each do |depth| array_end = result (depth - base_depth).times do array_end << [] unless array_end.last.kind_of? Array array_end = array_end.last end array_end << depth end result end end Eric ==== Interested in hands-on, on-site Ruby training? See http://LearnRuby.com for information about a well-reviewed class. |
|
|
|
#11 |
|
Messages: n/a
Hébergeur: |
On Nov 22, 2007 7:39 PM, Sebastian Hungerecker <sepp2k@googlemail.com> wrote:
> Eric I. wrote: > > Others, including Chris Morales, have interpreted the task as follows: > > > p [2,3,3,5,4,4].depthen => [2,[3,3,[[5],4,4]]] > > > > But that doesn't seem right to me, since the element 2 is at a depth > > of 1 and not 2. > > quoth Chris Morales: > > >>>> the first number is the base depth Yes, that's what I based my solution on. Afterwards I saw in his solution that he used the min of the array which makes more sense... Jesus. |
|
|
|
#12 |
|
Messages: n/a
Hébergeur: |
> I will be really thankful if anybody could me improve this monster
> with nice ruby tricks. My first impression is that the code should probably achieve its goals in some other way than it's currently attempting. Trying something this intricate often means setting yourself up for failure. It might be possible to use trees or something similar instead, depending on the nature of the problem you've decided to solve. -- Giles Bowkett Podcast: http://hollywoodgrit.blogspot.com Blog: http://gilesbowkett.blogspot.com Portfolio: http://www.gilesgoatboy.org Tumblelog: http://giles.tumblr.com |
|
|
|
#13 |
|
Messages: n/a
Hébergeur: |
Wow!
Thanks everybody & Thank you so much Eric > class Array > def depthen > base_depth = first > result = [] > > each do |depth| > array_end = result > (depth - base_depth).times do > array_end << [] unless array_end.last.kind_of? Array > array_end = array_end.last > end > array_end << depth > end > > result > end > end I couldn't have dreamt a shorter way to achieve this, You really are a Genius. So short and nice! This must be what they call the ruby way I think ![]() Chris. -- Posted via http://www.ruby-forum.com/. |
|
![]() |
| Outils de la discussion | |
|
|