[QUIZ] crossword.rb (#10)

The three rules of Ruby Quiz:

1. Please do not post any solutions or spoiler discussion for this quiz until
48 hours have passed from the time on this message.

2. Support Ruby Quiz by submitting ideas as often as you can:

http://www.grayproductions.net/ruby_quiz/

3. Enjoy!

···

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

#!/usr/bin/env ruby

class Square
  @@count = 1
  
  def initialize( holds_letter = false )
    @holds_letter = holds_letter
    @edge = false
  end
  
  attr_reader :holds_letter
  attr_accessor :edge
  
  def render( row, top, left, right, bottom )
    if @holds_letter
      number = ""
      if (top.nil? or not top.holds_letter) and
         (bottom and bottom.holds_letter)
        number = @@count.to_s
        @@count += 1
      elsif (left.nil? or not left.holds_letter) and
          (right and right.holds_letter)
        number = @@count.to_s
        @@count += 1
      end
      
      if top.nil? and left.nil?
        row[0] << "######"
        row[1] << sprintf("#%-4s#", number)
        row[2] << "# #"
        row[3] << "######"
      elsif top.nil?
        row[0] << "#####"
        row[1] << sprintf("%-4s#", number)
        row[2] << " #"
        row[3] << "#####"
      elsif left.nil?
        row[1] << sprintf("#%-4s#", number)
        row[2] << "# #"
        row[3] << "######"
      else
        row[1] << sprintf("%-4s#", number)
        row[2] << " #"
        row[3] << "#####"
      end
    else
      if @edge
        if top.nil? and left.nil?
          row[0] << " "
          row[1] << " "
          row[2] << " "
          row[3] << " "
        elsif top.nil?
          row[0] << " "
          row[1] << " "
          row[2] << " "
          row[3] << " "
        elsif left.nil?
          row[1] << " "
          row[2] << " "
          row[3] << " "
        else
          row[1] << " "
          row[2] << " "
          row[3] << " "
        end
        if right and not right.edge
          row.each { |e| e.sub!(/ $/, "#") }
        end
        if left and not left.edge
          row.each { |e| e.sub!(/ (.{5})$/, '#\1') }
        end
        if top and not top.edge
          row[0].sub!(/ +(#?)$/) do |m|
            "#" * (m.length - $1.length) + $1
          end
        end
        if bottom and not bottom.edge
          row[3].sub!(/ +(#?)$/) do |m|
            "#" * (m.length - $1.length) + $1
          end
        end
      else
        if top.nil? and left.nil?
          row[0] << "######"
          row[1] << "######"
          row[2] << "######"
          row[3] << "######"
        elsif top.nil?
          row[0] << "#####"
          row[1] << "#####"
          row[2] << "#####"
          row[3] << "#####"
        elsif left.nil?
          row[1] << "######"
          row[2] << "######"
          row[3] << "######"
        else
          row[1] << "#####"
          row[2] << "#####"
          row[3] << "#####"
        end
      end
    end
  end
end

board = [ ]
while line = ARGF.gets
  board << [ ]
  line.chomp.delete(" ").each_byte do |c|
    if c == ?X
      board[-1] << Square.new
    else
      board[-1] << Square.new(true)
    end
  end
end

loop do
  changed = false
  board.each_with_index do |row, y|
    row.each_with_index do |cell, x|
      next if cell.holds_letter or cell.edge
      
      if x == 0 or y == 0 or x == board[0].size - 1 or y == board.size - 1
        cell.edge = true
        changed = true
        next
      end
      
      top = board[y - 1][x]
      left = board[y][x - 1]
      right = board[y][x + 1]
      bottom = board[y + 1][x]
      if (top and top.edge) or (left and left.edge) or
         (right and right.edge) or (bottom and bottom.edge)
        cell.edge = true
        changed = true
      end
    end
  end
  break if not changed
end

board.each_with_index do |row, y|
  drawn_row = ["", "", "", ""]
  row.each_with_index do |cell, x|
    top = y == 0 ? nil : board[y - 1][x]
    left = x == 0 ? nil : board[y][x - 1]
    right = x == board[0].size - 1 ? nil : board[y][x + 1]
    bottom = y == board.size - 1 ? nil : board[y + 1][x]
    
    cell.render drawn_row, top, left, right, bottom
  end
  drawn_row.each { |e| puts e if e.length > 0 }
end

Wow, I'm full of mistakes this week, aren't I?! Egad! I promise to get more sleep very soon. Actual quiz coming up very soon now...

Sorry everyone.

James Edward Gray II

···

On Dec 3, 2004, at 7:50 AM, Ruby Quiz wrote:

The three rules of Ruby Quiz:

1. Please do not post any solutions or spoiler discussion for this quiz until
48 hours have passed from the time on this message.

2. Support Ruby Quiz by submitting ideas as often as you can:

Gray Soft / Not Found

3. Enjoy!

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Is the question in this quiz "Figure out what the quiz is about?"

I don't want to ask "wtf" if answers would be spoilers :slight_smile:

···

On Dec 3, 2004, at 6:50 AM, Ruby Quiz wrote:

The three rules of Ruby Quiz:

1. Please do not post any solutions or spoiler discussion for this quiz until
48 hours have passed from the time on this message.