-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsudoku.rb
122 lines (96 loc) · 2.14 KB
/
sudoku.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
#!/usr/bin/ruby
# randori sudoku 2009-10-14 -- Reno.rb
#
# partial design notes from late-night whiteboard
#
# grids works now
class Matrix
attr_reader :grid_size
def initialize(matrix_width=9)
if matrix_width == 3
@grid_size = 3
else
@grid_size = Math.sqrt(matrix_width) # TODO: fail if not an even square
end
@matrix = Hash.new {|hash, key| hash[key] = Hash.new }
@cols = Hash.new {|h, k| h[k] = Array.new }
@rows = Hash.new {|h, k| h[k] = Array.new }
@grids = Hash.new do |h, k|
h[k] = Hash.new {|h2, k2| h2[k2] = Array.new }
end
end
# Creates or returns an existing Cell.
#
# ==== Params
# +x+ - Cell's index in the Matrix, 0 based
# +y+
# +val+ - Cell's value
#
def cell(x, y, val=nil)
if c = @matrix[x][y]
return c
end
c = Cell.new(x, y, @cols[x], @rows[y], @grids[x/grid_size][y/grid_size])
c.val = val unless val.nil?
@matrix[x][y] = c
c
end
def to_s
@grids.each_key do |k|
@grids[k].each_key do |k2|
puts "grid: #{k2}:#{k}"
print @grids[k2][k] # works by side-effect of being square...
print " "
end
print "\n"
end
end
end
class Cell #########################
attr_accessor :val
attr_reader :x, :y, :col, :row, :grid
def initialize(x, y, col, row, grid)
@x = x; @y = y
@col = col; @row = row; @grid = grid
@col << self
@row << self
@grid << self
end
def valid?
valid_in_row? and valid_in_col? and valid_in_grid?
end
def to_s
"{x:#{@x}; y:#{@y}; val:#{val}}"
end
private
def valid_in_row?
uniq_in?(row)
end
def valid_in_col?
uniq_in?(col)
end
def valid_in_grid?
uniq_in?(grid)
end
def self.uniq_in?(collection)
end
end
# when run interactively...
if $0 == __FILE__
require 'stringio'
require 'pp'
matrix = Matrix.new(3)
StringIO.new(<<-EOS
. 6 .
. 4 .
. 3 .
EOS
).readlines.each_with_index do |line, idx|
line.chars.to_a.delete_if {|d| d.strip.empty? }.compact.each_with_index do |char, idx2|
cell = matrix.cell(idx2, idx, char)
puts cell
end
end
puts "******** matrix:"
puts matrix
end