[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: [QUIZ][SOLUTION] Crosswords (#10

Jamis Buck

12/5/2004 2:22:00 PM

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 = string.split( $/ ).map { |l| l.gsub(/\s/,"") }
@properties = Hash.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 >= columns ) || ( y >= rows )
@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] ] = value
end
end

class Formatter
def initialize( definition )
@definition = definition
end

CELL_WIDTH = 5
CELL_HEIGHT = 3

NUMBER_TOKEN = "%-3s"

FILLED_CELL = [ "#####", "#####", "#####" ]
EMPTY_CELL = [ "#####", "##{NUMBER_TOKEN} ", "# " ]
BLANK_CELL = [ "`^^^^", "< ", "< " ]

WALL = "#"
SPACE = " "

def format( output=STDOUT )
number = 1
@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 = cell[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 = number.to_s
number += 1
end
elsif !@definition[col,row]
if has_exit_path( col, row )
line = BLANK_CELL[row_y]
clear_left = has_exit_path( col-1, row )
clear_up = has_exit_path( col, row-1 )
clear_corner = has_exit_path( col-1, row-1 )
up_char = clear_up ? SPACE : WALL
left_char = clear_left ? SPACE : WALL
corner_char = clear_corner && clear_left && clear_up ?
SPACE : WALL
line = line.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 = Hash.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] ] = true

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 = found || ( col < @definition.columns-1 &&
!@definition[col+1,row] && find_exit_path_recurse( col+1, row ) )

found = found || ( row > 0 && !@definition[col,row-1] &&
find_exit_path_recurse( col, row-1 ) )

found = found || ( 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=STDOUT )
definition = Definition.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...
2 Answers

James Gray

12/8/2004 6:58:00 PM

0

On Dec 5, 2004, at 8:21 AM, Jamis Buck wrote:

> I've also attached a sample input file. :)

This is a wonderful test file.

Did you try your program with it? It doesn't quite get it right,
though it's very close. ;)

James Edward Gray II



James Gray

12/8/2004 7:03:00 PM

0

On Dec 8, 2004, at 12:57 PM, James Edward Gray II wrote:

> On Dec 5, 2004, at 8:21 AM, Jamis Buck wrote:
>
>> I've also attached a sample input file. :)
>
> This is a wonderful test file.
>
> Did you try your program with it? It doesn't quite get it right,
> though it's very close. ;)

My mistake. It does get it 100% right. I read the layout wrong.

James Edward Gray II