wordgrid 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/wordgrid.rb +110 -0
- metadata +45 -0
data/lib/wordgrid.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'matrix'
|
2
|
+
|
3
|
+
class Matrix
|
4
|
+
def find_cells_for_letter(letter)
|
5
|
+
cells = []
|
6
|
+
each_with_index do |e, row, column|
|
7
|
+
if (e == letter)
|
8
|
+
cell = [row, column]
|
9
|
+
cells.push(cell)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
return cells
|
13
|
+
end
|
14
|
+
|
15
|
+
# why doesn't matrix natively support this?!?
|
16
|
+
def neighbor_cells(root_cell)
|
17
|
+
row = root_cell[0]
|
18
|
+
column = root_cell[1]
|
19
|
+
cells = []
|
20
|
+
|
21
|
+
cells.push([row-1, column-1]) if row-1 >= 0 and column-1 >= 0 #NW
|
22
|
+
cells.push([row-1, column]) if row-1 >= 0 #N
|
23
|
+
cells.push([row-1, column+1]) if row-1 >= 0 and column+1 < column_size #NE
|
24
|
+
cells.push([row, column-1]) if column-1 >=0 #W
|
25
|
+
cells.push([row, column+1]) if column+1 < column_size #E
|
26
|
+
cells.push([row+1, column-1]) if row+1 < row_size and column-1 >= 0 #SW
|
27
|
+
cells.push([row+1, column]) if row+1 < row_size #S
|
28
|
+
cells.push([row+1, column+1]) if row+1 < row_size and column+1 < column_size #SE
|
29
|
+
|
30
|
+
return cells
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Wordgrid
|
35
|
+
|
36
|
+
def initialize(initial_grid=Matrix[])
|
37
|
+
self.grid = initial_grid
|
38
|
+
@cell_stack = []
|
39
|
+
end
|
40
|
+
|
41
|
+
attr_reader :grid
|
42
|
+
|
43
|
+
def grid=(new_grid)
|
44
|
+
# make sure each cell is a single letter character
|
45
|
+
bad_cell = new_grid.find_index{|cell| cell.match(/^[^A-Za-z]$/) }
|
46
|
+
if bad_cell
|
47
|
+
raise ArgumentError "Bad cell at " + bad_cell.to_s
|
48
|
+
end
|
49
|
+
|
50
|
+
unless new_grid.square?
|
51
|
+
raise ArgumentError "grid must be a square." # do I really care about this?
|
52
|
+
end
|
53
|
+
|
54
|
+
@grid = new_grid
|
55
|
+
end
|
56
|
+
|
57
|
+
def has_word?(word)
|
58
|
+
@letters = word.split('')
|
59
|
+
first_cells = @grid.find_cells_for_letter(@letters[0])
|
60
|
+
|
61
|
+
@cell_stack = []
|
62
|
+
first_cells.each do |cell|
|
63
|
+
@cell_stack.push(cell)
|
64
|
+
if find_next_letter_in_neighborhood() == true
|
65
|
+
return true
|
66
|
+
end
|
67
|
+
@cell_stack = []
|
68
|
+
end
|
69
|
+
return false
|
70
|
+
end
|
71
|
+
|
72
|
+
=begin
|
73
|
+
1. start with a cell
|
74
|
+
2. look at all the neighbors of the cell for the next letter.
|
75
|
+
if we don't find it, move back up to try a different path (if there were other matches a cell up)
|
76
|
+
if we do find it
|
77
|
+
if we're at the end of the string, stop, and return true
|
78
|
+
if we aren't at the end of the string, goto 2 for the cell we found
|
79
|
+
|
80
|
+
along the way, build a stack of the path. So for the following grid:
|
81
|
+
A B C
|
82
|
+
D E F
|
83
|
+
G H I
|
84
|
+
a final stack for "BEAD" should be: [0,1], [1,1], [0,0], [1,0]
|
85
|
+
|
86
|
+
=end
|
87
|
+
def find_next_letter_in_neighborhood
|
88
|
+
if (@cell_stack.size == @letters.size)
|
89
|
+
return true
|
90
|
+
end
|
91
|
+
neighbors = @grid.neighbor_cells(@cell_stack[-1])
|
92
|
+
current_letter = @letters[@cell_stack.size]
|
93
|
+
neighbors.each do |neighbor|
|
94
|
+
# don't retraverse nodes on the path we've taken thus far.
|
95
|
+
if @cell_stack.find { |cell| cell == neighbor }
|
96
|
+
next
|
97
|
+
end
|
98
|
+
|
99
|
+
neighbor_letter = @grid.element(neighbor[0], neighbor[1])
|
100
|
+
if neighbor_letter == current_letter
|
101
|
+
@cell_stack.push(neighbor)
|
102
|
+
if find_next_letter_in_neighborhood == true
|
103
|
+
return true
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
@cell_stack.pop
|
108
|
+
return false
|
109
|
+
end
|
110
|
+
end
|
metadata
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wordgrid
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jonathan Hansen
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-02 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Visualizing and solving games like boggle, scramble with friends, etc
|
15
|
+
email: jonathansen@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/wordgrid.rb
|
21
|
+
homepage: https://github.com/jonathansen/wordgrid
|
22
|
+
licenses: []
|
23
|
+
post_install_message:
|
24
|
+
rdoc_options: []
|
25
|
+
require_paths:
|
26
|
+
- lib
|
27
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ! '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
requirements: []
|
40
|
+
rubyforge_project:
|
41
|
+
rubygems_version: 1.8.22
|
42
|
+
signing_key:
|
43
|
+
specification_version: 3
|
44
|
+
summary: Wordgrid
|
45
|
+
test_files: []
|