# There has got to be a better way

**URL:** <https://www.ruby-forum.com/t/there-has-got-to-be-a-better-way/99798>\
**Category:** Ruby\
**Created:** [July 25, 2006, 5:06pm UTC](https://www.ruby-forum.com/t/there-has-got-to-be-a-better-way/99798 "2006-07-25T17:06:18Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![michaelb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b19c9b/32.png) [@michaelb](https://www.ruby-forum.com/u/michaelb)\
**Post date:** [July 25, 2006, 5:06pm UTC](https://www.ruby-forum.com/t/there-has-got-to-be-a-better-way/99798/1 "2006-07-25T17:06:18Z")

</div>

i’m looking to simplify the below…

@tournament.rounds = Array.new(4) { Round.new }

@tournament.rounds[0].matches = Array.new(8) { Match.new }  
@tournament.rounds[1].matches = Array.new(4) { Match.new }  
@tournament.rounds[2].matches = Array.new(2) { Match.new }  
@tournament.rounds[3].matches = Array.new(1) { Match.new }

thoughts/suggestions?

---

<div class="post-metadata">

**Author:** ![michaelb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b19c9b/32.png) [@michaelb](https://www.ruby-forum.com/u/michaelb)\
**Post date:** [July 25, 2006, 5:22pm UTC](https://www.ruby-forum.com/t/there-has-got-to-be-a-better-way/99798/2 "2006-07-25T17:22:01Z")

</div>

@tournament.rounds = Array.new(4) { Round.new }

@tournaments.rounds.inject(8) do |size, round|  
round.matches = Array.new(size) { Match.new }  
size / 2  
end

Something like that?

---

<div class="post-metadata">

**Author:** ![michaelb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b19c9b/32.png) [@michaelb](https://www.ruby-forum.com/u/michaelb)\
**Post date:** [July 25, 2006, 5:25pm UTC](https://www.ruby-forum.com/t/there-has-got-to-be-a-better-way/99798/3 "2006-07-25T17:25:33Z")

</div>

On 7/26/06, Michael B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> thoughts/suggestions?
> 
> –  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

a = [8,4,2,1]  
@tournament.rounds = 0.upto(3).inject([]) { |round, index|  
Round.new.matches=  
Array.new( a[index] ) {Match.new} }

I think that should provide the same thing that you have.

---

<div class="post-metadata">

**Author:** ![michaelb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b19c9b/32.png) [@michaelb](https://www.ruby-forum.com/u/michaelb)\
**Post date:** [July 25, 2006, 5:32pm UTC](https://www.ruby-forum.com/t/there-has-got-to-be-a-better-way/99798/4 "2006-07-25T17:32:16Z")

</div>

How about:  
@t.rounds = Array.new(4) { Round.new }  
@t.rounds.each\_index do |i|  
@t.rounds[@t.rounds.length - 1 - i] = Array.new(1 \<\< i) {  
Match.new }  
end  
?

---

<div class="post-metadata">

**Author:** ![michaelb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b19c9b/32.png) [@michaelb](https://www.ruby-forum.com/u/michaelb)\
**Post date:** [July 25, 2006, 5:35pm UTC](https://www.ruby-forum.com/t/there-has-got-to-be-a-better-way/99798/5 "2006-07-25T17:35:49Z")

</div>

On 25/07/06, Michael B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> i’m looking to simplify the below…
> 
> @tournament.rounds = Array.new(4) { Round.new }

@tournament.rounds.each\_with\_index do |round,roundNumber|  
round.matches = Array.new(2\*\*(@tournamet.rounds.length - 1 -  
roundNumber)) {Match.new}  
end

---

<div class="post-metadata">

**Author:** ![michaelb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b19c9b/32.png) [@michaelb](https://www.ruby-forum.com/u/michaelb)\
**Post date:** [July 25, 2006, 5:42pm UTC](https://www.ruby-forum.com/t/there-has-got-to-be-a-better-way/99798/6 "2006-07-25T17:42:26Z")

</div>

On Wed, 26 Jul 2006, Michael B. wrote:

> –  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

this may work for your needs

```
 harp:~ > cat a.rb
 class Match
   def initialize(idx) @idx = idx end
   def inspect() "#{ self.class } <#{ @idx }>" end
 end

 class Round < ::Array
   def self.new(*a,&b) super(*a){|*_| Match.new *_ } end
 end

 class Tournament < ::Array
 end

 def Match(*a,&b) Match.new(*a,&b); end
 def Round(*a,&b) Round.new(*a,&b); end
 def Tournament(*a,&b) Tournament.new(*a,&b); end

 tournament = Tournament[Round(8), Round(4), Round(2), Round(1)]

 p tournament[0]
 p tournament[1]
 p tournament[2]
 p tournament[3]

 p tournament[0][7]
 p tournament[3][0]

 harp:~ > ruby a.rb
 [Match <0>, Match <1>, Match <2>, Match <3>, Match <4>, Match <5>, 

```

Match \<6\>, Match \<7\>]  
[Match \<0\>, Match \<1\>, Match \<2\>, Match \<3\>]  
[Match \<0\>, Match \<1\>]  
[Match \<0\>]  
Match \<7\>  
Match \<0\>

regards.

-a

---

<div class="post-metadata">

**Author:** ![michaelb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b19c9b/32.png) [@michaelb](https://www.ruby-forum.com/u/michaelb)\
**Post date:** [July 25, 2006, 10:52pm UTC](https://www.ruby-forum.com/t/there-has-got-to-be-a-better-way/99798/7 "2006-07-25T22:52:02Z")

</div>

A small variant on answers already posted – use reverse! to avoid  
index twiddling.

Regards, Morton

--------------- start of code  
! /usr/bin/ruby -w

class M  
attr\_accessor :ii  
# \*\*\*\* support for pretty printing  
def to\_s  
“M.#@ii”  
end  
end

class R  
attr\_accessor :mm, :ii  
# \*\*\*\* support for pretty printing  
def to\_s  
s = (mm.collect {|m| m.to\_s}).join(", ")  
“[R#@ii: #{s}]”  
end  
end

class T  
def initialize  
# \*\*\*\* start of answer  
@rr = Array.new(4) {R.new}  
@rr.each\_with\_index {|r, i| r.mm = Array.new(1 \<\< i) {M.new}}  
@rr.reverse!  
# \*\*\*\* end of answer  
# \*\*\*\* support for pretty printing  
tag = 1  
@rr.each\_with\_index do |r, i|  
r.ii = i + 1  
r.mm.each do |m|  
m.ii = tag  
tag += 1  
end  
end  
end  
# \*\*\*\* support for pretty printing  
def to\_s  
s = (@rr.collect {|r| r.to\_s}).join(", ")  
“[T: #{s}]”  
end  
end

t = T.new  
puts t =\> [T: [R1: M.1, M.2, M.3, M.4, M.5, M.6, M.7, M.8],   
[R2: M.9, M.10, M.11, M.12], [R3: M.13, M.14],   
[R4: M.15]]

--------------- end of code

---

<div class="post-metadata">

**Author:** ![michaelb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b19c9b/32.png) [@michaelb](https://www.ruby-forum.com/u/michaelb)\
**Post date:** [July 26, 2006, 8:23am UTC](https://www.ruby-forum.com/t/there-has-got-to-be-a-better-way/99798/8 "2006-07-26T08:23:50Z")

</div>

On Jul 25, 2006, at 8:06, Michael B. wrote:

> i’m looking to simplify the below…
> 
> @tournament.rounds = Array.new(4) { Round.new }
> 
> @tournament.rounds[0].matches = Array.new(8) { Match.new }  
> @tournament.rounds[1].matches = Array.new(4) { Match.new }  
> @tournament.rounds[2].matches = Array.new(2) { Match.new }  
> @tournament.rounds[3].matches = Array.new(1) { Match.new }
> 
> thoughts/suggestions?

I’m not a big proponent of trying to do everything in one line, because  
it often results in code that’s hard to figure out when you go back to  
look at it later. So I was a little surprised when this turned into one  
line of active code. 🙂

class Match  
def initialize  
# put whatever’s needed here, of course  
end  
end

class Tournament  
attr\_reader :rounds  
def initialize(num\_of\_rounds)  
@rounds = (1…num\_of\_rounds).collect do |round\_number|  
Array.new(2\*\*(num\_of\_rounds-round\_number)) {|i| Match.new}  
end  
end  
end

@tournament = Tournament.new(4)

@tournament.rounds.each\_with\_index {|round, round\_num| puts "Number of  
matches in round " + (round\_num + 1).to\_s + " is " + round.size.to\_s}

Number of matches in round 1 is 8  
Number of matches in round 2 is 4  
Number of matches in round 3 is 2  
Number of matches in round 4 is 1
