Skip to content

Instantly share code, notes, and snippets.

@sunny
Created July 9, 2023 23:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sunny/474ebe4bc8929b0c892a3dc37f8450f8 to your computer and use it in GitHub Desktop.
Save sunny/474ebe4bc8929b0c892a3dc37f8450f8 to your computer and use it in GitHub Desktop.
class Sudoku
def initialize(lines)
@lines = lines
end
attr_reader :lines
def complete?
groups.all? { |group| complete_group?(group) }
end
def resolve
1.times do
9.times { |y| resolve_line(y) }
9.times { |x| resolve_row(x) }
9.times { |z| resolve_chunk(z) }
end
rescue => e
nil
end
def to_s
string_lines = lines.map do |numbers|
numbers
.each_slice(3)
.map { |n| n.join("") }
.join(" ")
end
string_lines.each_slice(3).map { |slices| slices.join("\n") }.join("\n\n")
end
# private
def groups
lines + rows + chunks
end
def rows
9.times.map do |row_index|
9.times.map do |index|
lines[index][row_index]
end
end
end
def chunks
chunks = []
lines.each_with_index do |line, index|
line.each_with_index do |value, jdex|
chunk = index / 3 + 3 * (jdex / 3)
chunks[chunk] ||= []
chunks[chunk] << value
end
end
chunks
end
def full_group
(1..9).to_a
end
def complete_group?(group)
group.sort == full_group
end
def resolve_line(y)
line = lines[y]
return if complete_group?(line)
line.each_with_index do |value, x|
next if value != 0
possible_values = full_group - line
lines[y][x] = possible_values.first if possible_values.count == 1
end
end
def resolve_row(x)
row = rows[x]
return if complete_group?(row)
row.each_with_index do |value, y|
next if value != 0
possible_values = full_group - row
lines[y][x] = possible_values.first if possible_values.count == 1
end
end
def resolve_chunk(z)
chunk = chunks[z]
return if complete_group?(chunk)
chunk.each_with_index do |value, i|
next if value != 0
possible_values = full_group - chunk
if possible_values.count == 1
p [z, i, possible_values.first.to_s, chunk]
# 0 => 0
# 1 => 3
# 2 => 6
# 3 => 0
# 4 => 3
# 5 => 6
# 6 => 0
# 7 => 3
# 8 => 6
y = z / 3
x = 0
p [y, x, 3, 3, lines[y][x]]
puts to_s
raise "done"
end
end
end
end
# sudoku = Sudoku.new([
# [0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0],
# ])
# p sudoku.complete?
# sudoku = Sudoku.new([
# [1, 2, 3, 4, 5, 6, 7, 8, 9],
# [7, 8, 9, 1, 2, 3, 4, 5, 6],
# [4, 5, 6, 7, 8, 9, 1, 2, 3],
# [2, 3, 4, 5, 6, 7, 8, 9, 1],
# [5, 6, 7, 8, 9, 1, 2, 3, 4],
# [8, 9, 1, 2, 3, 4, 5, 6, 7],
# [3, 4, 5, 6, 7, 8, 9, 1, 2],
# [6, 7, 8, 9, 1, 2, 3, 4, 5],
# [9, 1, 2, 3, 4, 5, 6, 7, 8],
# ])
# p sudoku.complete?
sudoku = Sudoku.new([
[1, 2, 3, 4, 5, 6, 7, 8, 9],
[7, 8, 9, 1, 2, 3, 0, 5, 6],
[4, 5, 6, 7, 8, 9, 1, 2, 3],
[0, 3, 0, 0, 6, 7, 8, 9, 1],
[5, 0, 0, 8, 9, 1, 2, 3, 4],
[0, 9, 1, 2, 3, 4, 5, 0, 7],
[3, 4, 5, 6, 7, 8, 9, 1, 2],
[6, 7, 8, 0, 1, 2, 3, 4, 0],
[9, 1, 2, 3, 4, 5, 6, 0, 0],
])
sudoku.resolve
# puts sudoku.to_s
# p sudoku.complete?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment