Sudoku is a solitaire game involving combinatorics. For the rules visit sudoku.com. According to some mathematician and his computer enumeration there are 9!×722×27×27,704,267,971 different sudoku puzzles - the last factor being prime.
Update: This super brief source code was communicated to me by a math professor.
function Y=sudoku(X)
if ~nargin
X=[
0 2 0 0 3 0 0 4 0
6 0 0 0 0 0 0 0 3
0 0 4 0 0 0 5 0 0
0 0 0 8 0 6 0 0 0
8 0 0 0 1 0 0 0 6
0 0 0 7 0 5 0 0 0
0 0 7 0 0 0 6 0 0
4 0 0 0 0 0 0 0 8
0 3 0 0 4 0 0 2 0
];
end
E=eye(9);
e=eye(3);
O=ones(9);
o=ones(3);
K=kron(E,O)|kron(O,E)|kron(e,kron(o,kron(e,o)));
lhs=X(:)*o(:)';
rhs=O(:)*(1:9);
P=1.0*K*(lhs==rhs);
[m,k]=min(~P*o(:)+10*X(:));
Y=X*(m>9);
E(:)=1:81;
for i=find(m>0 & m<10 & ~P(k,:))
Y=sudoku(X+i*(E==k));
if Y
return
end
end
Below is my own straightforward implementation:
We provide a simple Matlab function sudoku.m to find all solutions to a given sudoku puzzle. Furthermore, the code decides if the puzzle is fiendish, i.e. if branching is necessary.
The code can be naively modified to generate your own puzzles: From an initially full array, successivly delete an entry while the puzzle implies yet uniquely the initially array. Good puzzles are those with few entries given. The current record is 17, i.e. there is a puzzle with 17 initial entries that yet has a unique solution.
Here is the listing of sudoku.m:
function SOLUTIONS=sudoku(PUZZLE)
%Retrieves all solutions to the sudoku given by PUZZLE.
% PUZZLE is a 9x9 matrix with 0's as the missing entries
% SOLUTIONS is a 1xN cell where SOLUTIONS{i} is the i-th solution.
%
%Example: P=[0 4 0 0 0 5 1 0 0
% 5 6 0 0 0 3 0 0 2
% 0 0 2 6 0 8 0 0 4
% 7 0 5 0 0 0 0 3 0
% 0 0 0 0 0 0 0 0 0
% 0 1 0 0 0 0 5 0 7
% 2 0 0 9 0 6 4 0 0
% 3 0 0 8 0 0 0 2 6
% 0 0 6 4 0 0 0 8 0];
% S=sudoku(P);
% then S is a 1x1 cell and
% S{1}=[8 4 7 2 9 5 1 6 3
% 5 6 1 7 4 3 8 9 2
% 9 3 2 6 1 8 7 5 4
% 7 8 5 1 6 4 2 3 9
% 4 2 3 5 7 9 6 1 8
% 6 1 9 3 8 2 5 4 7
% 2 5 8 9 3 6 4 7 1
% 3 7 4 8 5 1 9 2 6
% 1 9 6 4 2 7 3 8 5];
global SOLUTIONS
SOLUTIONS=cell(0);
jisudoku(PUZZLE)
function jisudoku(PUZZLE)
global SOLUTIONS
A=cell(9); num=zeros(9); %---initialize---
[X,Y]=meshgrid([0 0 0 3 3 3 6 6 6],[0 0 0 1 1 1 2 2 2]);
T=X+Y+1;
I=repmat(find(T==1),[1 9])+repmat([0 3 6 27 30 33 54 57 60],[9 1]);
%---list available elements for free entries,
% i.e. unique in row/column/field
for c1=1:numel(PUZZLE)
x=ceil(c1/9);
y=mod(c1-1,9)+1;
if ~PUZZLE(y,x)
A{c1}=1:9;
A{c1}=setdiff(A{c1},PUZZLE(:,x));
A{c1}=setdiff(A{c1},PUZZLE(y,:));
A{c1}=setdiff(A{c1},PUZZLE(I(:,T(y,x))));
end
num(c1)=numel(A{c1});
end
if any(any(~num&~PUZZLE))%---free entry but no available => quit!
return
end
[y,x]=find(num==1); %---exactly one available => put!
if length(x)
for c1=1:length(x)
PUZZLE(y(c1),x(c1))=A{y(c1),x(c1)};
end
jisudoku(PUZZLE);
return
end
cnt=0;
for c1=1:9 %---forall 3x3 fields
u=[];
for c2=I(:,c1)' %----collect availables
u=[u A{c2}];
end
[u,U]=jiunique(u);
if length(intersect(1:9,[u PUZZLE(I(:,c1))']))<9
%---union in field of available & occupied != 1:9 => quit!
return
end
for c3=find(U==1) %---entry with unique available => put!
for c2=I(:,c1)'
if ismember(u(c3),A{c2})
PUZZLE(c2)=u(c3);
cnt=cnt+1;
end
end
end
end
if cnt
jisudoku(PUZZLE);
return
end
if all(all(PUZZLE)) %---found solution
disp('solution')
SOLUTIONS{numel(SOLUTIONS)+1}=PUZZLE;
else
[mv,mp]=min(reshape(num+10*~~PUZZLE,[1 81]));
disp('fiendish')
for c1=A{mp}
PUZZLE(mp)=c1;
jisudoku(PUZZLE);
PUZZLE(mp)=0;
end
end
function [u,U,I,J]=jiunique(x)
[u,I,J]=unique(x);
o=ones(size(x));
U=full(sparse(o,J,o));
Ich habe so lange ein Motivationsproblem,
bis ich ein Zeitproblem habe.