September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
273
Task/Sudoku/JavaScript/sudoku-1.js
Normal file
273
Task/Sudoku/JavaScript/sudoku-1.js
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
//-------------------------------------------[ Dancing Links and Algorithm X ]--
|
||||
/**
|
||||
* The doubly-doubly circularly linked data object.
|
||||
* Data object X
|
||||
*/
|
||||
class DoX {
|
||||
/**
|
||||
* @param {string} V
|
||||
* @param {!DoX=} H
|
||||
*/
|
||||
constructor(V, H) {
|
||||
this.V = V;
|
||||
this.L = this;
|
||||
this.R = this;
|
||||
this.U = this;
|
||||
this.D = this;
|
||||
this.S = 1;
|
||||
this.H = H || this;
|
||||
H && (H.S += 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to help build a horizontal doubly linked list.
|
||||
* @param {!DoX} e An existing node in the list.
|
||||
* @param {!DoX} n A new node to add to the right of the existing node.
|
||||
* @return {!DoX}
|
||||
*/
|
||||
const addRight = (e, n) => {
|
||||
n.R = e.R;
|
||||
n.L = e;
|
||||
e.R.L = n;
|
||||
return e.R = n;
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function to help build a vertical doubly linked list.
|
||||
* @param {!DoX} e An existing node in the list.
|
||||
* @param {!DoX} n A new node to add below the existing node.
|
||||
*/
|
||||
const addBelow = (e, n) => {
|
||||
n.D = e.D;
|
||||
n.U = e;
|
||||
e.D.U = n;
|
||||
return e.D = n;
|
||||
};
|
||||
|
||||
/**
|
||||
* Verbatim copy of DK's search algorithm. The meat of the DLX algorithm.
|
||||
* @param {!DoX} h The root node.
|
||||
* @param {!Array<!DoX>} s The solution array.
|
||||
*/
|
||||
const search = function(h, s) {
|
||||
if (h.R == h) {
|
||||
printSol(s);
|
||||
} else {
|
||||
let c = chooseColumn(h);
|
||||
cover(c);
|
||||
for (let r = c.D; r != c; r = r.D) {
|
||||
s.push(r);
|
||||
for (let j = r.R; r !=j; j = j.R) {
|
||||
cover(j.H);
|
||||
}
|
||||
search(h, s);
|
||||
r = s.pop();
|
||||
for (let j = r.R; j != r; j = j.R) {
|
||||
uncover(j.H);
|
||||
}
|
||||
}
|
||||
uncover(c);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Verbatim copy of DK's algorithm for choosing the next column object.
|
||||
* @param {!DoX} h
|
||||
* @return {!DoX}
|
||||
*/
|
||||
const chooseColumn = h => {
|
||||
let s = Number.POSITIVE_INFINITY;
|
||||
let c = h;
|
||||
for(let j = h.R; j != h; j = j.R) {
|
||||
if (j.S < s) {
|
||||
c = j;
|
||||
s = j.S;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Verbatim copy of DK's cover algorithm
|
||||
* @param {!DoX} c
|
||||
*/
|
||||
const cover = c => {
|
||||
c.L.R = c.R;
|
||||
c.R.L = c.L;
|
||||
for (let i = c.D; i != c; i = i.D) {
|
||||
for (let j = i.R; j != i; j = j.R) {
|
||||
j.U.D = j.D;
|
||||
j.D.U = j.U;
|
||||
j.H.S = j.H.S - 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Verbatim copy of DK's cover algorithm
|
||||
* @param {!DoX} c
|
||||
*/
|
||||
const uncover = c => {
|
||||
for (let i = c.U; i != c; i = i.U) {
|
||||
for (let j = i.L; i != j; j = j.L) {
|
||||
j.H.S = j.H.S + 1;
|
||||
j.U.D = j;
|
||||
j.D.U = j;
|
||||
}
|
||||
}
|
||||
c.L.R = c;
|
||||
c.R.L = c;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------[ Print Helpers ]--
|
||||
/**
|
||||
* Given the standard string format of a grid, print a formatted view of it.
|
||||
* @param {!string|!Array} a
|
||||
*/
|
||||
const printGrid = function(a) {
|
||||
|
||||
const getChar = c => {
|
||||
let r = Number(c);
|
||||
if (isNaN(r)) { return c }
|
||||
|
||||
let o = 48;
|
||||
if (r > 9 && r < 36) { o = 55 }
|
||||
if (r >= 36) { o = 61 }
|
||||
return String.fromCharCode(r + o)
|
||||
};
|
||||
|
||||
a = 'string' == typeof a ? a.split('') : a;
|
||||
|
||||
let U = Math.sqrt(a.length);
|
||||
let N = Math.sqrt(U);
|
||||
let line = new Array(N).fill('+').reduce((p, c) => {
|
||||
p.push(... Array.from(new Array(1 + N*2).fill('-')));
|
||||
p.push(c);
|
||||
return p;
|
||||
}, ['\n+']).join('') + '\n';
|
||||
|
||||
a = a.reduce(function(p, c, i) {
|
||||
let d = i && !(i % U), G = i && !(i % N);
|
||||
i = !(i % (U * N));
|
||||
d && !i && (p += '|\n| ');
|
||||
d && i && (p += '|');
|
||||
i && (p = '' + p + line + '| ');
|
||||
return '' + p + (G && !d ? '| ' : '') + getChar(c) + ' ';
|
||||
}, '') + '|' + line;
|
||||
console.log(a);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Given a search solution, print the resultant grid.
|
||||
* @param {!Array<!DoX>} a An array of data objects
|
||||
*/
|
||||
const printSol = a => {
|
||||
printGrid(a.reduce((p, c) => {
|
||||
let [i, v] = c.V.split(':');
|
||||
p[i * 1] = v;
|
||||
return p;
|
||||
}, new Array(a.length).fill('.')));
|
||||
};
|
||||
|
||||
//----------------------------------------------[ Grid to Exact cover Matrix ]--
|
||||
/**
|
||||
* Helper to get some meta about the grid.
|
||||
* @param {!string} s The standard string representation of a grid.
|
||||
* @return {!Array}
|
||||
*/
|
||||
const gridMeta = s => {
|
||||
const g = s.split('');
|
||||
const cellCount = g.length;
|
||||
const tokenCount = Math.sqrt(cellCount);
|
||||
const N = Math.sqrt(tokenCount);
|
||||
const g2D = g.map(e => isNaN(e * 1) ?
|
||||
new Array(tokenCount).fill(1).map((_, i) => i + 1) :
|
||||
[e * 1]);
|
||||
return [cellCount, N, tokenCount, g2D];
|
||||
};
|
||||
|
||||
/**
|
||||
* Given a cell grid index, return the row, column and box indexes.
|
||||
* @param {!number} n The n-value of the grid. 3 for a 9x9 sudoku.
|
||||
* @return {!function(!number): !Array<!number>}
|
||||
*/
|
||||
const indexesN = n => i => {
|
||||
let c = Math.floor(i / (n * n));
|
||||
i %= n * n;
|
||||
return [c, i, Math.floor(c / n) * n + Math.floor(i / n)];
|
||||
};
|
||||
|
||||
/**
|
||||
* Given a puzzle string, reduce it to an exact-cover matrix and use
|
||||
* Donald Knuth's DLX algorithm to solve it.
|
||||
* @param puzString
|
||||
*/
|
||||
const reduceGrid = puzString => {
|
||||
|
||||
printGrid(puzString);
|
||||
const [
|
||||
numCells, // The total number of cells in a grid (81 for a 9x9 grid)
|
||||
N, // the 'n' value of the grid. (3 for a 9x9 grid)
|
||||
U, // The total number of unique tokens to be placed.
|
||||
g2D // A 2D array representation of the grid, with each element
|
||||
// being an array of candidates for a cell. Known cells are
|
||||
// single element arrays.
|
||||
] = gridMeta(puzString);
|
||||
|
||||
const getIndex = indexesN(N);
|
||||
|
||||
/**
|
||||
* The DLX Header row.
|
||||
* Its length is 4 times the grid's size. This is to be able to encode
|
||||
* each of the 4 Sudoku constrains, onto each of the cells of the grid.
|
||||
* The array is initialised with unlinked DoX nodes, but in the next step
|
||||
* those nodes are all linked.
|
||||
* @type {!Array.<!DoX>}
|
||||
*/
|
||||
const headRow = new Array(4 * numCells)
|
||||
.fill('')
|
||||
.map((_, i) => new DoX(`H${i}`));
|
||||
|
||||
/**
|
||||
* The header row root object. This is circularly linked to be to the left
|
||||
* of the first header object in the header row array.
|
||||
* It is used as the entry point into the DLX algorithm.
|
||||
* @type {!DoX}
|
||||
*/
|
||||
let H = new DoX('ROOT');
|
||||
headRow.reduce((p, c) => addRight(p, c), H);
|
||||
|
||||
/**
|
||||
* Transposed the sudoku puzzle into a exact cover matrix, so it can be passed
|
||||
* to the DLX algorithm to solve.
|
||||
*/
|
||||
for (let i = 0; i < numCells; i++) {
|
||||
const [ri, ci, bi] = getIndex(i);
|
||||
g2D[i].forEach(num => {
|
||||
let id = `${i}:${num}`;
|
||||
let candIdx = num - 1;
|
||||
|
||||
// The 4 columns that we will populate.
|
||||
const A = headRow[i];
|
||||
const B = headRow[numCells + candIdx + (ri * U)];
|
||||
const C = headRow[(numCells * 2) + candIdx + (ci * U)];
|
||||
const D = headRow[(numCells * 3) + candIdx + (bi * U)];
|
||||
|
||||
// The Row-Column Constraint
|
||||
let rcc = addBelow(A.U, new DoX(id, A));
|
||||
|
||||
// The Row-Number Constraint
|
||||
let rnc = addBelow(B.U, addRight(rcc, new DoX(id, B)));
|
||||
|
||||
// The Column-Number Constraint
|
||||
let cnc = addBelow(C.U, addRight(rnc, new DoX(id, C)));
|
||||
|
||||
// The Block-Number Constraint
|
||||
addBelow(D.U, addRight(cnc, new DoX(id, D)));
|
||||
});
|
||||
}
|
||||
search(H, []);
|
||||
};
|
||||
25
Task/Sudoku/JavaScript/sudoku-2.js
Normal file
25
Task/Sudoku/JavaScript/sudoku-2.js
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
[
|
||||
'819..5.....2...75..371.4.6.4..59.1..7..3.8..2..3.62..7.5.7.921..64...9.....2..438',
|
||||
'53..247....2...8..1..7.39.2..8.72.49.2.98..7.79.....8.....3.5.696..1.3...5.69..1.',
|
||||
'..3.2.6..9..3.5..1..18.64....81.29..7.......8..67.82....26.95..8..2.3..9..5.1.3..',
|
||||
'394..267....3..4..5..69..2..45...9..6.......7..7...58..1..67..8..9..8....264..735',
|
||||
'97.3...6..6.75.........8.5.......67.....3.....539..2..7...25.....2.1...8.4...73..',
|
||||
'4......6.5...8.9..3....1....2.7....1.9.....4.8....3.5....2....7..6.5...8.1......6',
|
||||
'85...24..72......9..4.........1.7..23.5...9...4...........8..7..17..........36.4.',
|
||||
'..1..5.7.92.6.......8...6...9..2.4.1.........3.4.8..9...7...3.......7.69.1.8..7..',
|
||||
'.9...4..7.....79..8........4.58.....3.......2.....97.6........4..35.....2..6...8.',
|
||||
'12.3....435....1....4........54..2..6...7.........8.9...31..5.......9.7.....6...8',
|
||||
'9..2..5...4..6..3...3.....6...9..2......5..8...7..4..37.....1...5..2..4...1..6..9',
|
||||
'1....7.9..3..2...8..96..5....53..9...1..8...26....4...3......1..4......7..7...3..',
|
||||
'12.4..3..3...1..5...6...1..7...9.....4.6.3.....3..2...5...8.7....7.....5.......98',
|
||||
'..............3.85..1.2.......5.7.....4...1...9.......5......73..2.1........4...9',
|
||||
'.......39.....1..5..3.5.8....8.9...6.7...2...1..4.......9.8..5..2....6..4..7.....',
|
||||
'....839..1......3...4....7..42.3....6.......4....7..1..2........8...92.....25...6',
|
||||
'..3......4...8..36..8...1...4..6..73...9..........2..5..4.7..686........7..6..5..'
|
||||
].forEach(reduceGrid);
|
||||
|
||||
// Or of you want to create all the grids of a particular n-size.
|
||||
// I run out of stack space at n = 9
|
||||
let n = 2;
|
||||
let s = new Array(Math.pow(n, 4)).fill('.').join('');
|
||||
reduceGrid(s);
|
||||
67
Task/Sudoku/Julia/sudoku.julia
Normal file
67
Task/Sudoku/Julia/sudoku.julia
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
function check(i, j)
|
||||
id, im = div(i, 9), mod(i, 9)
|
||||
jd, jm = div(j, 9), mod(j, 9)
|
||||
|
||||
jd == id && return true
|
||||
jm == im && return true
|
||||
|
||||
div(id, 3) == div(jd, 3) &&
|
||||
div(jm, 3) == div(im, 3)
|
||||
end
|
||||
|
||||
const lookup = zeros(Bool, 81, 81)
|
||||
|
||||
for i in 1:81
|
||||
for j in 1:81
|
||||
lookup[i,j] = check(i-1, j-1)
|
||||
end
|
||||
end
|
||||
|
||||
function solve_sudoku(callback::Function, grid::Array{Int64})
|
||||
(function solve()
|
||||
for i in 1:81
|
||||
if grid[i] == 0
|
||||
t = Dict{Int64, Void}()
|
||||
|
||||
for j in 1:81
|
||||
if lookup[i,j]
|
||||
t[grid[j]] = nothing
|
||||
end
|
||||
end
|
||||
|
||||
for k in 1:9
|
||||
if !haskey(t, k)
|
||||
grid[i] = k
|
||||
solve()
|
||||
end
|
||||
end
|
||||
|
||||
grid[i] = 0
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
callback(grid)
|
||||
end)()
|
||||
end
|
||||
|
||||
function display(grid)
|
||||
for i in 1:length(grid)
|
||||
print(grid[i], " ")
|
||||
i % 3 == 0 && print(" ")
|
||||
i % 9 == 0 && print("\n")
|
||||
i % 27 == 0 && print("\n")
|
||||
end
|
||||
end
|
||||
|
||||
grid = Int64[5, 3, 0, 0, 2, 4, 7, 0, 0,
|
||||
0, 0, 2, 0, 0, 0, 8, 0, 0,
|
||||
1, 0, 0, 7, 0, 3, 9, 0, 2,
|
||||
0, 0, 8, 0, 7, 2, 0, 4, 9,
|
||||
0, 2, 0, 9, 8, 0, 0, 7, 0,
|
||||
7, 9, 0, 0, 0, 0, 0, 8, 0,
|
||||
0, 0, 0, 0, 3, 0, 5, 0, 6,
|
||||
9, 6, 0, 0, 1, 0, 3, 0, 0,
|
||||
0, 5, 0, 6, 9, 0, 0, 1, 0]
|
||||
|
||||
solve_sudoku(display, grid)
|
||||
173
Task/Sudoku/Scilab/sudoku.scilab
Normal file
173
Task/Sudoku/Scilab/sudoku.scilab
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
Init_board=[...
|
||||
5 3 0 0 7 0 0 0 0;...
|
||||
6 0 0 1 9 5 0 0 0;...
|
||||
0 9 8 0 0 0 0 6 0;...
|
||||
8 0 0 0 6 0 0 0 3;...
|
||||
4 0 0 8 0 3 0 0 1;...
|
||||
7 0 0 0 2 0 0 0 6;...
|
||||
0 6 0 0 0 0 2 8 0;...
|
||||
0 0 0 4 1 9 0 0 5;...
|
||||
0 0 0 0 8 0 0 7 9];
|
||||
|
||||
break_point=1.0d5; //if 0 there will be no break
|
||||
|
||||
function []=disp_board(board)
|
||||
StringBoard=string(board);
|
||||
for i=1:9
|
||||
for j=1:9
|
||||
if board(i,j)==0 then
|
||||
StringBoard(i,j)='×';
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
StringBoard=[StringBoard, string(zeros(9,2))];
|
||||
StringBoard=[StringBoard; string(zeros(2,11))];
|
||||
|
||||
for i=1:9
|
||||
StringBoard(i,:)=[StringBoard(i,1:3), '|', StringBoard(i,4:6), '|', StringBoard(i,7:9)]
|
||||
end
|
||||
StringBoard(9:11,:)=StringBoard(7:9,:);
|
||||
StringBoard(8,:)=strsplit('-----------');
|
||||
StringBoard(5:7,:)=StringBoard(4:6,:);
|
||||
StringBoard(4,:)=strsplit('-----------');
|
||||
|
||||
disp(StringBoard)
|
||||
endfunction
|
||||
|
||||
function varargout=validate_input(input,position,board)
|
||||
row=board(position(1),:);
|
||||
column=board(:,position(2));
|
||||
block=zeros(3,3);
|
||||
if position(1)>=1 & position(1)<=3 then
|
||||
i=0;
|
||||
elseif position(1)>=4 & position(1)<=6 then
|
||||
i=3;
|
||||
else
|
||||
i=6;
|
||||
end
|
||||
if position(2)>=1 & position(2)<=3 then
|
||||
j=0;
|
||||
elseif position(2)>=4 & position(2)<=6 then
|
||||
j=3;
|
||||
else
|
||||
j=6;
|
||||
end
|
||||
block=board(i+1:i+3,j+1:j+3)
|
||||
|
||||
valid_input=%F;
|
||||
valid_row=%F;
|
||||
valid_col=%F;
|
||||
valid_block=%F;
|
||||
|
||||
if find(input==row)==[] then
|
||||
valid_row=%T;
|
||||
end
|
||||
if find(input==column)==[] then
|
||||
valid_col=%T;
|
||||
end
|
||||
if find(input==block)==[] then
|
||||
valid_block=%T;
|
||||
end
|
||||
if valid_row & valid_col & valid_block then
|
||||
valid_input=%T;
|
||||
end
|
||||
|
||||
varargout=list(valid_input,valid_row,valid_col,valid_block)
|
||||
endfunction
|
||||
|
||||
function varargout=validate_board(board)
|
||||
valid_flag1=%T;
|
||||
for i=1:9
|
||||
for j=1:9
|
||||
if board(i,j)~= 0 then
|
||||
check_board=Init_board;
|
||||
check_board(i,j)=0;
|
||||
valid_flag1=validate_input(board(i,j),[i j],check_board);
|
||||
if ~valid_flag1 then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if ~valid_flag1 then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
valid_flag2 = (length( find(board) ) >= 17); //enforces rule of minimum of 17 givens
|
||||
//set it to always %T to ignore this rule
|
||||
valid_board = (valid_flag1 & valid_flag2);
|
||||
|
||||
varargout=list(valid_board)
|
||||
endfunction
|
||||
|
||||
disp('Initial board:');
|
||||
disp_board(Init_board);
|
||||
|
||||
valid_init_board=validate_board(Init_board);
|
||||
|
||||
if ~valid_init_board then
|
||||
error('Invalid initial board. Should follow sudoku rules and have at least 17 clues.');
|
||||
end
|
||||
|
||||
blank=[];
|
||||
for i=1:9
|
||||
for j=1:9
|
||||
if Init_board(i,j)== 0 then
|
||||
blank=[blank; i j];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Solved_board=Init_board;
|
||||
|
||||
tic();
|
||||
i=0; counter=0; breaked=%F;
|
||||
while i<size(blank,'r')
|
||||
i=i+1;
|
||||
counter=counter+1;
|
||||
pos=blank(i,:);
|
||||
|
||||
value=Solved_board(pos(1),pos(2));
|
||||
|
||||
valid_value=%F;
|
||||
|
||||
while valid_value==%F
|
||||
value=value+1;
|
||||
if value>=10
|
||||
break
|
||||
else
|
||||
valid_value=validate_input(value,pos,Solved_board);
|
||||
end
|
||||
end
|
||||
|
||||
if valid_value & value<10 then
|
||||
Solved_board(pos(1),pos(2))=value
|
||||
else
|
||||
Solved_board(pos(1),pos(2))=0;
|
||||
i=i-2;
|
||||
end
|
||||
|
||||
if counter==break_point
|
||||
breaked=%T;
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
valid_solved_board=validate_board(Solved_board);
|
||||
t2=toc();
|
||||
|
||||
if valid_solved_board & ~breaked then
|
||||
disp('Solved!');
|
||||
disp('Solution:');
|
||||
disp_board(Solved_board);
|
||||
disp('Time: '+string(t2)+'s.');
|
||||
disp('Steps: '+string(counter)+'.');
|
||||
elseif breaked
|
||||
disp('Break point reached.');
|
||||
disp('Time: '+string(t2)+'s.');
|
||||
disp_board(Solved_board);
|
||||
elseif ~valid_solved_board & ~breaked
|
||||
disp('Invalid solution found.');
|
||||
disp_board(Solved_board);
|
||||
end
|
||||
|
|
@ -5,38 +5,34 @@ func check(i, j) is cached {
|
|||
jd == id && return true
|
||||
jm == im && return true
|
||||
|
||||
var id2 = id//3
|
||||
var jd2 = jd//3
|
||||
|
||||
jd2 == id2 || return false
|
||||
|
||||
jm//3 == im//3
|
||||
(id//3 == jd//3) &&
|
||||
(jm//3 == im//3)
|
||||
}
|
||||
|
||||
func solve(board) {
|
||||
for i in ^board {
|
||||
board[i] && next
|
||||
var *t = board[^board -> grep {|j| check(i, j) }]
|
||||
func solve(grid) {
|
||||
for i in ^grid {
|
||||
grid[i] && next
|
||||
var t = [grid[{|j| check(i, j) }.grep(^grid)]].freq
|
||||
|
||||
{ |k|
|
||||
t.contains(k) && next
|
||||
board[i] = k
|
||||
solve(board)
|
||||
} * 9
|
||||
t.has_key(k) && next
|
||||
grid[i] = k
|
||||
solve(grid)
|
||||
} << 1..9
|
||||
|
||||
board[i] = 0
|
||||
grid[i] = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
for i in ^board {
|
||||
print "#{board[i]} ";
|
||||
for i in ^grid {
|
||||
print "#{grid[i]} "
|
||||
print " " if (3 -> divides(i+1))
|
||||
print "\n" if (9 -> divides(i+1))
|
||||
print "\n" if (27 -> divides(i+1))
|
||||
}
|
||||
}
|
||||
|
||||
var board = %i(
|
||||
var grid = %i(
|
||||
5 3 0 0 2 4 7 0 0
|
||||
0 0 2 0 0 0 8 0 0
|
||||
1 0 0 7 0 3 9 0 2
|
||||
|
|
@ -50,4 +46,4 @@ var board = %i(
|
|||
0 5 0 6 9 0 0 1 0
|
||||
)
|
||||
|
||||
solve(board)
|
||||
solve(grid)
|
||||
|
|
|
|||
|
|
@ -111,7 +111,6 @@ let board = [
|
|||
[4, 0, 0, 0, 0, 0, 0, 6, 0],
|
||||
[5, 0, 0, 0, 8, 0, 9, 0, 0],
|
||||
[3, 0, 0, 0, 0, 1, 0, 0, 0],
|
||||
|
||||
[0, 2, 0, 7, 0, 0, 0, 0, 1],
|
||||
[0, 9, 0, 0, 0, 0, 0, 4, 0],
|
||||
[8, 0, 0, 0, 0, 3, 0, 5, 0],
|
||||
64
Task/Sudoku/Swift/sudoku-2.swift
Normal file
64
Task/Sudoku/Swift/sudoku-2.swift
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
func solving(board: [[Int]]) -> [[Int]] {
|
||||
var board = board
|
||||
var isSolved = false
|
||||
while !isSolved {
|
||||
for x in 0 ..< 9 {
|
||||
for y in 0 ..< 9 {
|
||||
if board[x][y] == 0 {
|
||||
let known = Set(board.map { $0[y] } + board[x] + subgrid(board, pos: (x, y)))
|
||||
let possible = Set(Array(1...9)).subtracting(known)
|
||||
if possible.count == 1 {
|
||||
board[x][y] = possible.first!
|
||||
}
|
||||
}
|
||||
}
|
||||
isSolved = 45 == board[x].reduce(0, +)
|
||||
}
|
||||
}
|
||||
return board
|
||||
}
|
||||
|
||||
func subgrid(_ board: [[Int]], pos: (Int, Int)) -> [Int] {
|
||||
var r = [Int]()
|
||||
var (x, y) = pos
|
||||
x = x / 3 * 3
|
||||
y = y / 3 * 3
|
||||
for i in x ..< x + 3 {
|
||||
for j in y ..< y + 3 {
|
||||
r.append(board[i][j])
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func print(_ board: [[Int]]) {
|
||||
for i in board.indices {
|
||||
if i % 9 == 0 {
|
||||
print(" -------------------")
|
||||
}
|
||||
for j in board.indices {
|
||||
if j % board.count == 0 {
|
||||
print("| ", terminator: "")
|
||||
}
|
||||
let digit = board[i][j]
|
||||
print(digit != 0 ? digit : " ", terminator: "")
|
||||
print(" ", terminator: "")
|
||||
}
|
||||
print("|")
|
||||
}
|
||||
print(" -------------------")
|
||||
}
|
||||
|
||||
let puzzle = [
|
||||
[0,2,0,4,5,0,7,0,9],
|
||||
[0,0,0,1,0,9,0,3,0],
|
||||
[0,0,8,0,0,0,1,0,4],
|
||||
[0,4,0,0,6,1,0,7,0],
|
||||
[5,0,6,0,3,0,0,1,0],
|
||||
[0,3,0,0,0,2,0,9,0],
|
||||
[3,0,4,0,7,5,0,6,8],
|
||||
[0,9,0,0,1,0,3,0,7],
|
||||
[0,0,2,0,0,3,0,0,1]
|
||||
]
|
||||
|
||||
print(solving(board: puzzle))
|
||||
132
Task/Sudoku/SystemVerilog/sudoku.v
Normal file
132
Task/Sudoku/SystemVerilog/sudoku.v
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
/// @Author: Alexandre Felipe (o.alexandre.felipe@gmail.com)
|
||||
/// @Date: 2017-May-10
|
||||
///
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// SudokuSolver ///
|
||||
/// A class that fills up a sudoku board, the initial board is given ///
|
||||
/// as an array preset_rows, the positions where preset_rows is zero ///
|
||||
/// are to be determined. Three views of the sudoku board are created ///
|
||||
/// and the uniqueness of its elements are defined by on constraint for ///
|
||||
/// each view, one constraint ensures that the values are between 1 and ///
|
||||
/// 9, and two other constraints are used to ensure that the values in ///
|
||||
/// all three views agree to each other. ///
|
||||
/// ///
|
||||
/// ///
|
||||
/// A solution using only the "rows" array would be possible, however ///
|
||||
/// this illustrates better how one can relate different variables in ///
|
||||
/// SystemVerilog Constrained randomization. ///
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
class SudokuSolver;
|
||||
rand int tiles[0:8][0:8];
|
||||
rand int rows[0:8][0:8];
|
||||
rand int cols[0:8][0:8];
|
||||
int preset_rows[0:8][0:8];
|
||||
constraint board_input {
|
||||
foreach(preset_rows[i])foreach(preset_rows[i][j])
|
||||
if(preset_rows[i][j] != 0) rows[i][j] == preset_rows[i][j];
|
||||
}
|
||||
constraint range {
|
||||
foreach(rows[i]) foreach(rows[i][j])
|
||||
rows[i][j] inside {[1:9]};
|
||||
}
|
||||
////////////////////////////////////////////////
|
||||
/// Every number in a row is unique ///
|
||||
////////////////////////////////////////////////
|
||||
constraint rows_permutation {
|
||||
foreach(rows[i]) foreach(rows[i][j1])
|
||||
foreach(rows[i][j2])
|
||||
if(j1 != j2) rows[i][j1] != rows[i][j2];
|
||||
}
|
||||
///////////////////////////////////////////////
|
||||
/// Every number in a column is unique ///
|
||||
///////////////////////////////////////////////
|
||||
constraint cols_permutation {
|
||||
foreach(cols[i]) foreach(cols[i][j1])
|
||||
foreach(cols[i][j2])
|
||||
if(j1 != j2) cols[i][j1] != cols[i][j2];
|
||||
}
|
||||
/////////////////////////////////////////////////
|
||||
/// Every number in a tile (square) is unique ///
|
||||
/////////////////////////////////////////////////
|
||||
constraint tiles_permutation {
|
||||
foreach(tiles[i]) foreach(tiles[i][j1])
|
||||
foreach(tiles[i][j2])
|
||||
if(j1 != j2) tiles[i][j1] != tiles[i][j2];
|
||||
}
|
||||
///////////////////////////////////////////////////
|
||||
/// Makes sure that sure that the numbers in ///
|
||||
/// each view agree with other views ///
|
||||
///////////////////////////////////////////////////
|
||||
constraint rows_vs_tiles {
|
||||
foreach(tiles[i]) foreach(tiles[i][j])
|
||||
tiles[i][j] == rows[(i/3) * 3 + (j/3)][3*(i%3)+(j%3)];
|
||||
}
|
||||
constraint rows_vs_cols {
|
||||
foreach(cols[i]) foreach(cols[i][j])
|
||||
cols[i][j] == rows[j][i];
|
||||
}
|
||||
///////////////////////////////////////////////////
|
||||
/// Print the current state of the board in the ///
|
||||
/// standard output ///
|
||||
///////////////////////////////////////////////////
|
||||
function void printBoard;
|
||||
int i, j;
|
||||
for(i = 0; i < 9; ++i) begin
|
||||
if(i % 3 == 0)$display(" -------------");
|
||||
$write(" ");
|
||||
for(j = 0; j < 9; ++j) begin
|
||||
if(j % 3 == 0) $write("|");
|
||||
$write("%c", "0" + rows[i][j]);
|
||||
end
|
||||
$display("|");
|
||||
end
|
||||
$display(" -------------");
|
||||
endfunction
|
||||
function void printInitial;
|
||||
int i, j;
|
||||
for(i = 0; i < 9; ++i) begin
|
||||
if(i % 3 == 0)$display("-------------");
|
||||
for(j = 0; j < 9; ++j) begin
|
||||
if(j % 3 == 0) $write("|");
|
||||
if(preset_rows[i][j]) begin
|
||||
$write("%c", "0" + preset_rows[i][j]);
|
||||
end
|
||||
else begin
|
||||
$write(".");
|
||||
end
|
||||
end
|
||||
$display("|");
|
||||
end
|
||||
$display("-------------");
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
/// Simple program instantiating the sudoku object ///
|
||||
//////////////////////////////////////////////////////
|
||||
program SudokuTest;
|
||||
SudokuSolver board;
|
||||
initial begin
|
||||
board = new;
|
||||
foreach(board.preset_rows[0][i]) board.preset_rows[i][i] = i+1;
|
||||
$display("Initial Board:");
|
||||
board.printInitial();
|
||||
// Generate two different solutions for the board
|
||||
if(board.randomize())begin
|
||||
$display("One solution:");
|
||||
board.printBoard();
|
||||
end
|
||||
else begin
|
||||
$display("ERROR: Failed to generate first solution");
|
||||
end
|
||||
if(board.randomize())begin
|
||||
$display("Another solution:");
|
||||
board.printBoard();
|
||||
end
|
||||
else begin
|
||||
$display("ERROR: Failed to generate second solution");
|
||||
end
|
||||
end
|
||||
endprogram
|
||||
22
Task/Sudoku/Zkl/sudoku-1.zkl
Normal file
22
Task/Sudoku/Zkl/sudoku-1.zkl
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
fcn trycell(sdku,pos=0){
|
||||
row,col:=pos/9, pos%9;
|
||||
|
||||
if(pos==81) return(True);
|
||||
if(sdku[pos]) return(trycell(sdku, pos + 1));
|
||||
|
||||
used:=0;
|
||||
foreach r in (9){ used=used.bitOr((1).shiftLeft(sdku[r*9 + col] - 1)) }
|
||||
foreach c in (9){ used=used.bitOr((1).shiftLeft(sdku[row*9 + c] - 1)) }
|
||||
|
||||
row,col = row/3*3, col/3*3;
|
||||
foreach r,c in ([row..row+2], [col..col+2])
|
||||
{ used=used.bitOr((1).shiftLeft(sdku[r*9 + c] - 1)) }
|
||||
|
||||
sdku[pos]=1; while(sdku[pos]<=9){
|
||||
if(used.isEven and trycell(sdku, pos + 1)) return(True);
|
||||
sdku[pos]+=1; used/=2;
|
||||
}
|
||||
|
||||
sdku[pos]=0;
|
||||
return(False);
|
||||
}
|
||||
19
Task/Sudoku/Zkl/sudoku-2.zkl
Normal file
19
Task/Sudoku/Zkl/sudoku-2.zkl
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
problem:=
|
||||
#<<<
|
||||
" 5 3 0 0 7 0 0 0 0
|
||||
6 0 0 1 9 5 0 0 0
|
||||
0 9 8 0 0 0 0 6 0
|
||||
8 0 0 0 6 0 0 0 3
|
||||
4 0 0 8 0 3 0 0 1
|
||||
7 0 0 0 2 0 0 0 6
|
||||
0 6 0 0 0 0 2 8 0
|
||||
0 0 0 4 1 9 0 0 5
|
||||
0 0 0 0 8 0 0 7 9";
|
||||
#<<<
|
||||
s:=problem.split().apply("toInt").copy(); // writable list of 81 ints
|
||||
trycell(s).println();
|
||||
println("+-----+-----+-----+");
|
||||
foreach n in (3){
|
||||
s[n*27,27].pump(Console.println,T(Void.Read,8),("| " + "%s%s%s | "*3).fmt); // 3 lines
|
||||
println("+-----+-----+-----+");
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue