Class: Kira::Puzzle
- Inherits:
-
Object
- Object
- Kira::Puzzle
- Defined in:
- lib/kira/puzzle.rb
Overview
Represents the state of a 9x9 sudoku puzzle.
Instance Attribute Summary collapse
-
#grid ⇒ Object
readonly
Returns the value of attribute grid.
Instance Method Summary collapse
- #[](idx) ⇒ Object
- #[]=(idx, val) ⇒ Object
-
#initialize(grid) ⇒ Puzzle
constructor
A new instance of Puzzle.
-
#scan(pos, &proc) ⇒ Object
(also: #update)
Traverses the row, column, and box containing the ‘pos’ and calls the ‘proc’ with the current index as an argument on each step.
- #to_s ⇒ Object
-
#valid?(val, pos) ⇒ Boolean
Returns true if the ‘val’ on the given ‘pos’ does not repeat in a column, row or box.
Constructor Details
#initialize(grid) ⇒ Puzzle
Returns a new instance of Puzzle.
7 8 9 10 11 12 13 14 15 16 17 18 |
# File 'lib/kira/puzzle.rb', line 7 def initialize(grid) grid.delete!(" \t\n\r") if grid.length != 81 raise ArgumentError.new("Grid has invalid size") elsif not grid.match("^[0-9.]{81}$") raise ArgumentError.new("Grid contains invalid characters") end @grid = [] grid.each_char { |c| @grid.push(c.to_i) } end |
Instance Attribute Details
#grid ⇒ Object (readonly)
Returns the value of attribute grid.
20 21 22 |
# File 'lib/kira/puzzle.rb', line 20 def grid @grid end |
Instance Method Details
#[](idx) ⇒ Object
92 93 94 |
# File 'lib/kira/puzzle.rb', line 92 def [](idx) @grid[idx] end |
#[]=(idx, val) ⇒ Object
96 97 98 99 100 101 102 103 104 |
# File 'lib/kira/puzzle.rb', line 96 def []=(idx, val) if idx > 80 raise IndexError.new("Index out of range") elsif not val.between?(0, 9) raise ArgumentError.new("Value out of range") end @grid[idx] = val end |
#scan(pos, &proc) ⇒ Object Also known as: update
Traverses the row, column, and box containing the ‘pos’ and calls the ‘proc’ with the current index as an argument on each step. Note that it visits some cells more than once.
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 |
# File 'lib/kira/puzzle.rb', line 25 def scan(pos, &proc) # pos - (pos % 9): # index of the first cell in the row containing 'pos'. # # pos % 9: # index of the first cell in the column containing 'pos'. # # (pos - (pos % 3)): # index of the left-most cell in the box containing 'pos'. # # (pos - (pos % 3)) % 9: # index of the first cell in the column containing the top-left corner # of the box. # # (pos - (pos % 27)): # index of the first cell in the row containing the top-left corner of # the box. # # (pos - (pos % 3)) % 9 + (pos - (pos % 27)): # index of the top-left corner of the box containing 'pos'. # Scan row 9.times do |i| proc.call((pos - (pos % 9)) + i) end # Scan col 9.times do |i| proc.call((pos % 9) + i*9) end # Scan box corner_idx = (pos - (pos % 3)) % 9 + (pos - (pos % 27)) 3.times do |i| 3.times do |j| proc.call(corner_idx + i*9 + j) end end end |
#to_s ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/kira/puzzle.rb', line 76 def to_s string = "" 0.upto(80) do |i| if @grid[i] == 0 string << "." else string << @grid[i].to_s end if ((i + 1) % 9 == 0 and i != 80) string << "\n" end end string end |
#valid?(val, pos) ⇒ Boolean
Returns true if the ‘val’ on the given ‘pos’ does not repeat in a column, row or box. The ‘pos’ is a 1-dimensional, 0-based index.
69 70 71 72 73 74 |
# File 'lib/kira/puzzle.rb', line 69 def valid?(val, pos) if val != 0 scan(pos) { |i| if val == @grid[i] then return false end } end true end |