• API
• FAQ
• Tools
• Archive
A Pastebin account makes a great Christmas gift
SHARE
TWEET

# Untitled

a guest Mar 14th, 2018 52 Never
ENDING IN00days00hours00mins00secs

1. module Rudoku
2.   class Sudoku
4.
5.     def initialize
6.       @fields = Array.new(9 * 9) do |i|
7.         x = i % 9
8.         y = i / 9
9.         Field.new(x, y)
10.       end
11.     end
12.
13.     def [](*val) # 1-based
14.       if val.size == 2 # 2, 3
15.         x = val[0] - 1
16.         y = val[1] - 1
17.       elsif val.size == 1 # B3
18.         str = val[0].to_s
19.         x = str[0] - ?A
20.         y = str[1] - ?1
21.       else
22.         return nil
23.       end
24.
25.       @fields[x + y * 9]
26.     end
27.
28.     def []=(i, number) # also allows setting of multiple values: s[:B5] = [1, 2, 5]
29.       self[i].remove((1..9).to_a - number.to_a.flatten)
30.     end
31.
32.     def solved?
33.       @fields.all? { |f| f.solved? }
34.     end
35.
36.     def to_s
37.       row_strings = (1..9).collect { |i| row_to_s(i) }
38.       row_strings.join("\n-+-+-+-+-+-+-+-+-\n")
39.     end
40.
41.     def row(i) # 1-based
42.       @fields[(9 * (i - 1))..(9 * (i - 1) + 8)]
43.     end
44.
45.     def column(i) # 1-based
46.       @fields[(0..8).collect{ |j| 9 * j + i - 1}]
47.     end
48.
49.     def grid(i) # 1-based
50.       # TODO
51.     end
52.
53.     def row_to_s(i)
54.       (row(i).collect { |f| f.to_s }).join("|")
55.     end
56.
57.
58.     def each_row
59.       # TODO
60.     end
61.
62.     def each_column
63.       # TODO
64.     end
65.
66.     def each_grid
67.       # TODO
68.     end
69.
70.
71.     def apply_rule(rule)
72.       rule.apply_to(self)
73.     end
74.   end
75.
76.   class Field
78.
79.     def initialize(x,y)
80.       @possibilities = (1..9).to_a
81.       @x = x
82.       @y = y
83.     end
84.
85.     def remove(numbers)
86.       numbers = numbers.to_a.flatten # this works for a single number and for ranges, too
87.       new_possibilities = @possibilities - numbers
88.       @possibilities = new_possibilities if (new_possibilities.size >= 1) # fails silently!
89.     end
90.
91.     def position
92.       (?A + x).chr + (y + 1).to_s # 2, 3 => B3
93.     end
94.
95.     def solved?
96.       @possibilities.size == 1
97.     end
98.
99.     def to_s
100.       solved? ? @possibilities[0].to_s : " "
101.     end
102.   end
103.
104.   class Rule
106.
107.     def initialize(salience = 0, &block)
108.       @logic = block
109.       @salience = salience
110.     end
111.
112.     def apply_to(sudoku)
113.       args_iterate(@logic.arity - 1) do |*args|
114.         @logic.call(sudoku, *args)
115.       end
116.       # applies the rule to the sudoku.
117.       # iterates over all possible values for all parameters (thats why they're kept in a hash)
118.     end
119.
120.     protected
121.       def args_iterate(n) # n: number of arguments
122.         if n == 0
123.           yield
124.         else
125.           # fill in leftmost parameter, iterate over the remaining argumnents
126.           args_iterate(n - 1) do |*args|
127.             ret = false
128.             (1..9).each do |i|
129.               ret = yield(i, *args)
130.               break if ret # breaks out of all
131.             end
132.
133.             ret # return value has to be passed on to the higher level
134.           end
135.         end
136.       end
137.   end
138.
139.   class Solver
141.
142.     def initialize(rules)
143.       @rules = rules
144.     end
145.
146.     def sort_rules
147.       @rules = @rules.sort_by { |r| r.salience }.reverse # highest salience first
148.     end
149.
150.     def solve(sudoku, allow_bruteforce = false)
151.       # if apply_rules returns true, no bruteforcing is required.
152.       return true if apply_rules(sudoku)
153.       return false unless allow_bruteforce
154.       bruteforce(sudoku)
155.       return true
156.     end
157.
158.     def apply_rules(sudoku)
159.       # iterate over all implemented rules in order of saliency
160.       # if one is applicable and changes the sudoku, start over
161.       @rules.each do |rule|
162.         retry if rule.apply_to(sudoku) # true -> something has changed
163.       end
164.
165.       sudoku.solved?
166.     end
167.
168.     def bruteforce(sudoku)
169.       # TODO
170.     end
171.   end
172. end
173.
174.
175.
176. include Rudoku
177.
178. =begin RULE BLOCK:
179. heeft een aantal parameters, de eerste is het sudoku-object
180. geeft "true" terug als er een aanpassing gebeurd is aan de sudoku
181. =end
182.
183.
184. s = Sudoku.new
185. r = Rule.new do |s, i, j, k|
186.   puts i.to_s + "," + j.to_s + "," + k.to_s
187.   true if i == 3 && j == 5 && k == 2
188. end
189.
190. r.apply_to(s)
191.
192. # test code
193. =begin
194. s = Rudoku::Field.new(2,3)
195. puts s.position
196. s.remove(1..9)
197. puts s.possibilities
198. s.remove(1..4)
199. puts s.possibilities
200. puts s.solved?
201. s.remove(6..9)
202. puts s.possibilities
203. puts s.solved?
204.
205.
206. s = Rudoku::Sudoku.new
207. s[:B5] = [1,2,5]
208. s[:A1] = 1
209. s[:A2] = 2
210. puts s
211. =end
212.
213. # s.row(3).each do |f|
214. #   puts f.position
215. # end
216.
217. # puts s[9, 9].position
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy.

Top