Module: Sudoku::Logic
- Included in:
- Grid
- Defined in:
- lib/sudoku/logic.rb
Overview
Logique de base du Sudoku
Instance Method Summary collapse
-
#base ⇒ Fixnum
Renvoie la base du sudoku.
-
#col(x) ⇒ Array
Renvoie le contenu de la ligne x.
-
#completable? ⇒ Boolean
Renvoie true si chaque case a au moins 1 possibilité à ce stade.
-
#complete? ⇒ Boolean
Renvoie true si le sudoku ne contient aucune case vide.
-
#count(*values) ⇒ Hash
Compte le nombre d’occurences pour les valeurs.
-
#import(other) ⇒ self
Charge un sudoku depuis un autre sudoku.
-
#inspect ⇒ String
Représentation courte (utile dans irb).
-
#length ⇒ Fixnum
Renvoie le nombre de cases dans le sudoku.
-
#load(sutxt_str) ⇒ self
Charge un Sudoku depuis une chaine Sutxt.
-
#possibilities(x, y) ⇒ Array
Renvoie toutes les possibilités pour la case x,y.
-
#row(y) ⇒ Array
Renvoie le contenu de la ligne y.
-
#square(x, y) ⇒ Array
Renvoie le contenu du carré contenant la case x,y.
-
#to_s ⇒ String
Représentation texte humainement lisible.
-
#to_sutxt ⇒ String
Représentation pour l’enregistrement.
- #valid?(*args) ⇒ Object
-
#valid_cell?(x, y, val) ⇒ Boolean
Renvoie true si val est possible en x,y.
-
#valid_grid? ⇒ Boolean
Renvoie true si tous les nombres de la grille sont valides.
Instance Method Details
#base ⇒ Fixnum
Renvoie la base du sudoku
123 124 125 126 127 128 129 |
# File 'lib/sudoku/logic.rb', line 123 def base if @base @base else @base = (size**0.5).to_i end end |
#col(x) ⇒ Array
Renvoie le contenu de la ligne x
6 7 8 9 10 11 12 13 |
# File 'lib/sudoku/logic.rb', line 6 def col x res = [] size.times do |y| val = get x, y res << val if val != 0 end res end |
#completable? ⇒ Boolean
Renvoie true si chaque case a au moins 1 possibilité à ce stade
50 51 52 53 54 55 56 |
# File 'lib/sudoku/logic.rb', line 50 def completable? completed = 0 each do |x, y, val| return false if possibilities(x, y).empty? end return true end |
#complete? ⇒ Boolean
Renvoie true si le sudoku ne contient aucune case vide
44 45 46 47 |
# File 'lib/sudoku/logic.rb', line 44 def complete? each{|x,y,val| return false if val == 0} true end |
#count(*values) ⇒ Hash #count ⇒ Hash
Compte le nombre d’occurences pour les valeurs
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/sudoku/logic.rb', line 148 def count *values values = Array.new(size){|i| i+1} if values.empty? res = {} values.each do |val| if val<0 || val>size raise ArgumentError, "Impossible value #{val} in a #{size}x#{size} sudoku" end res[val] = 0 end each do |x, y, val| res[val] += 1 if values.include? val end res end |
#import(other) ⇒ self
Charge un sudoku depuis un autre sudoku
234 235 236 237 238 239 240 |
# File 'lib/sudoku/logic.rb', line 234 def import other unless size == other.size raise NotCompatibleError, "Cannot import a #{other.base} sudoku in a #{base} sudoku" end other.each{|x,y,v| set x, y, v} self end |
#inspect ⇒ String
Représentation courte (utile dans irb)
187 188 189 |
# File 'lib/sudoku/logic.rb', line 187 def inspect "#<#{self.class} #{size}x#{size} [#{get 0, 0}, #{get 0, 1}, ... , #{get size-2, size-1}, #{get size-1, size-1}]>" end |
#length ⇒ Fixnum
Renvoie le nombre de cases dans le sudoku
133 134 135 136 137 138 139 |
# File 'lib/sudoku/logic.rb', line 133 def length if @length @length else @length = size*size end end |
#load(sutxt_str) ⇒ self
Charge un Sudoku depuis une chaine Sutxt
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/sudoku/logic.rb', line 207 def load sutxt_str unless sutxt_str =~ /(\d+):(.+);/ raise MalformedSutxtError, "It doesn't seem to be a sutxt line..." end sutxt_base = $1.to_i unless sutxt_base == base raise NotCompatibleError, "A #{base} sudoku cannot load a #{sutxt_base} Sutxt" end data = $2.split(/\s+/).delete_if(&:empty?).map(&:to_i) unless data.length == length raise MalformedSutxtError, "Expecting #{length} numbers, #{data.length} given" end size.times do |y| size.times do |x| set x, y, data.shift end end self end |
#possibilities(x, y) ⇒ Array
Renvoie toutes les possibilités pour la case x,y
60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/sudoku/logic.rb', line 60 def possibilities x, y res = Array.new(size){|i| i+1} xmin = x-x%base ymin = y-y%base size.times do |i| res.delete get(x,i) if i!=y res.delete get(i,y) if i!=x xx, yy = xmin+i%base, ymin+i/base res.delete get(xx, yy) if xx!=x && yy!=y end res end |
#row(y) ⇒ Array
Renvoie le contenu de la ligne y
17 18 19 20 21 22 23 24 |
# File 'lib/sudoku/logic.rb', line 17 def row y res = [] size.times do |x| val = get x, y res << val if val != 0 end res end |
#square(x, y) ⇒ Array
Renvoie le contenu du carré contenant la case x,y
28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/sudoku/logic.rb', line 28 def square x, y xmin = x - (x%base) ymin = y - (y%base) res = [] base.times do |xx| base.times do |yy| val = get xx+xmin, yy+ymin res << val if val != 0 end end res end |
#to_s ⇒ String
Représentation texte humainement lisible
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/sudoku/logic.rb', line 168 def to_s res = "" width = size.to_s.length zero = ".".center width+1 size.times do |y| res += "\n" if y>0 && y%base == 0 size.times do |x| res += " " if x>0 && x%base == 0 val = get x, y res += val.zero? ? zero : "#{val.to_s.center width} " end res += "\n" end res end |
#to_sutxt ⇒ String
Représentation pour l’enregistrement
193 194 195 196 197 198 199 200 201 |
# File 'lib/sudoku/logic.rb', line 193 def to_sutxt res = "#{base}:" size.times do |y| size.times do |x| res << " #{get x, y}" end end res+';' end |
#valid?(x, y, val) ⇒ Boolean #valid? ⇒ Boolean
111 112 113 114 115 116 117 118 119 |
# File 'lib/sudoku/logic.rb', line 111 def valid? *args if args.empty? valid_grid? elsif args.length == 3 valid_cell? *args else raise ArgumentError, "wrong number of arguments(#{args.length} for 0 or 3)" end end |
#valid_cell?(x, y, val) ⇒ Boolean
Renvoie true si val est possible en x,y
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/sudoku/logic.rb', line 86 def valid_cell? x, y, val return true if val.zero? val = val.to_i xmin = x-x%base ymin = y-y%base size.times do |i| return false if i!=y && get(x,i)==val return false if i!=x && get(i,y)==val xx, yy = xmin+i%base, ymin+i/base return false if xx!=x && yy!=y && get(xx, yy) == val end true end |
#valid_grid? ⇒ Boolean
Renvoie true si tous les nombres de la grille sont valides
76 77 78 79 80 81 82 83 |
# File 'lib/sudoku/logic.rb', line 76 def valid_grid? each do |x, y, val| next if val.zero? return false unless valid_cell? x, y, val end true end |