(Where it says attached, it will be attached in another email, the email 
  was too big)

Following is the version that makes a nice, configurable ASCII chart.
The chart is basically an object that stores a nested hash of [x][y]
values.  Instead of just outputting the data as a string, as above, this
version stores everything in Objects.  Tournament has rounds which have
matches which have teams.  The matching logic is very similar to the
above.  The options for the program can be accessed by running it with
no arguments (or --help or -h or -? or look below):
daniel@daniel-desktop:~$ ./tournie.rb
Usage: tournie.rb [options]

Use one of the following options to determine the teams:
       -n, --numerical TEAMS            TEAMS number of teams where 1 is
the best
                                        and TEAMS is the worst.
       -f, --from-csv FILE              CSV file FILE to get team data from.
                                        <rank>,<name>\n format

And any number of these to determine the output format(s):
       -c, --[no-]chart                 Display an ASCII based chart of
rounds
       -t, --[no-]text                  Display the rounds in a textual
format,
                                        for example:
                                        Round 1: 1 vs. 8, 4 vs. 5...

The following are completely optional:
(the short names correspond with positions on the num-pad)
       -8, --chart-height HEIGHT        Controls the vertical spacing on
the chart,
                                        with a higher HEIGHT meaning more
spacing.
                                        Defaults to 4, must be an integer
above 2.
       -4, --spacing-left SPACE         Controls the space to the left of
the team names.
                                        Defaults to 3, must be a positive,
non-negative integer.
       -6, --spacing-right SPACE        Controls the space to the right of
the team names.
                                        Defaults to 1, must be a positive,
non-negative integer.
       -5, --team-alignment ALIGNMENT   The alignment of team names on
their lines.
                                        Defaults to [l]eft, can be [r]ight
or [c]entered.
                                        Takes -6 but not -4 into account.
       -?, -h, --help                   Show this message

The quiz examples, as decided by this version (and some others):

daniel@daniel-desktop:~$ ./tournie.rb -n 6 -ct
Round 1: 1 vs. bye, 4 vs. 5, 2 vs. bye, 3 vs. 6.
Round 2: 1 vs. 4, 2 vs. 3.
Round 3: 1 vs. 2.
     1
    -----+
         |---+
    -----+   |  1
     bye     +----+
             |    |---+
     4       +----+   |
    -----+   |  4     |
         |---+        |
    -----+            |  1
     5                +----+
                      |    |---> 1
     2                +----+
    -----+            |  2
         |---+        |
    -----+   |  2     |
     bye     +----+   |
             |    |---+
     3       +----+
    -----+   |  3
         |---+
    -----+
     6


daniel@daniel-desktop:~$ ./tournie.rb -n 8 -ct
Round 1: 1 vs. 8, 4 vs. 5, 2 vs. 7, 3 vs. 6.
Round 2: 1 vs. 4, 2 vs. 3.
Round 3: 1 vs. 2.
     1
    ---+
       |---+
    ---+   |  1
     8     +----+
           |    |---+
     4     +----+   |
    ---+   |  4     |
       |---+        |
    ---+            |  1
     5              +----+
                    |    |---> 1
     2              +----+
    ---+            |  2
       |---+        |
    ---+   |  2     |
     7     +----+   |
           |    |---+
     3     +----+
    ---+   |  3
       |---+
    ---+
     6

daniel@daniel-desktop:~$ ./tournie.rb --from-csv tournie.csv --chart
--text --team-alignment c --spacing-right 5
Round 1: Red Devils vs. Underdogs, Metrostart vs. Giants, Mets vs. Jets,
Yankees vs. Red Sox.
Round 2: Red Devils vs. Metrostart, Mets vs. Yankees.
Round 3: Red Devils vs. Mets.
       Red Devils
    ----------------+
                    |---+
    ----------------+   |    Red Devils
        Underdogs       +-----------------+
                        |                 |---+
       Metrostart       +-----------------+   |
    ----------------+   |    Metrostart       |
                    |---+                     |
    ----------------+                         |    Red Devils
         Giants                               +-----------------+
                                              |                 |---> RD
          Mets                                +-----------------+(RD
change
    ----------------+                         |       Mets        d by me
                    |---+                     |                  b/c wrapp
    ----------------+   |       Mets          |                  ing)
          Jets          +-----------------+   |
                        |                 |---+
         Yankees        +-----------------+
    ----------------+   |      Yankees
                    |---+
    ----------------+
         Red Sox

Where tournie.csv had the following:
5,Metrostart
4,Yankees
8,Red Sox
7,Giants
2,Red Devils
9,Jets
3,Mets
56,Underdogs

Source of the program (I recommend viewing attachment because of wrapping):
#! /usr/bin/ruby
require 'enumerator'
require 'optparse'
require 'ostruct'

class String
	# Alias for String#center that fits into the ljust, rjust naming scheme.
	def cjust(*args)
		self.center(*args)
	end
	
	# align(:r, 5) --> rjust(5).  Alignment can be :r, :l, :c
	def align(alignment, *args)
		self.send((alignment.to_s + "just").to_sym, *args)
	end
end	

class Numeric
	# Is the given number a power of self?
	# 16.isPowerOf(2) == true
	# 100.isPowerOf(2) == false
	def isPowerOf(other)
		i = 0
		while (other ** i <= self)
			return true if other ** i == self
			i += 1
		end
		false
	end
	
	def average(other)
		(self + other) / 2
	end
end

# Rounds have matches which have a winning and loosing team.
class Match
	def initialize(*teams)
		@teams = teams.sort
		setLoser
	end
	
	# The loser is defined as the team with the lowest ranking before the
tournament.
	def setLoser
		@teams.last.eliminate
	end
	
	def winner
		@teams.find{|x| !x.eliminated?}
	end
	
	def loser
		@teams.find{|x| x.eliminated? }
	end
	
	# Return in the following format: <winner> vs. <looser>
	def to_s
		@teams.collect{|team| team.to_s}.join(" vs. ")
	end
	
	attr_reader :teams
end

# Tournaments have rounds, which have matches.
class Round
	@@totalRounds = 0
	
	def initialize()
		@matches = []
		@roundNum = @@totalRounds += 1
	end
	
	def addMatch(match)
		@matches.push(match)
	end

	# Prints the round in "Round x: <match>, <match>, etc." format.
	def to_s
		"Round #{@roundNum}: " + @matches.join(", ") + "."
	end
	
	# This changes the order of the matches so that in the next round, the
most extreme teams will face off.
	# Assumes that the matches were previously sorted by favorability (asc
or desc)
	def sort!
		sorted = []
		while @matches.length > 0
			sorted << @matches.shift << @matches.pop
		end
		@matches = sorted.compact
		self
	end
	
	attr_reader :roundNum, :matches
end

# Matches have teams which have info about themselves.
class Team
	@@favored = []
	@@currentRound = nil
	
	def initialize(name)
		@name = name
		@eliminated = false
		@rounds = []
		@@favored.push(self)
	end
	
	# Remove a team from future rounds if they lost.
	def eliminate
		@eliminated = true
		@@favored.delete(self)
		#@@notEliminated -= 1
	end
	
	# If a team has played in a certain round.
	def inRound?()
		@rounds.include? @@currentRound
	end
	
	# Add a round a team has played in
	def addPlayedRound()
		@rounds << @@currentRound
		self
	end
	
	def to_s
		@name
	end
	
	# Returns an array with teams not in the current round by favorability.
	def self.eligibleTeams()
		@@favored.select{|x| !x.inRound?}.sort
	end
	
	def <=>(other)
		@@favored.index(self) <=> @@favored.index(other)
	end
	
	def self.currentRound=(round)
		@@currentRound = round
	end
	
	attr_reader :name, :eliminated
	alias_method :"eliminated?", :eliminated
end

class Tournament
	# Recieves an aray of team names in order of ranking with the best first.
	def initialize(teams)
		@teams = teams.collect {|team| Team.new(team.to_s) }
		@rounds = []
	end
	
	def createNextRound
		currentRound = Round.new()
		Team.currentRound = currentRound
		
		# The top teams have a "bye" opponent if the number of teams isn't a
power of two.  Bye opponents always lose.
		until (Team.eligibleTeams.length.isPowerOf(2))
			currentRound.addMatch( Match.new(
				Team.eligibleTeams.first.addPlayedRound,
				Team.new("bye")
			) )
		end
		
		# Assign the rest of the teams to play their extreme opposites.
		while(Team.eligibleTeams.length > 1)
			currentRound.addMatch( Match.new(
				Team.eligibleTeams.last.addPlayedRound,
				Team.eligibleTeams.first.addPlayedRound
			) )
		end
		
		currentRound.sort! if currentRound.roundNum == 1
		@rounds.push(currentRound)
	end
	
	def createAllRounds
		until (@teams.find_all{|x| !x.eliminated?}.length == 1)
			createNextRound
		end
	end
	
	def to_s
		@rounds.join("\n")
	end
	
	def toASCIIChart(chartHeightModifier, spacingLeft, spacingRight, alignment)
		# Everything goes into this array in output[x][y] format, which is
then printed.  The origin is in the top left.
		output = ASCIICoordinatePlane.new
		
		# This stores the midpoints of the existing games outputted so that
the next round's matches will be aligned in between this round's matches.
		midpoints = Hash.new( Array.new )
		midpoints[1] = [chartHeightModifier]
		@rounds.first.matches.each {midpoints[1].unshift( midpoints[1].first -
(chartHeightModifier + 2) )}
		
		x = 2
		
		# Every round is one column.
		@rounds.each do |round|
			# The longest team name.
			columnWidth = round.matches.collect{|match|
match.teams}.flatten.collect{|team| team.name}.max{|a, b| a.length <=>
b.length}.length + spacingRight
			
			connectTheDots = []
			insertMidpoint = true
			
			# Every iteration makes 1 match appear.
			round.matches.reverse.each do |match|
				y = midpoints[round.roundNum].shift + 2
				
				# The first team's name.
				output.set(x, y, match.teams[0].name.to_s.align(alignment, columnWidth))
				
				# The line under that team's name.
				output.fill(x - spacingLeft, y -= 1, x + columnWidth, y, "-")
				output.set(x - spacingLeft, y, "+")
				output.fill(0, y, x - 1, y, " ") if round.roundNum == 1
				
				# The connector to the next round.
				output.set(x + columnWidth + 1, y -= 1, "-" * 3)
				
				# Deals with the midpoints.
				if insertMidpoint
					midpoints[round.roundNum + 1].push(y)
				else
					midpoints[round.roundNum + 1].push( midpoints[round.roundNum +
1].pop.average(y) )
				end
				insertMidpoint = !insertMidpoint
				
				# The line above the next team's name.
				output.fill(x - spacingLeft, y -= 1, x + columnWidth, y, "-")
				output.set(x - spacingLeft, y, "+")
				output.fill(0, y, x - 1, y, " ") if round.roundNum == 1
				
				# The next team's name.
				output.set(x, y -= 1, match.teams[1].name.to_s.align(alignment,
columnWidth))
				
				# The line on the right of the match going vertically.
				output.vertLine(x + columnWidth, y + 3, y+1)
				
				# To connect the match and the next match to each other.
				connectTheDots.push(y+2)
			end
			x += columnWidth + 4
			
			# Makes the lines vertically between matches.
			connectTheDots.each_slice(2) do |yvalues|
				starting = yvalues[0]
				if yvalues[1]
					ending = yvalues[1]
				else
					ending = starting
				end
				
				output.vertLine(x, starting, ending)
			end
			
			x += spacingLeft
		end
		
		# Print the winning team.
		output.set(x - spacingLeft, midpoints[@rounds.length].last, "> " +
@rounds.last.matches[0].winner.name)
		output
	end
	
	attr_reader :rounds
end

# Represents a coordinate plane with the origin in the top left.  Every
position can store a character.
class ASCIICoordinatePlane
	def initialize
		# Thank you Joel VanderWerf!
		@value = Hash.new {|h,k| h[k] = Hash.new {" "}}
		
		@maxx = 10
		@miny = -10
	end
	
	# Sets a specific character to a point, overflowing onto points to the
right if neccessary.
	def set(x, y, string)
		0.upto(string.length-1) do |index|
			@value[x][y] = string[index].chr	
			x += 1
		end
		
		@miny = y if y < @miny
		@maxx = x if x > @maxx
	end
	
	# Fill a horizontal line with a repeating character.
	def fillHorz(opts)
		set(opts[:startx], opts[:starty], opts[:string ] * (opts[:endx] -
opts[:startx]).abs)
	end
	
	# Fill a vertical line with a repeating character.
	def fillVert(opts)
		yvalues = [opts[:starty], opts[:endy]]
		y = yvalues.max
		
		until (y < yvalues.min)
			set(opts[:startx], y, opts[:string])
			y -= 1
		end
	end
	
	# Fills a straight, non-diagonal line with a repeating character
	def fill(startx, starty, endx, endy, string)
		if startx == endx
			fillVert({:startx => startx, :endx => endx, :starty => starty, :endy
=> endy, :string => string})
		else
			fillHorz({:startx => startx, :endx => endx, :starty => starty, :endy
=> endy, :string => string})
		end
	end
	
	# Creates a vertical line with +'s for the line endings.
	def vertLine(x, starty, endy)
		fill(x, starty, x, endy, "|")
		[starty, endy].each {|y| set(x, y, "+") }
	end
	
	# Outputs the coordinate plane to a string with spaces where no
character was entered.
	def to_s
		output = ""
		0.downto(@miny) do |y|
			0.upto(@maxx) do |x|
				output += @value[x][y]
			end
			output += "\n"
		end
		output
	end
end

class OptParser
	def self.parse(args)
		options = OpenStruct.new
		options.csv = nil
		options.numerical = nil
		options.league = nil
		options.chart = false
		options.chartheight = 4
		options.spacingleft = 3
		options.spacingright = 1
		options.alignment = :l
		options.textual = false
		
		# When called with no options, show the help.
		args = ["-?"] if args.empty?
		
		opts = OptionParser.new do |opts|
			opts.banner = "Usage: tournie.rb [options]"
			opts.separator ""
			opts.separator "Use one of the following options to determine the teams:"
			
			# From 1 to a numerical value.
			opts.on("-n", "--numerical TEAMS",
					"TEAMS number of teams where 1 is the best",
					"and TEAMS is the worst.") do |n|
						options.numerical = n
			end
			
			# From a CSV file
			opts.on("-f", "--from-csv FILE",
					"CSV file FILE to get team data from.",
					"<rank>,<name>\\n format") do |file|
						options.csv = file
			end
			
			opts.separator ""
			opts.separator "And any number of these to determine the output
format(s):"
			
			# Chart based representation
			opts.on("-c", "--[no-]chart",
					"Display an ASCII based chart of rounds") do |chartYesNoMaybeNaN|
						options.chart = chartYesNoMaybeNaN
			end
			
			# Textual representation
			opts.on("-t", "--[no-]text",
					"Display the rounds in a textual format,",
					"for example:",
					"Round 1: 1 vs. 8, 4 vs. 5...") do |text|
						options.textual = text
			end
			
			opts.separator ""
			opts.separator "The following are completely optional:"
			opts.separator "(the short names correspond with positions on the
num-pad)"
			
			# Chart height modifier
			opts.on("-8", "--chart-height HEIGHT",
					"Controls the vertical spacing on the chart,",
					"with a higher HEIGHT meaning more spacing.",
					"Defaults to 4, must be an integer above 2.") do |heigh|
						options.chartheight = heigh.to_i
			end
				
			# Spacing to the left of team names.
			opts.on("-4", "--spacing-left SPACE",
					"Controls the space to the left of the team names.",
					"Defaults to 3, must be a positive, non-negative integer.") do |s|
						options.spacingleft = s.to_i
			end
			
			# Spacing to the right of team names.
			opts.on("-6", "--spacing-right SPACE",
					"Controls the space to the right of the team names.",
					"Defaults to 1, must be a positive, non-negative integer.") do |s|
						options.spacingright = s.to_i
			end
			
			# Alignment of team names.
			opts.on("-5", "--team-alignment ALIGNMENT",
					"The alignment of team names on their lines.",
					"Defaults to [l]eft, can be [r]ight or [c]entered.",
					"Takes -6 but not -4 into account.") do |s|
						options.alignment = s.to_sym
			end
			
			opts.on("-?", "-h", "--help", "Show this message") do
				puts opts
				exit
			end
		end
		
		opts.parse!(args)
		options
	end
end

# Parse command line arguments
opts = OptParser.parse(ARGV)

# Create the tournament.
if (opts.numerical)
	tournie = Tournament.new((1..(opts.numerical.to_i)).to_a)
else
	teams = Hash.new
	orderedTeams = Array.new
	f = File.new(opts.csv)
	
	f.each_line do |line|
		line.chomp!
		line =~ /^([0-9]+), *(.*)$/
		teams[$1.to_i] = $2
	end
	
	teams.keys.sort.each do |rank|
		orderedTeams.push(teams[rank])
	end
	
	tournie = Tournament.new(orderedTeams)
end

# Do the logic
tournie.createAllRounds

# Display the tournament
puts tournie.to_s if opts.textual
puts tournie.toASCIIChart(opts.chartheight, opts.spacingleft,
opts.spacingright, opts.alignment).to_s if opts.chart