-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathsolve.rb
executable file
·136 lines (122 loc) · 2.82 KB
/
solve.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#! /bin/sh
exec ruby -w -x "${0}" "${@}"
# BENCH_INVOKE_CMD:./solve.rb dict.txt
# BENCH_VERSION_CMD:ruby --version | awk '{print $2}'
#!ruby
require "set"
class DictionaryNode
def initialize
@finished = false
@next = {}
end
def add_suffix( suffix_ )
if ( suffix_.length == 0 )
@finished = true
else
char = suffix_[0]
if ( ! @next.key?( char ) )
@next[char] = DictionaryNode.new
end
@next[char].add_suffix( suffix_[1..-1] )
end
end
def get( char_ )
return ( @next.fetch( char_, nil ) )
end
def print_all( prefix_ = "" )
if ( @finished )
puts( prefix_ )
end
@next.each_key do | char |
@next[char].print_all( prefix_ + char )
end
end
attr_reader :finished
end
class Cube
def initialize( letter_ )
@letter = letter_
@visited = false
@neighbors = []
end
attr_accessor :letter
attr_accessor :neighbors
attr_accessor :visited
end
class Board
def initialize( letters_ )
len = Math.sqrt( letters_.length ).round
if ( len * len != letters_.length )
raise "Bad board definition"
end
@size = len
@cubes = []
letters_.split( "" ).each do | l |
@cubes.push( Cube.new( l ) )
end
deltas = [[-1,-1], [-1,0], [-1,1], [0,-1], [0,1], [1,-1], [1,0], [1,1]]
( 0 .. len - 1 ).each do | x |
( 0 .. len - 1 ).each do | y |
deltas.each do | d |
nx = x + d[0]
ny = y + d[1]
if ( ( nx >= 0 ) && ( nx < len ) && ( ny >= 0 ) && ( ny < len ) )
get_cube( x, y ).neighbors.push( get_cube( nx, ny ) )
end
end
end
end
end
def get_cube( x_, y_ )
return ( @cubes[y_ * @size + x_] )
end
def solve( dictionary_ )
result = Set.new
@cubes.each do | cube |
solve_recursive( result, "", cube, dictionary_ )
end
return ( result.to_a.sort { | a, b | a.length <=> b.length } )
end
def solve_recursive( result, prefix_, cube_, dictNode_ )
nextNode = dictNode_.get( cube_.letter )
if ( nextNode == nil )
return
end
cube_.visited = true
newPrefix = prefix_ + cube_.letter
if ( nextNode.finished && ( newPrefix.length >= 3 ) )
result.add( newPrefix )
end
cube_.neighbors.each do | neighbor |
if ( ! neighbor.visited )
solve_recursive( result, newPrefix, neighbor, nextNode )
end
end
cube_.visited = false
end
end
def main( argv_ )
dictionaryRoot = DictionaryNode.new
File.open( argv_[1] ).each do | line |
dictionaryRoot.add_suffix( line.strip() )
end
# dictionaryRoot.print_all
puts( "[ OK ] Ready" )
letters = ""
while ( ( line = STDIN.gets() ) != nil )
line = line.strip()
if ( ( letters.length > 0 ) && ( line.length == 0 ) )
puts( "[ OK ] Solving" )
board = Board.new( letters )
board.solve( dictionaryRoot ).each do | word |
puts( "(" + word.length.to_s + ") " + word )
end
puts( "[ OK ] Solved" )
letters = ""
else
letters += line
end
end
end
main( [$0] + ARGV )
# vim: set ft=ruby: