From: James Edward Gray II Date: 2004-12-06T00:52:01+09:00 Subject: Re: [SOLUTION] Crosswords (#10) (was: [QUIZ] Crosswords (#10)) On Dec 5, 2004, at 8:07 AM, Markus Koenig wrote: > This is my solution. Here's mine... again. (Feel bad about the early spoiler. Sorry!) This code is far from pretty. It was one of those solutions that kept getting fixes piled on until it works. I probably should has rewritten it, but it does work. If you did this problem in 20 minutes, you're about 5 times smarter than me. James Edward Gray II #!/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