class Grid
Attributes
points[RW]
remaining_nums[RW]
Public Class Methods
new(txt_file)
click to toggle source
# File lib/sudoku_solver/grid.rb, line 6 def initialize(txt_file) @points = [] txt_file.each_with_index do |text, row| text.split("").map(&:to_i).each_with_index do |num, col| @points << Point.new(row, col, num) end end remaining_points.each do |poi| poi.nums = Array(1..9) - (get_box(poi.box) + get_row(poi.y) + get_column(poi.x)) end end
Public Instance Methods
all_naked_pairs()
click to toggle source
# File lib/sudoku_solver/grid.rb, line 108 def all_naked_pairs fill_in pinned_points naked_pairs end
box_count(box, num)
click to toggle source
# File lib/sudoku_solver/grid.rb, line 208 def box_count(box, num) @points.select { |p| p.box == box && p.nums.to_set.subset?(num.to_set) }.count end
box_line_reduction()
click to toggle source
# File lib/sudoku_solver/grid.rb, line 151 def box_line_reduction pointing_pairs remaining_points.each do |point| (1..9).each do |num| [:x, :y].each do |symbol| possible = remaining_points.select { |p| p.send(symbol) == point.send(symbol) && p.box == point.box && p.include?(num) } if possible.count >= 2 if @points.select { |p| p.send(symbol) == point.send(symbol) && (!possible.include?(p)) && p.include?(num) }.count == 0 remove = remaining_points.select { |p| p.box == point.box && p.include?(num) && (!possible.include?(p)) } remove.each do |r| r.nums = (r.nums - [num]) end end end end end end end
check_row(row, point, num, symbol)
click to toggle source
# File lib/sudoku_solver/grid.rb, line 239 def check_row(row, point, num, symbol) a = @points.select { |p| p.send(flip(symbol)) == row && p != point }.map { |x| x.nums }.flatten a.count(num) <= 1 end
compare_points(arr)
click to toggle source
# File lib/sudoku_solver/grid.rb, line 182 def compare_points(arr) a = [] a << :x if arr.all? { |w| w.x == arr.first.x } a << :y if arr.all? { |s| s.y == arr.first.y } a << :box if arr.all? { |t| t.box == arr.first.box } a end
components()
click to toggle source
# File lib/sudoku_solver/grid.rb, line 82 def components [:x, :y, :box] end
fill_in()
click to toggle source
# File lib/sudoku_solver/grid.rb, line 71 def fill_in remaining_points.each do |p| find_diff(p) end end
fill_row(num)
click to toggle source
# File lib/sudoku_solver/grid.rb, line 44 def fill_row(num) @points.select { |point| point.x == num } end
find_diff(point)
click to toggle source
# File lib/sudoku_solver/grid.rb, line 48 def find_diff(point) point.nums = point.nums - (get_box(point.box) + get_row(point.y) + get_column(point.x)) end
flat_points()
click to toggle source
# File lib/sudoku_solver/grid.rb, line 52 def flat_points @points.select { |p| p.value == 0 } end
flip(n)
click to toggle source
# File lib/sudoku_solver/grid.rb, line 244 def flip(n) if n == :y :x else :y end end
get_box(num)
click to toggle source
# File lib/sudoku_solver/grid.rb, line 32 def get_box(num) @points.select { |point| point.box == num }.map { |b| b.value } end
get_column(num)
click to toggle source
# File lib/sudoku_solver/grid.rb, line 40 def get_column(num) @points.select { |point| point.x == num }.map { |b| b.value } end
get_row(num)
click to toggle source
# File lib/sudoku_solver/grid.rb, line 36 def get_row(num) @points.select { |point| point.y == num }.map { |b| b.value } end
get_values(arr)
click to toggle source
# File lib/sudoku_solver/grid.rb, line 56 def get_values(arr) arr.map { |b| b.value } end
is_solved?()
click to toggle source
# File lib/sudoku_solver/grid.rb, line 170 def is_solved? @points.select{ |p| p.value == 0 }.count == 0 end
naked_pairs()
click to toggle source
# File lib/sudoku_solver/grid.rb, line 114 def naked_pairs remaining_points.each do |point| next if point.nums.count <= 1 components.each do |symbol| possible = remaining_points.select { |p| p.subset?(point) && p != point && p.send(symbol) == point.send(symbol) && p.nums.count >= 2 } possible << point if possible.count == point.nums.count compare_points(possible).each do |type| found = remaining_points.select { |p| p.send(type) == point.send(type) && (!possible.include?(p)) } found.each do |f| f.nums = (f.nums - point.nums) end end end end end end
pinned_points()
click to toggle source
# File lib/sudoku_solver/grid.rb, line 86 def pinned_points remaining_points.each do |point| components.each do |symbol| point.nums.each do |num| if @points.select { |p| p.include?(num) && p.send(symbol) == point.send(symbol) && p != point }.count == 0 point.value = num end end end end end
pointing_pairs()
click to toggle source
# File lib/sudoku_solver/grid.rb, line 132 def pointing_pairs all_naked_pairs remaining_points.each do |point| (1..9).each do |num| [:x, :y].each do |symbol| possible = @points.select { |p| p.send(symbol) == point.send(symbol) && p.box == point.box && p.include?(num) } if possible.count >= 2 if @points.select { |p| p.box == point.box && (!possible.include?(p)) && p.include?(num) }.count == 0 remove = remaining_points.select { |p| p.box != point.box && p.send(symbol) == point.send(symbol) && p.include?(num) } remove.each do |r| r.nums = (r.nums - [num]) end end end end end end end
print_values()
click to toggle source
# File lib/sudoku_solver/grid.rb, line 26 def print_values a = @points.map { |p| p.value}.join puts a a end
print_values_formatted()
click to toggle source
# File lib/sudoku_solver/grid.rb, line 19 def print_values_formatted puts "SOLUTION" @points.each_slice(9) do |s| puts s.map{ |p| p.value}.join end end
remaining_points()
click to toggle source
# File lib/sudoku_solver/grid.rb, line 78 def remaining_points @points.select { |p| p.value == 0 } end
solve()
click to toggle source
# File lib/sudoku_solver/grid.rb, line 98 def solve while !is_solved? all_naked_pairs hidden_pairs pointing_pairs box_line_reduction x_wing end end
update_points() { |select { |p| send== num }| ... }
click to toggle source
# File lib/sudoku_solver/grid.rb, line 60 def update_points @points.select { |po| po.value == 0 }.each do |poi| find_diff(poi) end (0..8).each do |num| [:box, :x, :y].each do |fields| yield @points.select { |p| p.send(fields) == num } end end end
x_wing()
click to toggle source
# File lib/sudoku_solver/grid.rb, line 212 def x_wing box_line_reduction remaining_points.each do |point| point.nums.each do |num| [:x, :y].each do |symbol| arr = @points.select{ |p| p.nums.include?(num) && p.send(flip(symbol)) == point.send(flip(symbol)) && p.value == 0 } if arr.count == 2 && @points.select { |p| p.value == num && p.send(flip(symbol)) == point.send(flip(symbol)) }.count == 0 last = @points.select { |p| p.nums.include?(num) && arr.map{ |a| a.send(symbol) }.include?(p.send(symbol)) && (!arr.include?(p)) && p.value == 0 && check_row(p.y,p,num,symbol) } if last.all? { |x| x.send(flip(symbol)) == last.first.send(flip(symbol)) } && last.count == 2 && @points.select { |p| p.value == num && p.send(flip(symbol)) == last.first.send(flip(symbol)) }.count == 0 final = arr + last places = final.map { |m| m.send(symbol) }.uniq remaining_points.select { |p| places.include?(p.send(symbol)) && (!final.include?(p)) }.each do |poi| poi.nums = poi.nums - [num] end end end end end end end