--J2SCkAp4GZ/dPZZf
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
I originally thought I would have my solution work in two passes--the first,
effectively building a formatted string, and the second emitting the string
to the chosen stream. I decided to try and do it in one pass, though,
building the layout and emitting the string in a single pass.
I used two classes: Definition, which was just the encapsulation of the
input, and Formatter, which performed the layout formatting.
I've also attached a sample input file. :)
##########################################################################
# Jamis Buck's solution to Ruby-Quiz #10:
##########################################################################
module Layout
class Definition
def initialize( string )
@lines tring.split( $/ ).map { |l| l.gsub(/\s/,"") }
@properties ash.new
end
def rows
@lines.length
end
def columns
@lines.first.length
end
def []( x, y )
return false if ( x < 0 ) || ( y < 0 )
return false if ( x > olumns ) || ( y > ows )
@lines[y][x] ?_
end
def property( x, y, name )
@properties[ [x,y,name] ]
end
def set_property( x, y, name, value )
@properties[ [x,y,name] ] alue
end
end
class Formatter
def initialize( definition )
@definition efinition
end
CELL_WIDTH
CELL_HEIGHT
NUMBER_TOKEN %-3s"
FILLED_CELL "#####", "#####", "#####" ]
EMPTY_CELL "#####", "##{NUMBER_TOKEN} ", "# " ]
BLANK_CELL "`^^^^", "< ", "< " ]
WALL #"
SPACE "
def format( output DOUT )
number
@definition.rows.times do |row|
CELL_HEIGHT.times do |row_y|
@definition.columns.times do |col|
cell definition[col,row] ? EMPTY_CELL : FILLED_CELL
line ell[row_y]
number_str "
if cell[row_y].include?(NUMBER_TOKEN) && @definition[col,row]
if ( !@definition[col-1,row] && @definition[col+1,row] ) ||
( !@definition[col,row-1] && @definition[col,row+1] )
# begin
number_str umber.to_s
number +
end
elsif !@definition[col,row]
if has_exit_path( col, row )
line LANK_CELL[row_y]
clear_left as_exit_path( col-1, row )
clear_up as_exit_path( col, row-1 )
clear_corner as_exit_path( col-1, row-1 )
up_char lear_up ? SPACE : WALL
left_char lear_left ? SPACE : WALL
corner_char lear_corner && clear_left && clear_up ?
SPACE : WALL
line ine.tr( "`^<", "#{corner_char}#{up_char}#{left_char}" )
else
@definition.set_property( col, row, :exit_path, false )
end
end
output << line % number_str
end
puts( @definition[@definition.columns-1,row-1] &&
row_y 0 || @definition[@definition.columns-1,row] ?
WALL : SPACE )
end
end
@definition.columns.times do |col|
if !@definition[col,@definition.rows-1]
if col 0 || col > 0 && !@definition[col-1,@definition.rows-1]
print SPACE
else
print WALL
end
print SPACE*4
else
print WALL*5
end
end
if @definition[@definition.columns-1,@definition.rows-1]
print WALL
end
puts
end
def has_exit_path( col, row )
@visited ash.new
find_exit_path_recurse( col, row )
end
private :has_exit_path
def find_exit_path_recurse( col, row )
return false if @definition[col,row]
return false if @visited[ [col,row] ]
@visited[ [col,row] ] rue
return true if @definition.property( col, row, :exit_path )
return false if @definition.property( col, row, :exit_path ) false
if col 0 || col @definition.columns-1 ||
row 0 || row @definition.rows-1
#begin
@definition.set_property( col, row, :exit_path, true )
return true
end
found col > 0 && !@definition[col-1,row] &&
find_exit_path_recurse( col-1, row ) )
found ound || ( col < @definition.columns-1 &&
!@definition[col+1,row] && find_exit_path_recurse( col+1, row ) )
found ound || ( row > 0 && !@definition[col,row-1] &&
find_exit_path_recurse( col, row-1 ) )
found ound || ( row < @definition.rows-1 && !@definition[col,row+1] &&
find_exit_path_recurse( col, row+1 ) )
if found
@definition.set_property( col, row, :exit_path, true )
return true
end
return false
end
private :find_exit_path_recurse
end
def format( file, output DOUT )
definition efinition.new( File.read( file ) )
Formatter.new( definition ).format( output )
end
module_function :format
end
Layout.format( ARGV.first, STDOUT ) if __FILE__ $0
--
Jamis Buck
jgb3 / email.byu.edu
http://www.jamisbuck.org/jamis
--J2SCkAp4GZ/dPZZf
Content-Type: text/plain; charset=us-ascii
Content-Description: A sample crossword layout
Content-Disposition: attachment; filename="ruby-quiz.layout"
_ _ _ _ X _ X _ X _ _ _ _ _ _ _ X _
_ X X _ X _ X _ X _ X X X _ X _ X _
_ X X _ X _ X _ X _ X X X _ X _ X _
_ _ _ X X _ X _ X _ _ _ _ X X _ _ _
_ X _ _ X _ X _ X _ X X X _ X X _ X
_ X X _ X _ X _ X _ X X X _ X X _ X
_ X X _ _ _ _ _ _ _ _ _ _ _ X X _ X
_ X X X X X X X X X X X X X X X X X
_ _ _ _ X _ X _ X _ _ _ _ _ _ _ _ _
_ X X _ X _ X _ X X X _ X X X X X _
_ X X _ X _ X _ X X X _ X X X X _ _
_ X X _ X _ X _ X X X _ X X X X _ X
_ X X _ X _ X _ X X X _ X X X _ _ X
_ X _ _ X _ X _ X X X _ X X X _ X X
_ _ _ _ _ _ _ _ _ _ _ _ _ X _ _ _ _
--J2SCkAp4GZ/dPZZf--