📄 sudokon.m
字号:
[ndg,np,hc] = rm(k,cc(nn),dg,p,gr,hc,action);
[ok,ndg,np] = checkit(ndg,np,gr,hc,action);
if action(1)=='a', p(82,1) = np(82,1); end
if ok, dg = ndg; p = np; return, end
end
end
end
function g = examples(n)
%EXAMPLES provide a sample puzzle
switch n
case 1
mssg = 'this is a simple puzzle, rating 2';
g = [
8 0 0 5 0 0 3 2 0
7 0 3 1 0 0 4 0 0
1 2 0 0 0 9 0 0 8
0 9 0 0 0 0 0 1 0
6 5 0 0 9 3 0 8 0
0 8 0 6 2 0 0 9 3
0 0 6 0 0 8 1 0 2
2 0 0 4 0 0 0 6 7
0 7 4 0 0 6 0 0 5 ] ; % 2 inserts, 1|0|0|2|4; 0
case 2
mssg = 'this is a randomly made up puzzle, rating 3';
g=[0 0 0 0 0 5 3 0 2
7 1 0 3 0 0 8 0 0
0 6 0 0 0 2 0 0 0
0 3 0 0 0 0 0 4 0
2 0 0 4 0 3 0 0 9
0 0 9 0 7 0 0 5 0
9 0 0 6 0 0 0 0 0
0 0 1 0 3 7 0 0 8
0 4 0 0 8 0 0 0 1 ]; % 3 inserts: 2two, 9|4|5|4|6; 0
case 3
mssg = 'this is a medium-simple puzzle, rating 4';
g = [
0 7 8 0 1 0 9 0 4
0 0 0 0 0 0 0 0 0
3 0 2 0 0 0 6 7 0
0 4 0 1 0 9 0 0 7
0 0 6 2 0 8 4 0 0
0 2 0 5 0 3 0 0 8
0 0 1 0 0 0 0 0 0
9 0 0 0 0 0 2 1 0
0 6 7 0 9 0 5 0 3 ]; % 4 inserts: 2two, 8|2|2|4|2;
case 4
mssg = 'this is a medium-hard puzzle, rating 5';
g=[3 9 0 2 0 0 8 0 0
0 0 0 7 0 0 0 2 9
7 0 0 3 0 0 0 5 0
0 0 0 4 1 2 0 0 0
0 0 0 0 0 0 9 3 0
0 5 6 0 0 0 0 0 0
4 1 0 0 0 6 0 0 0
0 7 0 0 0 4 0 0 2
0 0 3 0 0 7 0 8 4]; % 5 inserts: 2two, 12|2|1|3|1;
case 5
mssg = 'this is a medium-hard puzzle, rating 5';
g=[0 8 3 1 0 0 0 5 0
0 0 0 0 0 0 2 6 0
5 0 0 9 4 0 0 0 0
0 0 0 2 0 3 0 0 0
9 7 0 0 0 0 0 0 0
0 0 0 0 0 0 0 7 8
0 4 6 0 0 0 0 0 0
0 0 0 0 8 1 0 0 9
0 3 0 0 0 4 6 1 0 ] ; % 5 inserts, 11|3|2|5|3
case 6
mssg = 'this is a hard puzzle, rating 7';
g=[8 0 0 0 9 0 0 0 0
0 0 0 6 2 0 0 0 0
0 0 0 0 0 1 0 3 9
0 0 0 1 3 0 0 8 0
2 9 7 0 5 0 0 0 0
0 8 0 0 0 0 5 0 0
0 2 0 0 0 0 0 0 0
0 0 0 0 0 0 7 0 1
0 0 3 0 0 7 6 0 5 ] ; % 7 inserts: 2two, 10|5|4|4|2
case 7
mssg = 'this is a hard puzzle, rating 7';
g=[4 6 0 0 0 1 0 0 0
0 0 2 0 9 6 0 0 0
0 3 0 0 0 0 0 6 8
0 0 0 6 0 7 0 0 0
0 0 0 0 0 0 0 3 7
5 1 0 0 0 0 0 0 0
0 0 0 7 1 0 9 0 0
8 4 0 0 0 0 0 5 0
0 0 0 3 0 0 0 2 4 ]; % 7 inserts: 2two, 12|5|4|3|3
case 8
mssg = 'this is a very hard puzzle, rating 8';
g=[0 1 0 0 2 0 0 0 4
0 9 0 0 0 0 5 0 0
0 0 2 0 0 3 0 0 0
2 0 7 1 0 0 8 0 0
0 0 0 0 9 0 2 0 5
0 0 0 7 3 0 0 0 1
1 0 0 0 0 7 0 0 0
0 0 4 0 0 0 6 0 0
0 0 8 0 0 6 0 9 0 ] ; % 8 inserts: 3two, 11|2|1|5|5
case 9
mssg = 'this is a very, very hard puzzle (one fourer), rating 9';
g=[ 3 5 0 0 0 0 6 0 1
2 0 0 0 0 0 5 0 8
0 0 9 0 0 0 0 7 0
5 0 0 2 0 0 0 0 0
0 0 0 0 3 4 0 0 0
8 1 0 0 0 5 0 0 9
0 0 0 0 0 1 8 0 0
0 0 0 0 2 0 0 0 7
1 0 6 3 9 0 0 0 0 ]; % 9 inserts: 1two, 6|3|3|5|5
case 10
mssg = 'this puzzle requires use of the X-wing, rating 9';
g=[0 6 5 0 2 0 0 0 9
0 0 0 4 0 0 0 0 0
7 2 0 0 0 5 0 3 0
0 0 9 0 0 0 3 8 0
2 0 0 0 0 0 0 0 7
0 5 8 0 0 0 2 0 0
0 1 0 7 0 0 0 9 6
0 0 0 0 0 6 0 0 0
6 0 0 0 9 0 8 5 0 ] ; % 9|2|1|4|6
case 11
mssg = 'this puzzle is surprisingly hard, yet rating 5';
g=[0 0 0 0 0 8 0 0 0
6 4 1 3 0 0 0 8 0
0 8 0 0 7 0 1 3 0
4 2 0 0 6 7 0 0 0
0 0 0 2 0 0 4 0 0
0 0 7 0 0 0 0 0 6
0 9 0 0 0 0 0 0 0
5 0 0 0 0 1 0 4 9
0 0 3 4 8 9 0 1 0 ]; % 5 inserts: 12|2|0|5|8
case 12
mssg = 'this puzzle is the hardest here; must guess with only 34 cells settled; rating 12';
g=[0 0 0 1 0 2 3 0 4
0 0 0 0 0 0 0 0 0
0 0 0 5 0 6 1 0 7
6 0 1 0 0 0 7 0 8
0 0 0 0 0 0 0 0 0
8 0 5 0 0 0 4 0 3
5 0 6 2 0 1 0 0 0
0 0 0 0 0 0 0 0 0
2 0 4 6 0 3 0 0 0]; % 3+3+2+1+1+5 inserts: 2two
otherwise
mssg = 'interesting puzzle, rating 7';
g=[0 0 0 0 2 7 0 0 0
1 0 5 0 0 0 0 0 0
0 0 0 0 0 0 0 4 2
0 0 0 0 3 4 0 0 0
9 0 3 7 8 6 0 0 0
0 8 0 0 0 0 4 6 0
0 3 2 0 0 0 5 0 0
0 0 0 3 4 2 0 7 8
0 0 0 0 1 9 0 0 0]; % 7 inserts: 1two, 14|2|3|6|8
end
% now randomize the puzzle, for greater variety. This means choosing, for
% both rows and columns, a permutation that maps a 3-group to a 3-group:
rows = [randperm(3) randperm(3) randperm(3)] + ...
reshape(repmat(3*(randperm(3)-1),3,1),1,9);
cols = [randperm(3) randperm(3) randperm(3)] + ...
reshape(repmat(3*(randperm(3)-1),3,1),1,9);
% ... as well as an arbitrary 9-permutation for permuting the 9 digits
perm9 = [1, randperm(9)+1];
% ... to give the acceptable variation
g(rows,cols) = perm9(g+1)-1;
% ... further `changed' by, possibly, switching to the transposed
perm2 = randperm(2)-1; if perm2(1), g = g.'; end
temp = msgbox(mssg); set(temp,'Tag','sudokon Message Box')
function keyboard(k,hc,p,w)
%KEYBOARD generate a keyboard on cell k
set([hc(82,3),p(82,:)],'Visible','off')
x = [-1 0 1 -1 0 1 -1 0 1]*(w(1)/3)+(hc(k,2)-w(1)/6);
y = [1 1 1 0 0 0 -1 -1 -1]*(w(2)/3)+(hc(k,3)-w(2)/6);
hh = 1:9; if ~hc(85,4), hh(~p(k,:)) = []; end
for j=hh
set(p(82,j),'Visible','on',...
'Position',[x(j),y(j),w/3],...
'Userdata',[k,j]);
end
function [dg,p,hc] = rm(s,ds,dg,p,gr,hc,action)
%RM remove the value ds(j) of the singleton s(j) from all of its groups
for r=1:length(s)
k = s(r);
j = ceil(k/9); i = k - 9*(j-1); % get corresp. col and row index
c = ceil(i/3)+ 3*(ceil(j/3)-1); % get corresp. cell index
d = ds(r); % get the given digit
% zero out that digit in the three groups that k belongs to
p(unique(gr(:,[i j+9 c+18])),d) = 0;
% also zero out all other digits at k, but reintroduce d at k
p(k,:) = 0; p(k,d) = 1;
% update dg
dg(k) = d; hc(k,4) = 1;
if nargin==6 % update the display
set(hc(k,1),'Foregroundcolor','k','Fontsize',30,'Fontweight','bold',...
'String',d)
update(hc,p)
% if this is the ninth of this digit being settled, change their color to
% blue
cds = find(p(1:81,d));
if numel(cds)==9&&all(hc(cds,4)==1)
set(hc(cds,1),'ForegroundColor','b'), end
if ~hc(85,4)&&all(sum(p(1:81,:),2)==1) % there are only singletons left,
% so, for greater pleasure, turn off all cells not yet settled,
% being prepared to turn them on again when a hint is asked for
hc(85,4) = 1;
set(hc(85,1),'Visible','on', ...
'String',{'Only one choice left for each cell;'; ...
get(hc(83,3),'Userdata')})
set(hc(~hc(1:81,4),1),'String','')
end
end
end
function update(hc,p)
%UPDATE update display
if ~hc(85,4) % if we are in help mode
C = repmat(' ',3,5);
for k=1:81
if ~hc(k,4) % only those not yet settled
A = '123456789'; A(~p(k,:)) = ' '; C(:,[1 3 5]) = reshape(A,3,3)';
set(hc(k,1),'String',C,'Fontweight','normal','Foregroundcolor','k')
end
end
end
function [dg,p,hc] = bringback(hst,p,gr,hc)
%BRINGBACK restore to the end of the given HST
p(1:81,:) = 1;
dg = zeros(9,9);
A = reshape('147258369',3,3);
set(hc(1:81,1),'Visible','on','Fontsize',10,'Fontweight','normal',...
'ForegroundColor','k','String',A)
hc([1:81,85],4) = 0;
% enter the givens, if any
s = find(~hst(:,1));
if ~isempty(s)
[dg,p,hc] = rm(hst(s,2),hst(s,3),dg,p,gr,hc);
end
s = find(hst(:,1)==1);
if ~isempty(s)
[dg,p,hc] = rm(hst(s,2),hst(s,3),dg,p,gr,hc);
end
s = find(hst(:,1)==2);
p(hst(s,2)+(hst(s,3)-1)*82) = 0;
update(hc,p)
if ~hc(85,4)
set(hc(85,1),'Visible','on','String',get(hc(84,2),'Userdata'))
end
function setdonot(handle,xy)
%SETDONOT set the do-nothing uicontrol
W = .11;
set(handle,'Position',[xy-W/2,W,W],'Visible','on');
function [pn,mfname,coru] = getfilename(suffix,curbd)
%GETFILENAME get a filename (including directory) for storing stuff
mfname = ['board',num2str(curbd+1),suffix]; coru = ''; curdir = pwd;
if ~(curdir(end)==filesep), curdir = [curdir filesep]; end
getfiletitle = ['Choose a Name for the ',suffix,'-File'];
while isempty(coru)
[mfname,pn] = uiputfile([curdir mfname], getfiletitle);
if isequal(mfname,0)||isequal(pn,0)
% the user hit Cancel, so give up on this
mfname = ''; return
else
checked = 0;
if length(mfname)>2&&isequal(mfname(end-3:end),suffix)
% strip off terminal suffix
mfname(end-3:end) = []; checked = 1;
end
fullfilename = [pn mfname,suffix];
if ~exist(fullfilename, 'file')
coru = 'cre';
else
if checked
anss = 'Yes';
else
anss = questdlg([which(fullfilename),' already exists.';...
' Do you want to replace it?'], ...
[suffix,'-file already exists ...'], 'No','Yes','No');
end
if isequal(anss,'Yes')
coru = 'upd';
end
end
end
end
function groupr = getgroup(r)
%GETGROUP gets text as to what group exactly r represents
if r<10, groupr = ['row ',num2str(r)];
elseif r<19, groupr = ['column ',num2str(r-9)];
else r = r-18; j = ceil(r/3); i = r-3*(j-1);
groupr = ['box ',num2str(i),'|',num2str(j)];
end
function cij = cellid(k)
%CIJ returns the row(s) and column(s) of the given cell(s) k
j = ceil(k/9); i = k - 9*(j-1); % get corresp. col and row index
cij = [i,j];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -