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
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.