module Sudoku::Logic

Logique de base du Sudoku

Public Instance Methods

base() click to toggle source

Renvoie la base du sudoku

@return (Fixnum)
# File lib/sudoku/logic.rb, line 123
def base
  if @base
    @base
  else
    @base = (size**0.5).to_i
  end
end
col(x) click to toggle source

Renvoie le contenu de la ligne x

@return (Array)
# 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?() click to toggle source

Renvoie true si chaque case a au moins 1 possibilité à ce stade

# 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?() click to toggle source

Renvoie true si le sudoku ne contient aucune case vide

# File lib/sudoku/logic.rb, line 44
def complete?
  each{|x,y,val| return false if val == 0}
  true
end
count(*values) click to toggle source

Compte le nombre d'occurences pour les valeurs @return [Hash] L'association valeur => occurences @overload count(*values)

Compte les occurences pour les valeurs passées en paramètres
@param [*Fixnum] values Les valeurs à compter

@overload count

Compte les occurences de chaque valeur
# 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) click to toggle source

Charge un sudoku depuis un autre sudoku

@param [Grid] l'autre Sudoku
@return (self)
@raise [NotCompatibleError] L'autre sudoku est de base differente
# 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() click to toggle source

Représentation courte (utile dans irb)

@return [String]
# 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() click to toggle source

Renvoie le nombre de cases dans le sudoku

@return (Fixnum)
# File lib/sudoku/logic.rb, line 133
def length
  if @length
    @length
  else
    @length = size*size
  end
end
load(sutxt_str) click to toggle source

Charge un Sudoku depuis une chaine Sutxt

@return (self)
@raise [MalformedSutxtError] Chaine Sutxt mal formatee
@raise [NotCompatibleError]  La chaine Sutxt correspond a un Sudoku de base differente
# 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) click to toggle source

Renvoie toutes les possibilités pour la case x,y

@return (Array)
# 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) click to toggle source

Renvoie le contenu de la ligne y

@return (Array)
# 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) click to toggle source

Renvoie le contenu du carré contenant la case x,y

@return (Array)
# 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() click to toggle source

Représentation texte humainement lisible

@return (String)
# 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() click to toggle source

Représentation pour l'enregistrement

@return (String)
# 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?(*args) click to toggle source

@overload valid?(x, y, val)

Vérifie si val est valide en x,y
@param [Fixnum] x   La colonne de la valeur à vérifier
@param [Fixnum] y   La ligne de la valeur à vérifier
@param [Fixnum] val La valeur à vérifier
@return [Boolean] true si la valeur est valide, false sinon

@overload valid?

Vérifie que toutes les valeurs du Sudoku sont vlaides
@return [Boolean] true si toutes les valeurs sont valides, false sinon
# 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) click to toggle source

Renvoie true si val est possible en x,y

# 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?() click to toggle source

Renvoie true si tous les nombres de la grille sont valides

# 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