Well, unfortunately, I don't have time to generate the chart, but it
was easy enough to generate the pairings...  This could probably be
easily golfed, but I figured just leave it be.

The output is "stacked" array pairs... What I mean by that is that the
top array has two items: left and right. Each of those items is an
array of two items: left and right.... etc until you get down to the
leaves.  A pair like [1, 2] means "Team 1 vs Team 2", while a pair
like [6, nil] means "Team 6 gets a bye."


class Integer
   def ceilPow2
      n = self - 1
      i = 1
      until (n >> i).zero?
         n |= (n >> i)
         i *= 2
      end
      n += 1
   end

   def even?
      (self % 2).zero?
   end
end

class Array
   def fold
      raise ArgumentError unless size.even?
      h = size / 2
      self[0,h].zip(self[h,h].reverse)
   end
end

def matchup(n)
   raise ArgumentError unless n > 0

   byes = n.ceilPow2 - n
   mups = (1..n).to_a + [nil] * byes

   until mups.size == 1
      mups = mups.fold
   end

   mups[0]
end

def report(mups)
   # Here is where you could do tree output or similar... but I've no time.
   p mups
end

numTeams = (ARGV[0] || 23).to_i
if numTeams < 2
   puts "C'mon, that's not much of a competition..."
else
   matchUps = matchup(numTeams)
   report(matchUps)
end