From: Bob Showalter Date: 2007-01-02T22:21:40+09:00 Subject: Re: [QUIZ] Word Search (#107) Here's my submission. No extra credits. # RubyQuiz Word Search (107) # Bob Showalter class WordSearch class Board < Array def to_s collect {|s| s.split(//).join(' ')}.join("\n") end end attr_reader :board, :solution # creates a new, empty solver def initialize @board = Board.new @solution = Board.new end # resets the solution def reset @solution.clear @board.each {|row| @solution << row.gsub(/./, '+')} end # checks that the board contains only letters and that it has a uniform # rectangular shape def validate @board.size > 0 or raise "Board has no rows" @board.grep(/[^A-Z]/).empty? or raise "Board contains non-letters" w = @board.collect {|row| row.size}.uniq w.size == 1 or raise "Board rows are not all the same length" w.first > 0 or raise "Board has no columns" end # parses the board by reading lines from io until a blank line (or EOF) # is read. def parse(io = ARGV) @board.clear while line = io.gets line = line.strip.upcase break if line == '' @board << line end validate reset end # search for word. returns number of times found. solution is updated with # all occurences. def search(word) found = 0 0.upto(board.size-1) do |y| 0.upto(board[y].size-1) do |x| [-1, 0, 1].each do |dy| [-1, 0, 1].each do |dx| next if dx == 0 and dy == 0 found += 1 if search_for(word.strip.upcase, x, y, dx, dy) end end end end found end # search for word in board starting at position (x,y) and moving in direction # (dx,dy). returns true if found, false if not found. def search_for(word, x, y, dx, dy) return false if x < 0 or x >= board.first.size or y < 0 or y >= board.size return false if board[y][x] != word[0] prev = solution[y][x] solution[y][x] = board[y][x] return true if word.length <= 1 found = search_for(word[1,word.length-1], x + dx, y + dy, dx, dy) solution[y][x] = prev unless found found end # creates a new puzzle by parsing the board from io. see WordSearch#parse def self.parse(io = ARGF) obj = new obj.parse(io) obj end def to_s solution.to_s end end # parse the board first p = WordSearch.parse # parse the words until a blank line is read words = [] while line = ARGF.gets line = line.strip.upcase break if line == '' words += line.gsub(',', ' ').split end # submit each word and show how many times it was found for word in words.sort.uniq n = p.search(word) puts word + ' was ' + (n == 0 ? 'not found' : n == 1 ? 'found once' : "found #{n} times") end # show the solution puts p