Class: Kira::Puzzle

Inherits:
Object
  • Object
show all
Defined in:
lib/kira/puzzle.rb

Overview

Represents the state of a 9x9 sudoku puzzle.

Instance Attribute Summary collapse

Instance Method Summary collapse

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

#gridObject (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_sObject



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.

Returns:

  • (Boolean)


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