| 
View
 

ReportMeet20060830

Page history last edited by PBworks 19 years, 3 months ago

Incontro, 30 agosto 2006. Tema: sudoku

 


 

Eccoci tornati dalla pausa estiva, fra l'ultimo incontro riportato sul wiki e la pausa estiva ci sono stati un altro paio di incontri, uno dei quali ha visto i partecipanti impegnati nella realizzazione del kata del sudoku

 

L'esperienza di questo primo incontro è stata positiva, così abbiamo pensato di rompere il ghiaccio della nuova stagione proprio con questo esercizio. All'inizio dell'incontro, dopo i saluti (Gabriele: e i complimenti per il mio nuovo MacBookPro) abbiamo deciso che lo scopo di questo kata:

  • data una tavola non completa, e una casella vuota, fornire l'elenco di tutti i numeri che possono essere inseriti in quella casella secondo le regole del gioco

 

Si sono formate quattro coppie, due coppie hanno sviluppato una soluzione in java, le altre due in ruby, di seguito il risultato delle nostre fatiche

 

Coppia: Gabriele/Uberto, Linguaggio: Ruby

 

abbiamo raggiunto l'obiettivo che ci eravamo prefissati, e siamo andati oltre, abbiamo aggiunto una strategia risolutiva banale ma efficace nei casi più semplici: scorrere la tabella cercando quelle caselle vuote dove il numero dei numeri inseribili è uno, ovvero quelle caselle completamente vincolate, inserire il numero, ripetere il ciclo fino a che la board non è completa. Questa strategia ha il vantaggio di essere incrementale, ovvero di volta in volta potrebbe suggerire al giocatore la prossima mossa da fare :-)

 

sudoku_test.rb

require 'test/unit'
require 'sudoku'

class SequenceTest < Test::Unit::TestCase

  def test_sequence
    sequence = Sequence.new([0,1,2,3,4,5,6,7,8])
    assert_equal(5, sequence[5])
    assert(sequence.ok?)
  end

  def test_repetions
    sequence = Sequence.new([1,1,2,3,4,5,6,7,8])
    assert(!sequence.ok?)
    sequence = Sequence.new([0,0,2,3,4,5,6,7,8])
    assert(sequence.ok?)
  end

  def test_forbidden
    sequence = Sequence.new([1,2,10,3,4,5,6,7,8])
    assert(!sequence.ok?)
  end

  def test_nine_digit
    sequence = Sequence.new([0,1,2,3,4,5,6,7,8,0])
    assert(!sequence.ok?)
  end

  def test_complete
    sequence = Sequence.new([0,1,2,3,4,5,6,7,8])
    assert(!sequence.complete?)
    sequence = Sequence.new([1,2,3,4,5,6,7,8,9])
    assert(sequence.complete?)
  end

  def test_missing_numbers
    sequence = Sequence.new([0,1,2,3,4,5,6,7,8])
    assert_equal([9], sequence.missing_numbers)
    sequence = Sequence.new([0,0,2,3,4,5,6,0,8])
    assert_equal([1,7,9], sequence.missing_numbers)
  end

  def test_sequence_as_string
    sequence = Sequence.new([1,2,3,4,5,6,7,8,9])
    assert_equal("1 2 3 4 5 6 7 8 9", sequence.to_str)
  end

end

class SudokuTest < Test::Unit::TestCase

  def setup
    @complete = Sudoku.new([
      8,1,9,6,7,5,3,2,4,
      6,4,2,9,8,3,7,5,1,
      5,3,7,1,2,4,8,6,9,
      4,2,6,5,9,7,1,8,3,
      7,9,5,3,1,8,6,4,2,
      1,8,3,4,6,2,5,9,7,
      3,5,8,7,4,9,2,1,6,
      2,6,4,8,3,1,9,7,5,
      9,7,1,2,5,6,4,3,8])
    @incomplete = Sudoku.new([
      8,1,9,6,7,5,3,2,4,
      6,4,2,9,8,3,7,5,1,
      5,3,7,1,2,4,8,6,9,
      4,2,6,5,0,7,1,8,3,
      7,0,5,3,1,0,6,4,2,
      1,8,3,4,6,2,5,9,7,
      3,5,8,7,4,9,2,1,6,
      2,6,4,8,3,1,9,7,5,
      9,7,1,2,5,0,4,3,8])
    @real = Sudoku.new([
      1,0,2,0,0,0,7,0,0,
      0,4,7,0,2,1,3,0,0,
      0,8,0,7,0,3,0,1,0,
      4,6,0,1,0,0,0,8,0,
      0,0,0,2,6,4,0,0,0,
      0,5,0,0,0,9,0,6,4,
      0,9,0,5,0,7,0,2,0,
      0,0,1,3,4,0,9,7,0,
      0,0,6,0,0,0,8,0,3])
    @solved = Sudoku.new([
      1,3,2,4,5,8,7,9,6,
      9,4,7,6,2,1,3,5,8,
      6,8,5,7,9,3,4,1,2,
      4,6,9,1,3,5,2,8,7,
      7,1,8,2,6,4,5,3,9,
      2,5,3,8,7,9,1,6,4,
      3,9,4,5,8,7,6,2,1,
      8,2,1,3,4,6,9,7,5,
      5,7,6,9,1,2,8,4,3])
  end

  def test_empty_board
    sudoku = Sudoku.empty
    assert(sudoku.ok?)
  end
  
  def test_ok
    assert(@complete.ok?)
  end

  def test_complete
    assert(@complete.complete?)
  end

  def test_select_line
    assert_equal([5,3,7,1,2,4,8,6,9], @complete.line(2))
    assert_equal([6,4,2,9,8,3,7,5,1], @complete.line(1))
  end

  def test_select_column
    assert_equal([7,8,2,9,1,6,4,3,5], @complete.column(4))
    assert_equal([1,4,3,2,9,8,5,6,7], @complete.column(1))
    assert(@complete.column(4).ok?)
  end

  def test_select_square
    assert_equal([8,1,9,6,4,2,5,3,7], @complete.square(0))
    assert(@complete.square(0).ok?)
    assert_equal([5,9,7,3,1,8,4,6,2], @complete.square(4))
    assert(@complete.square(4).ok?)
  end

  def test_square_at
    assert_equal([8,1,9,6,4,2,5,3,7], @complete.square_at(2,2))
    assert_equal([5,9,7,3,1,8,4,6,2], @complete.square_at(4,5))
  end

  def test_missing_numbers
    assert_equal([8], @incomplete.missing_numbers(4,5))
  end
  
  def test_hint
    assert_equal([0,1,3], @real.hint)
  end

  def test_solve
    while !@real.complete?
      @real.hint!
    end
    assert_equal(@real, @solved)
  end

end

 

sudoku.rb

class Sequence < Array

  def ok?
    !repeated_digit? && !forbidden_digit? && nine_digit?
  end

  def complete?
    ok? && !zero_digit?
  end

  def missing_numbers
    [1,2,3,4,5,6,7,8,9] - self
  end

  def repeated_digit?
    filled = select { |digit| digit > 0 } 
    filled.uniq != filled
  end

  def forbidden_digit?
    any? { |digit| digit < 0 || digit > 9}
  end
  
  def nine_digit?
    size == 9
  end

  def zero_digit?
    any? { |digit| digit == 0 }
  end

  def to_str
    join(" ")
  end
    
end


class Sudoku

  def initialize(digits)
    @lines = (0..8).inject([]) do |lines,i|
      lines << Sequence.new(digits.slice!(0, 9))
    end
  end

  def Sudoku.empty
    Sudoku.new([0]*81)
  end

  def ok?
    @lines.all? { |l| l.ok? } && @lines.size == 9
  end

  def complete?
    @lines.all? { |l| l.complete? }
  end

  def line(index) 
    @lines[index]
  end

  def column(index)
    Sequence.new((@lines.transpose)[index])
  end

  def square(index)
    Sequence.new(
      (0..2).inject([]) do |square,i|
        square += @lines[(index/3)*3+i].slice((index % 3)*3,3)
      end
    )
  end

  def missing_numbers(line_index, column_index)
    return [] if @lines[line_index][column_index] > 0
    line(line_index).missing_numbers &
    column(column_index).missing_numbers &
    square_at(line_index,column_index).missing_numbers
  end

  def hint
    (0..8).each do |line|
      (0..8).each do |column|
        missing = missing_numbers(line,column)
        return [line,column,missing.first] if missing.size == 1
      end
    end
  end

  def hint!
    put(*hint) 
  end

  def put(line_index, column_index, digit)
    @lines[line_index][column_index] = digit
  end

  def square_at(line_index, column_index)
    square(((line_index/3)*3) + (column_index/3))
  end

  def to_str
    @lines.inject("") { |str,l| str << l << "n" } 
  end

  def ==(other)
    to_str == other.to_str
  end

end

 

 

Coppia: Franco/Marco, Linguaggio: Java

NineIntValidatorTest.java

import junit.framework.TestCase;

public class NineIntValidatorTest extends TestCase {
  
  public void testIsValid() {
    NineIntValidator validator = new NineIntValidator(
        new int[] {1,2,3,4,5,6,7,8,9}
    );
    
    assertTrue(validator.isValid());
    
  }
}

 

NineIntValidator.java

import java.util.*;

public class NineIntValidator {

  private int[] numbers;
  private Set okSet = new HashSet();

  public NineIntValidator(int[] numbers) {
    this.numbers = numbers;
  }

  public boolean isValid() {
    boolean result = true;
    for (int i = 0; i < numbers.length && result; i++) {
      if (numbers[i]<0 || numbers[i]>9) {
        result = false;
      } else if (numbers[i]!=0) {
        result = okSet.add(new Integer(numbers[i]));
      }
    }
    return result;
  }

}

 

 

SectionTest.java

import junit.framework.TestCase;

public class SectionTest extends TestCase {
  
  public void testCompleteRow() {
    Section row = new Section(8,1,9,6,7,5,3,2,4);
    assertTrue(row.isComplete());
    
    row = new Section(8,1,9,6,7,0,3,2,4);
    assertFalse(row.isComplete());
  }

  
  public void testValidRow() {
    Section row = new Section(8,1,9,6,7,5,3,2,4);
    assertTrue(row.isValid());
    
    row = new Section(8,8,9,6,7,0,3,2,4);
    assertFalse(row.isValid());
    
    row = new Section(8,1,9,6,7,0,3,2,4);
    assertTrue(row.isValid());
    
    row = new Section(8,1,9,6,7,-1,3,2,4);
    assertFalse(row.isValid());
  }
  
  public void testEquals() {
    Section section1 = new Section(1,2,3,4,5,6,7,8,9);
    Section section2 = new Section(1,2,3,4,5,6,7,8,9);
    assertEquals(section1, section2);
  }
  
  public void testCloneSection() {
    Section section1 = new Section(1,2,3,4,5,6,7,8,9);
    assertEquals(section1, section1.cloneSection());
  }
  
  public void testSetValueAt() {
    Section section1 = new Section(1,2,3,4,5,6,7,8,0);
    Section expected = new Section(1,2,3,4,5,6,7,8,9);
    section1.setValueAt(8,9);
    assertEquals(section1, expected);
  }
}

 

 

Section.java

public class Section {
  
  private int[] values;

  public Section(int i, int j, int k, int l, int m, int n, int o, int p, int q) {
    values = new int[]{i, j, k,  l,  m,  n,  o,  p,  q};
  }
  
  public Section(int[] values) {
    this(values[0],values[1],values[2],values[3],values[4],values[5],
        values[6],values[7],values[8]);
  }

  public boolean isComplete() {
    boolean result = true;
    for (int i = 0; i < values.length && result; i++) {
      result = result && values[i]> 0; 
    }
    return result;
  }

  public boolean isValid() {
    NineIntValidator validator = new NineIntValidator(values);
    return validator.isValid();
  }

  public boolean equals(Object obj) {
    try {
      Section s2 = (Section) obj;
      boolean result = true;
      for (int i = 0; i < values.length && result; i++) {
        result = result && values[i] == s2.values[i];
      }
      return result;
    } catch (RuntimeException e) {
      return false;
    }
  }
  
  public int getValueAt(int position) {
    return values[position];
  }

  public Section cloneSection() {
    int[] cloned = new int[values.length];
    System.arraycopy(values, 0, cloned, 0, values.length);
    return new Section(cloned);
  }

  public void setValueAt(int position, int value) {
    values[position]=value;
    
  }
  
}

 

 

BoardTest.java

import java.util.Collection;

import junit.framework.TestCase;

public class BoardTest extends TestCase {
  private Board validAndCompleteBoard = new Board(
      new Section(8,1,9,6,7,5,3,2,4),
      new Section(6,4,2,9,8,3,7,5,1),
      new Section(5,3,7,1,2,4,8,6,9),
      new Section(4,2,6,5,9,7,1,8,3),
      new Section(7,9,5,3,1,8,6,4,2),
      new Section(1,8,3,4,6,2,5,9,7),
      new Section(3,5,8,7,4,9,2,1,6),
      new Section(2,6,4,8,3,1,9,7,5),
      new Section(9,7,1,2,5,6,4,3,8));
  
  private Board     almostEmptyBoard = new Board(
      new Section(8,1,9,6,7,5,3,2,4),
      new Section(6,9,2,4,8,3,7,5,1),
      new Section(5,3,7,1,2,4,0,6,9),
      new Section(0,0,0,0,0,0,0,0,0),
      new Section(0,0,0,0,0,0,0,0,0),
      new Section(0,0,0,0,0,0,0,0,0),
      new Section(0,0,0,0,0,0,0,0,0),
      new Section(0,0,0,0,0,0,0,0,0),
      new Section(0,0,0,0,0,0,0,0,0));
  
  public void testCompleteBoard() {
    
    assertTrue(validAndCompleteBoard.isComplete());
    
    Board board = new Board(
        new Section(8,1,9,6,7,5,3,2,4),
        new Section(6,4,2,9,8,3,7,5,1),
        new Section(5,3,7,1,2,4,0,6,9),
        new Section(4,2,6,5,9,7,1,8,3),
        new Section(7,9,5,3,1,8,6,4,2),
        new Section(1,8,3,4,6,2,5,9,7),
        new Section(3,5,8,7,4,9,2,1,6),
        new Section(2,6,4,8,3,1,9,7,5),
        new Section(9,7,1,2,5,6,4,3,8));
    
    assertFalse(board.isComplete());
  }
  
  public void testValidBoard() {

    
    assertTrue(validAndCompleteBoard.isValid());
    
    Board board = new Board(
        new Section(8,1,9,6,7,5,3,2,4),
        new Section(6,4,2,9,8,3,7,5,1),
        new Section(5,3,7,1,2,4,0,6,9),
        new Section(4,2,6,5,9,7,1,8,3),
        new Section(7,9,5,3,1,8,6,4,2),
        new Section(1,8,3,4,6,2,5,9,7),
        new Section(3,5,8,7,4,9,2,1,6),
        new Section(2,6,4,8,3,1,9,7,5),
        new Section(9,7,1,2,5,6,4,3,8));
    
    assertTrue(board.isValid());
    
    board = new Board(
        new Section(8,1,9,6,7,5,3,2,4),
        new Section(8,4,2,9,6,3,7,5,1),
        new Section(5,3,7,1,2,4,8,6,9),
        new Section(4,2,6,5,9,7,1,8,3),
        new Section(7,9,5,3,1,8,6,4,2),
        new Section(1,8,3,4,6,2,5,9,7),
        new Section(3,5,8,7,4,9,2,1,6),
        new Section(2,6,4,8,3,1,9,7,5),
        new Section(9,7,1,2,5,6,4,3,8));
    
    assertFalse(board.isValid());
    
    
    assertFalse(almostEmptyBoard.isValid());
  }
  
  public void testColumn() {
    Section firstColumn = validAndCompleteBoard.column(0);
    assertEquals(new Section(8,6,5,4,7,1,3,2,9),firstColumn);
  }
  
  public void testSquare() {
    Board board = new Board(
        new Section(8,1,9,6,7,5,3,2,4),
        new Section(6,9,2,4,8,3,7,5,1),
        new Section(5,3,7,1,2,4,0,6,9),
        new Section(0,0,0,0,0,0,0,0,0),
        new Section(0,0,0,0,0,0,0,1,2),
        new Section(0,0,0,0,0,0,0,0,0),
        new Section(0,0,0,0,0,0,0,0,0),
        new Section(0,0,0,0,0,0,0,0,0),
        new Section(0,0,0,0,0,0,0,0,0));
    
    assertEquals(new Section(8,1,9,6,9,2,5,3,7), board.square(0, 0));
    assertEquals(new Section(0,0,0,0,1,2,0,0,0), board.square(1, 2));
  }
  
  public void testPossibleValues() {
    Board board = new Board(
        new Section(8,1,9,6,7,5,3,2,4),
        new Section(6,4,2,9,8,3,7,5,1),
        new Section(5,3,7,1,2,4,0,6,9),
        new Section(0,0,0,0,0,0,0,0,0),
        new Section(0,0,0,0,0,0,0,1,2),
        new Section(0,0,0,0,0,0,0,0,0),
        new Section(0,0,0,0,0,0,0,0,0),
        new Section(0,0,0,0,0,0,0,0,0),
        new Section(0,0,0,0,0,0,0,0,0));
    
    assertTrue(board.isValid());
    
    Collection possibleValues = board.possibleValues(0,0);
    assertTrue(possibleValues.isEmpty());
    
    possibleValues = board.possibleValues(2, 6);
    assertEquals(1, possibleValues.size());
    assertEquals(new Integer(8), possibleValues.iterator().next());
    
    possibleValues = board.possibleValues(3, 7);
    assertEquals(5, possibleValues.size());
    assertTrue(possibleValues.contains(new Integer(3)));
    assertTrue(possibleValues.contains(new Integer(4)));
    assertTrue(possibleValues.contains(new Integer(7)));
    assertTrue(possibleValues.contains(new Integer(8)));
    assertTrue(possibleValues.contains(new Integer(9)));
  }
  
  public void testIsEmpty() {
    assertFalse(validAndCompleteBoard.isEmpty(5,5));
    assertTrue(almostEmptyBoard.isEmpty(5,5));
  }
  
  public void testSetValueAt() {
    Board board = almostEmptyBoard.cloneBoard();
    int r = 3;
    int c = 1;
    int v = 9;
    assertEquals(0, board.getValueAt(r,c));
    board.setValueAt(r, c, v);
    assertEquals(v, board.getValueAt(r,c));
  }

}

 

Board.java

import java.util.*;

public class Board {

  private Section[] rows;
  
  public Board(Section row1, Section row2, Section row3, Section row4, Section row5, Section row6,
      Section row7, Section row8, Section row9) {
    rows=new Section[]{row1, row2, row3, row4, row5,row6,row7, row8, row9};
  }

  public boolean isComplete() {
    boolean result = true;
    for (int i = 0; i < rows.length; i++) {
      result = result && rows[i].isComplete();
    }
    return result;
  }

  public boolean isValid() {
    
    boolean result = true;
    for (int i = 0; i < rows.length; i++) {
      result = result && rows[i].isValid();
      result = result && column(i).isValid();
    }
    if (result) {
      for (int r= 0; r < 3; r++) {
        for (int c = 0; c < 3; c++) {
          result = result && square(r, c).isValid();
        }
      }
    }
    return result;
  }

  public Section column(int colPosition) {
    int[] colValues = new int[9];
    for (int i = 0; i < rows.length; i++) {
      colValues[i]=rows[i].getValueAt(colPosition);
    }
    return new Section(colValues);
  }

  public Section square(int row, int col) {
    int y = row*3;
    int x = col*3;
    Section result = 
      new Section(rows[y].getValueAt(x), 
                  rows[y].getValueAt(x+1), 
                  rows[y].getValueAt(x+2),
                  rows[y+1].getValueAt(x), 
                  rows[y+1].getValueAt(x+1), 
                  rows[y+1].getValueAt(x+2),
                  rows[y+2].getValueAt(x), 
                  rows[y+2].getValueAt(x+1), 
                  rows[y+2].getValueAt(x+2));
    return result;
  }

  public Collection possibleValues(int row, int col) {
    Collection result = new ArrayList();
    if(isEmpty(row, col)) {
      int old = getValueAt(row, col);
      for (int i = 1; i < 10; i++) {
        setValueAt(row, col, i);
        if (isValid()) {
          result.add(new Integer(i));
        }
      }
      setValueAt(row, col, old);
    }
    return result;
  }
  
  public Board cloneBoard() {
    return new Board(rows[0].cloneSection(),
        rows[1].cloneSection(),
        rows[2].cloneSection(),
        rows[3].cloneSection(),
        rows[4].cloneSection(),
        rows[5].cloneSection(),
        rows[6].cloneSection(),
        rows[7].cloneSection(),
        rows[8].cloneSection());
  }

  public boolean isEmpty(int row, int col) {
    return rows[row].getValueAt(col)==0;
  }

  public int getValueAt(int r, int c) {
    return rows[r].getValueAt(c);
  }

  public void setValueAt(int r, int c, int v) {
    rows[r].setValueAt(c, v);
  }

}

 

Coppia: Matteo/Roberto, Linguaggio: Ruby

 

Ho messo un piccolo report della serata sul mio blog

 

board.rb

class Board

  def initialize(list=nil)
    @list = list.dup
  end
  
  def at(r, c)
    @list[r*9 + c] 
  end
  
  def set(r, c, val)
    @list[r*9 + c] = val
  end
  
  def find_hole
    @list.each_with_index { |e, index|
      return linear_to_r_c(index) if e == 0
    }
    nil
  end
  
  def apply(n)
    r, c = find_hole
    if possible_numbers(r, c).member?(n)
      set(r, c, n)
      return true
    else
      return false
    end
  end

  def forbidden_numbers(r, c)
    result = quad(r, c)
    result += row(r)
    result += col(c)
    result = result.reject { |n| n == 0 }
    result.sort
    result.uniq
  end

  def possible_numbers(r, c)
    Board.complement(forbidden_numbers(r, c))
  end

  def self.complement(ar)
    universe = [1,2,3,4,5,6,7,8,9]
    universe.reject {|x| ar.member?(x) }
  end

  def quad(r, c)
    result = []
    for rr in ((r/3)*3...(r/3)*3+3)
      for cc in ((c/3)*3...(c/3)*3+3)
        result << @list[cc + rr*9]
      end
    end
    result
  end
  
  def row(n)
    @list[n*9...(n+1)*9]
  end

  def col(n)
    result = []
    for r in (0...9)
      result << @list[n + r*9]
    end
    result
  end
  
  def list
    @list
  end
  
  private
  def linear_to_r_c(index)
    [index / 9, index % 9]
  end

end

def do_print(list)
  for rr in (0...9)
    for cc in (0...9)
      print list[rr*9 + cc].to_s + ' '
    end
    print "n"
  end
end

def solve(board)
  if !board.find_hole 
    return board.list
  end
  r, c = board.find_hole
  possibles = board.possible_numbers(r, c)
  for p in possibles
    board.set(r, c, p)
    solved = solve(Board.new(board.list))
    return solved if solved
  end
  return false
end

 

sudoku.rb

require "test/unit"
require "board"

TEST_BOARD = [
  0,   1,  2,  3,  4,  5,  6,  7,  8, 
  9,  10, 11, 12, 13, 14, 15, 16, 17, 
  18, 19, 20, 21, 22, 23, 24, 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, 64, 65, 66, 67, 68, 69, 70, 71, 
  72, 73, 74, 75, 76, 77, 78, 79, 80, 
]

EMPTY_BOARD = Array.new(81, 0)

DIAG_BOARD = [
  1,0,0,0,0,0,0,0,0,
  0,2,0,0,0,0,0,0,0,
  0,0,3,0,0,0,0,0,0,
  0,0,0,4,0,0,0,0,0,
  0,0,0,0,5,0,0,0,0,
  0,0,0,0,0,6,0,0,0,
  0,0,0,0,0,0,7,0,0,
  0,0,0,0,0,0,0,8,0,
  0,0,0,0,0,0,0,0,9,
]

SOLVED_BOARD = [
  8,1,9,6,7,5,3,2,4,
  6,4,2,9,8,3,7,5,1,
  5,3,7,1,2,4,8,6,9,
  4,2,6,5,9,7,1,8,3,
  7,9,5,3,1,8,6,4,2,
  1,8,3,4,6,2,5,9,7,
  3,5,8,7,4,9,2,1,6,
  2,6,4,8,3,1,9,7,5,
  9,7,1,2,5,6,4,3,8,
]

PROBLEM = [
  1, 0, 2, 0, 0, 0, 7, 0, 0,
  0, 4, 7, 0, 2, 1, 3, 0, 0,
  0, 8, 0, 7, 0, 3, 0, 1, 0,
  4, 6, 0, 1, 0, 0, 0, 8, 0,
  0, 0, 0, 2, 6, 4, 0, 0, 0,
  0, 5, 0, 0, 0, 9, 0, 6, 4,
  0, 9, 0, 5, 0, 7, 0, 2, 0,
  0, 0, 1, 3, 4, 0, 9, 7, 0,
  0, 0, 6, 0, 0, 0, 8, 0, 3,
]

class TestNameOfTestCases < Test::Unit::TestCase
  
  def test_board_at
    b = Board.new(SOLVED_BOARD)
    assert_equal b.at(0, 0), 8
    assert_equal b.at(2, 3), 1
  end

  def test_set
    b = Board.new(SOLVED_BOARD)
    b.set(2,3,255)
    assert_equal 255, b.at(2, 3)
  end
  
  def test_board_find_hole
    b = Board.new(SOLVED_BOARD)
    assert_equal nil, b.find_hole
    b.set(1, 2, 0)
    assert_equal [1, 2], b.find_hole
  end

  def test_row_col
    b = Board.new(TEST_BOARD)
    assert_equal [18, 19, 20, 21, 22, 23, 24, 25, 26], b.row(2)
    assert_equal [1, 10, 19, 28, 37, 46, 55, 64, 73],  b.col(1)
    assert_equal [0, 1, 2, 9, 10, 11, 18, 19, 20], b.quad(0, 0)
    assert_equal [0, 1, 2, 9, 10, 11, 18, 19, 20], b.quad(1, 1)
    assert_equal [0, 1, 2, 9, 10, 11, 18, 19, 20], b.quad(2, 2)
    assert_equal [27, 28, 29, 36, 37, 38, 45, 46, 47], b.quad(4, 1)
    assert_equal [30, 31, 32, 39, 40, 41, 48, 49, 50], b.quad(5, 5)
  end
  
  def test_forbidden_numbers_on_quadrant
    assert_equal [], Board.new(EMPTY_BOARD).forbidden_numbers(4, 4)
    assert_equal [1,2,3], Board.new(DIAG_BOARD).forbidden_numbers(0, 1)
  end
  
  def test_forbidden_numbers_on_quad_and_row
    b = Board.new(DIAG_BOARD)
    b.set(0, 4, 4)
    assert_equal [1,2,3,4], b.forbidden_numbers(0, 1)
  end

  def test_forbidden_numbers_on_quad_and_col
    b = Board.new(DIAG_BOARD)
    b.set(4, 0, 5)
    assert_equal [1,2,3,5], b.forbidden_numbers(1, 0)
  end
  
  def test_possible_numbers_on_problem
    b = Board.new(PROBLEM)
    assert_equal [3], b.possible_numbers(0, 1)
  end

  def test_invert
    assert_equal [], Board.complement([1,2,3,4,5,6,7,8,9])
    assert_equal [9], Board.complement([1,2,3,4,5,6,7,8])
    assert_equal [1,4,9], Board.complement([2,3,5,6,7,8])
  end

  def test_solved_board
    b = Board.new(SOLVED_BOARD)
    for r in (0...9)
      for c in (0...9)
        element = b.at(r, c)
        b.set(r, c, 0)
        assert_equal [element], b.possible_numbers(r, c)
        b.set(r, c, element)
      end
    end
  end

  def test_apply
    b = Board.new(SOLVED_BOARD)
    b.set(0, 0, 0)
    assert_equal true, b.apply(8)
    assert_equal 8, b.at(0, 0)

    b.set(0, 0, 0)
    assert_equal false, b.apply(1)
  end

  def test_solve
    b = Board.new(SOLVED_BOARD)
    assert_equal SOLVED_BOARD, solve(b)

    b.set(0,0,0)
    assert_equal SOLVED_BOARD, solve(b)

    b.set(0, 0, 0)
    b.set(0, 1, 0)
    assert_equal SOLVED_BOARD, solve(b)
    
    b.set(0, 0, 0)
    b.set(0, 1, 8)
    assert_equal false, solve(b)
  end

  def test_acceptance
    b = Board.new(PROBLEM)
    assert_equal [3], b.possible_numbers(0, 1)
    do_print(solve(b))
  end

end

Comments (0)

You don't have permission to comment on this page.