From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- macros/latex/contrib/sudokubundle/README | 73 + macros/latex/contrib/sudokubundle/sudokubundle.dtx | 4794 ++++++++++++++++++++ macros/latex/contrib/sudokubundle/sudokubundle.ins | 83 + macros/latex/contrib/sudokubundle/sudokubundle.pdf | Bin 0 -> 350052 bytes 4 files changed, 4950 insertions(+) create mode 100644 macros/latex/contrib/sudokubundle/README create mode 100644 macros/latex/contrib/sudokubundle/sudokubundle.dtx create mode 100644 macros/latex/contrib/sudokubundle/sudokubundle.ins create mode 100644 macros/latex/contrib/sudokubundle/sudokubundle.pdf (limited to 'macros/latex/contrib/sudokubundle') diff --git a/macros/latex/contrib/sudokubundle/README b/macros/latex/contrib/sudokubundle/README new file mode 100644 index 0000000000..5f28daa93e --- /dev/null +++ b/macros/latex/contrib/sudokubundle/README @@ -0,0 +1,73 @@ + The sudoku bundle provides the printsudoku, solvesudoku and createsudoku +coordinated set of packages for typesetting, solving, and creating Sudoku +puzzles. Over 50 puzzles are also supplied. + + If there are any questions please ask them on the comp.text.tex newsgroup. + +CHANGES +sudokubundle.dtx v1.0a (2006/02/19) +o Deleted a clue from the example puzzle, no package changes. + +printsudoku.sty v1.0 (2006/02/16) +o First public release + +solvesudoku.sty v1.0 (2006/02/16) +o First public release + +createsudoku.sty v1.0 (2006/02/16) +o First public release + +somesudoku.tex (2006/02/16) +o First public release + +------------------------------------------------------------------ + Author: Peter Wilson (Herries Press) herries dot press at earthlink dot net + Copyright 2006 Peter R. Wilson + + This work may be distributed and/or modified under the + conditions of the Latex Project Public License, either + version 1.3 of this license or (at your option) any + later version. + The latest version of the license is in + http://www.latex-project.org/lppl.txt + and version 1.3 or later is part of all distributions of + LaTeX version 2003/06/01 or later. + + This work has the LPPL maintenance status "author-maintained". + + This work consists of the files: + README (this file) + sudokubundle.dtx + sudokubundle.ins + sudokubundle.pdf + and the derived files + printsudoku.sty + solvesudoku.sty + createsudoku.sty + somesudoku.tex + +------------------------------------------------------------------ + The distribution consists of the following files: +README (this file) +sudokubundle.dtx +sudokubundle.ins + + To install the sudoku bundle: +o run: latex sudokubundle.ins (which will generate printsudoku.sty, + solvesudoku.sty and createsudoku.sty, and also somesudoku.tex) +o Move the .sty files to a location where LaTeX will find them (for more + information on this see the FAQ). +o Run LaTeX on somesudoku.tex to typeset a collection of puzzles, plus + their answers. Be aware that this will lead to a large number of small + *.sud and *.ans files being created. + + To generate a second copy of the manual (which is already supplied as a PDF file): +o run: latex *.dtx +o (for an index run: makeindex -s gind.ist *.idx) +o run: latex *.dtx +o Print *.dvi for a hardcopy of the package manual + +2006/02/19 +Peter Wilson +herries dot press at earthlink dot net + diff --git a/macros/latex/contrib/sudokubundle/sudokubundle.dtx b/macros/latex/contrib/sudokubundle/sudokubundle.dtx new file mode 100644 index 0000000000..6f64a98203 --- /dev/null +++ b/macros/latex/contrib/sudokubundle/sudokubundle.dtx @@ -0,0 +1,4794 @@ +% \iffalse meta-comment +% +% sudokubundle.dtx +% +% Author: Peter Wilson (Herries Press) herries dot press at earthlink dot net +% Copyright 2006 Peter R. Wilson +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either +% version 1.3 of this license or (at your option) any +% later version. +% The latest version of the license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of +% LaTeX version 2003/06/01 or later. +% +% This work has the LPPL maintenance status "author-maintained". +% +% This work consists of the files listed in the README file. +% +%<*driver> +\documentclass[twoside]{ltxdoc} +\usepackage{printsudoku} +\usepackage{url} +\usepackage[draft=false, + plainpages=false, + pdfpagelabels, + bookmarksnumbered, + hyperindex=false + ]{hyperref} +\makeatletter + \@mparswitchfalse +\makeatother +\EnableCrossrefs +\CodelineIndex +%%% \RecordChanges +%%%%%%%%%%%%% uncomment the next line to show all the code details +%%\OnlyDescription +%%% Don't use the default Short Verb. +\AtBeginDocument{\DeleteShortVerb{\|}} +%%% page headings to aid navigation, but I don't like Uppercased titles. +\renewcommand{\MakeUppercase}[1]{#1} +\pagestyle{headings} +\setcounter{StandardModuleDepth}{1} +\begin{document} + \DocInput{sudokubundle.dtx} +\end{document} +% +% +% \fi +% +% \CheckSum{5494} +% +% \DoNotIndex{\',\.,\@M,\@@input,\@addtoreset,\@arabic,\@badmath} +% \DoNotIndex{\@centercr,\@cite} +% \DoNotIndex{\@dotsep,\@empty,\@gobble,\@gobbletwo,\@ignoretrue} +% \DoNotIndex{\@input,\@ixpt,\@m} +% \DoNotIndex{\@minus,\@ne,\@nil,\@nomath,\@plus,\@set@topoint} +% \DoNotIndex{\@tempboxa,\@tempcnta,\@tempdima,\@tempdimb} +% \DoNotIndex{\@tempswafalse,\@tempswatrue,\@viipt,\@viiipt,\@vipt} +% \DoNotIndex{\@vpt,\@warning,\@xiipt,\@xipt,\@xivpt,\@xpt,\@xviipt} +% \DoNotIndex{\@xxpt,\@xxvpt,\\,\ ,\addpenalty,\addtolength,\addvspace} +% \DoNotIndex{\advance,\Alph,\alph} +% \DoNotIndex{\arabic,\ast,\begin,\begingroup,\bfseries,\bgroup,\box} +% \DoNotIndex{\bullet} +% \DoNotIndex{\cdot,\cite,\CodelineIndex,\cr,\day,\DeclareOption} +% \DoNotIndex{\def,\DisableCrossrefs,\divide,\DocInput,\documentclass} +% \DoNotIndex{\DoNotIndex,\egroup,\ifdim,\else,\fi,\em,\endtrivlist} +% \DoNotIndex{\EnableCrossrefs,\end,\endgroup} +% \DoNotIndex{\endlist,\everycr,\everypar,\ExecuteOptions,\expandafter} +% \DoNotIndex{\fbox} +% \DoNotIndex{\filedate,\filename,\fileversion,\fontsize,\framebox,\gdef} +% \DoNotIndex{\global,\halign,\hbox,\hfil,\hfill,\hrule} +% \DoNotIndex{\hsize,\hskip,\hspace,\hss,\if@tempswa,\ifcase,\or,\fi,\fi} +% \DoNotIndex{\ifhmode,\ifvmode,\ifnum,\iftrue,\ifx,\fi,\fi,\fi,\fi,\fi} +% \DoNotIndex{\input} +% \DoNotIndex{\jobname,\kern,\leavevmode,\let} +% \DoNotIndex{\list,\llap,\long,\m@ne,\m@th} +% \DoNotIndex{\month,\newcommand,\newcounter,\newenvironment} +% \DoNotIndex{\NeedsTeXFormat,\newdimen} +% \DoNotIndex{\newlength,\newpage,\nobreak,\noindent,\null,\number} +% \DoNotIndex{\numberline,\OldMakeindex,\OnlyDescription,\p@} +% \DoNotIndex{\par,\paragraph,\paragraphmark,\parfillskip} +% \DoNotIndex{\penalty,\PrintChanges,\PrintIndex,\ProcessOptions} +% \DoNotIndex{\protect,\ProvidesClass} +% \DoNotIndex{\refstepcounter,\relax,\renewcommand,\reset@font} +% \DoNotIndex{\rightskip,\rlap,\rmfamily,\roman} +% \DoNotIndex{\roman,\secdef,\selectfont,\setbox,\setcounter,\setlength} +% \DoNotIndex{\settowidth,\sfcode,\skip,\sloppy,\slshape,\space} +% \DoNotIndex{\symbol,\the,\trivlist,\typeout,\tw@,\undefined,\uppercase} +% \DoNotIndex{\usecounter,\usefont,\usepackage,\vfil,\vfill,\viiipt} +% \DoNotIndex{\viipt,\vipt,\vskip,\vspace} +% \DoNotIndex{\wd,\xiipt,\year,\z@} +% \DoNotIndex{\@namedef,\@nameuse,\csname,\endcsname} +% +% \def\dtxfile{sudokubundle.dtx} +% \def\fileversion{1.0a} \def\filedate{2006/02/19} +% +% \newcommand*{\fref}[1]{Figure~\ref{#1}} +% \newcommand*{\tref}[1]{Table~\ref{#1}} +% \newcommand*{\Lopt}[1]{\textsf {#1}} ^^A typeset an option +% \newcommand*{\file}[1]{\texttt {#1}} ^^A typeset a file +% \newcommand*{\Lcount}[1]{\textsl {\small#1}} ^^A typeset a counter +% \newcommand*{\pstyle}[1]{\textsl {#1}} ^^A typeset a pagestyle +% \newcommand*{\Lenv}[1]{\texttt {#1}} ^^A typeset an environment +% \newcommand*{\Lpack}[1]{\textsf {#1}} ^^A typeset a package +% \newcommand*{\ctt}{\textsc{ctt}} +% \newcommand{\Lclass}[1]{\textsf{#1}} +% \newcommand{\PWcomment}[1]{} +% \newenvironment{PW}{\itshape}{} +% \renewenvironment{PW}{\sffamily}{} +% \newcommand{\texbook}{\textit{TeXbook}} +% \newcommand{\thetexbook}{\textit{The TeXbook}} +% \newcommand{\egstart}{} +% \newcommand{\egmid}{} +% \newcommand{\egend}{} +% \renewcommand{\egstart}{ +% \par +% \begingroup +% \centering +% \begin{minipage}{0.45\textwidth}} +% \renewcommand{\egmid}{ +% \end{minipage}\hfill\begin{minipage}{0.45\textwidth}} +% \renewcommand{\egend}{ +% \end{minipage}\par\endgroup} +% +% \title{The sudoku bundle for displaying, solving and generating Sudoku +% puzzles\thanks{This file (\dtxfile) +% has version number \fileversion, last revised on \filedate.}} +% \author{Peter +% Wilson\thanks{\texttt{herries dot press at earthlink dot net}}\\ +% The Herries Press} +% \date{\filedate} +% \maketitle +% +% \begin{abstract} +% The \Lpack{sudoku bundle} provides a coordinated set of packages for +% displaying, solving, and generating Sudoku puzzles. A set of over 50 puzzles +% is also supplied. +% \end{abstract} +% +% \tableofcontents +% \listoffigures +% +% \section{Introduction} +% +% In December 2005 the \emph{PracTeX Journal}~\cite{PRACTEX} set a competition +% about Sudoku puzzles. +% Depending on their experience with \TeX\ contestants were asked to +% (a) typeset a particular puzzle, (b) typeset +% a puzzle described in a `sudoku' file, (c) create a solver for +% sudoku puzzles. I entered the competition with a printer and solver. +% Following from this it was no great effort to develop a matching +% Soduko puzzle generator. +% +% The packages described here have been developed completely independently +% from Paul Abraham's \Lpack{sudoku} package~\cite{SUDOKU}, which I did +% not see until after I had finished work on them. +% +% A Sudoku puzzle consists a 9 by 9 grid of cells with +% some of the cells containing a number between 1 and 9, such as is +% shown in \fref{fig:puz1}. The problem +% is to place a number between 1 and 9 in each cell such that no number appears +% more than once in each row and in each column and in each minor 3 by 3 grid. +% The solution to the example puzzle is shown in \fref{fig:ans1}. The +% puzzle and answer have been typeset using the \Lpack{printsudoku} package. +% +% \changes{v1.0a}{2006/02/19}{Deleted clue from example puzzle, +% courtesy William Hammond} +% \renewcommand*{\puzzlefile}{examout.sud} +% \writepuzzle% +% {..483..72}% +% {.12....8.}% +% {..52.13..}% +% {....62.91}% +% {7..5.9..3}% +% {94.78....}% +% {..39.74..}% +% {.5....61.}% +% {.8..469..}% +% [Example puzzle \sudpuzznewline +% (anything can come after the nine puzzle lines)] +% \begin{figure} +% \centering +% \sudoku{examout.sud} +% \caption{Example Sudoku puzzle}\label{fig:puz1} +% \end{figure} +% +% Among many other sources the \emph{Sudoku Solver by logic} +% website~\cite{SSBL} +% provides much information on Sudoku puzzles and their solutions, +% as does the \emph{Sudoku Online}~\cite{SOL} website. +% +% A Sudoku puzzle may be represented as a simple text file consisting +% of nine rows of numbers and dots, nine numbers and dots in each row. +% The numbers are the clues to the puzzle and the dots represent blanks +% in the grid. A sudoko file for the example puzzle is given in +% \fref{fig:file1}. +% +% +% \begin{figure} +% \centering +% \begin{verbatim} +% ..483..72 +% .12....8. +% ..52.13.. +% ....62.91 +% 7..5.9..3 +% 94.78.... +% ..39.74.. +% .5....61. +% .8..469.. +% +% Example puzzle +% (anything can come after the nine puzzle lines) +% \end{verbatim} +% \caption{A sudoku file for the example puzzle}\label{fig:file1} +% \end{figure} +% +% +% \renewcommand*{\puzzlefile}{examout.ans} +% \writepuzzle% +% {694835172}% +% {312674589}% +% {875291364}% +% {538462791}% +% {726519843}% +% {941783256}% +% {163957428}% +% {459328617}% +% {287146935}% +% [Solution to example puzzle] +% +% \begin{figure} +% \centering +% \cluefont{\normalsize}\cellsize{1.5\baselineskip} +% \sudoku{examout.ans} +% \caption{Solution to example puzzle}\label{fig:ans1} +% \end{figure} +% +% +% This manual is typeset according to the conventions of the \LaTeX{} +% \textsc{docstrip} utility which enables the automatic extraction +% of the \LaTeX{} macro source files~\cite{COMPANION}. +% +% \section{Usage} +% +% The bundle provides three packages; one for typesetting a puzzle, one +% for solving a puzzle, and the third for generating a puzzle. Each package +% requires the previous one(s). +% +% A file is also provided that contains over 50 puzzles and their answers --- +% all you have to do is run LaTeX on it, print it, and get to work on the puzzles +% (or give them to someone else). +% +% \subsection{Typesetting} +% +% The \Lpack{printsudoku} package enables you to typeset a Sudoku +% puzzle given in a sudoku file. +% +% \DescribeMacro{\sudoku} +% The command \cs{sudoku}\marg{file} typesets the sudoku puzzle from the +% sudoku file named \meta{file}. +% For example: \\ +% \verb? \begin{center} \sudoku{puzzle1.sud} \end{center}? \\ +% The command reads only the first nine lines in the file, which must +% contain the puzzle's description. Anything after these lines is ignored, +% so comments, such as a title or other explanatory text, +% can be put at the end of the file. +% +% \DescribeMacro{\cluefont} +% Following \cs{cluefont}\marg{font} the clues are typeset using the +% \meta{font} font specification. The default is: \\ +% \verb?\cluefont{\Huge}? +% +% \DescribeMacro{\cellsize} +% The puzzle is typeset as a \LaTeX\ \Lenv{picture} and +% \cs{cellsize}\marg{length} specifies the size of the cells in the grid. +% To match the \cs{cluefont} the default is: \\ +% \verb?\cellsize{2.5\baselineskip}? +% +% Figure~\ref{fig:puz1} was set using the default \cs{cluefont} and +% \cs{cellsize}. On the other hand, \fref{fig:ans1} was set via: +% \begin{verbatim} +% \begin{figure} +% \centering +% \cluefont{\normalsize}\cellsize{1.5\baselineskip} +% \sudoku{examout.ans} +% \caption{Solution to example puzzle}\label{fig:ans1} +% \end{figure} +% \end{verbatim} +% +% \DescribeMacro{\writepuzzle} +% \DescribeMacro{\puzzlefile} +% \DescribeMacro{\sudpuzznewline} +% The command \cs{writepuzzle}, which takes nine required arguments each of +% which is a line in the puzzle, writes the puzzle to the file \cs{puzzlefile}, where the default +% is: \\ +% \verb?\newcommand*{\puzzlefile}{puzz.sud}? +% +% The nine required arguments to \cs{writepuzzle} are the lines describing +% a puzzle as they would appear in a sudoku file. There is an optional tenth +% argument after the nine required arguments which you may use to write +% a comment at the end of the file. +% For instance, earlier I used the following +% to write out the example puzzle to the file \file{examout.sud}: +% \begin{verbatim} +% \renewcommand*{\puzzlefile}{examout.sud} +% \writepuzzle% +% {..483..72}% +% {.12....8.}% +% {..52.13..}% +% {....62.91}% +% {7..5.9..3}% +% {94.78....}% +% {..39.74..}% +% {.5....61.}% +% {.8..469..}% +% [Example puzzle \sudpuzznewline +% (anything can come after the nine puzzle lines)] +% \end{verbatim} +% And similarly for writing out the file with the solution. +% +% If you want a multiline comment, use the \cs{sudpuzznewline} macro to +% start a new line (\verb?\\? or \cs{newline} will not work). +% +% +% \subsection{Solving} +% +% The \Lpack{solvesudoku} package lets you use \LaTeX\ to try and solve +% a Sudoku puzzle. +% +% \DescribeMacro{\sudokusolve} +% The macro \cs{sudokusolve}\marg{file} attempts to find a solution to +% the puzzle in the sudoku file \meta{file}. It uses the \Lpack{printsudoku} +% package for typesetting the puzzle. +% +% It first prints the puzzle as given and then attempts to solve it. +% The solution, or as much as was obtainable, is typeset in a smaller +% font below the original. Here is the definition: +% \begin{verbatim} +% \newcommand*{\sudokusolve}[1]{% +% \begin{center} +% \sudoku{#1} +% \end{center} +% \getproblem{#1} +% \reduceallcells \keepreducing +% \writegame +% \noindent\begin{minipage}{\linewidth} +% THE ANSWER +% \begin{center} +% \cluefont{\normalsize} +% \cellsize{1.5\baselineskip} +% \sudoku{sud.out} +% \end{center} +% \end{minipage}} +% \end{verbatim} +% You may use the macros in \cs{sudokusolve} separately if you wish. +% +% \DescribeMacro{\getproblem} +% \cs{getproblem}\marg{file} reads in the puzzle from the sudoku file +% \meta{file} and initialises the solution. +% +% \DescribeMacro{\reduceallcells} +% \cs{reduceallcells} takes a simple-minded approach to develop a solution +% to the puzzle. +% +% \DescribeMacro{\keepreducing} +% If \cs{reduceallcells} does not completely solve the puzzle then +% \cs{keepreducing} applies increasingly sophisticated solution methods, +% which may or may not lead to a complete solution. +% +% \DescribeMacro{\writegame} +% \DescribeMacro{\sudsolnfile} +% \cs{writegame} writes out a (partially) solved puzzle to the sudoku file +% \cs{sudsolnfile} (default \file{sud.out}). Later this is read in again +% by \cs{sudoku} to +% typeset the solution. +% +% Here's a small example of how you might use the package. This will keep +% asking on the terminal for sudoku files to solve. +% \begin{verbatim} +%%%% solvethem.tex Solve Sudoku files +%%%% Peter Wilson +% \documentclass{article} +% \usepackage{solvesudoku} +% \newcommand*{\solvefile}[1]{\begingroup +% \sudokusolve{#1}% +% \par +% \vspace{\baselineskip} +% Number of clues = \the\numcluesctr\ and difficulty = \the\difficultyctr. +% \endgroup} +% \def\yesans{y} +% \begin{document} +% \loop +% \typein[\getans]{New file? y/n} +% \ifx\yesans\getans +% \typein[\sudfile]{Enter the file name} +% \clearpage +% \begin{center} \Huge \sudfile \end{center} +% \solvefile{\sudfile} +% \repeat +% \end{document} +% \end{verbatim} +% +% \DescribeMacro{\numcluesctr} +% \DescribeMacro{\difficultyctr} +% These are two \TeX\ \cs{count}s. \cs{numcluesctr} is the number of clues +% in the initial puzzle, and \cs{difficultyctr} is a numerical indication +% of how hard the solver had to work, but it doesn't really mean much +% as the solver has had successes with some puzzles with a high +% \cs{difficultyctr} rating +% but failed to solve some with medium values of \cs{difficultyctr}. +% +% \subsection{Generation} +% +% With the \Lpack{createsudoku} package you can get \LaTeX\ to automatically +% generate a Sudoku puzzle. This package does require the use of Donald +% Arseneau's \Lpack{random} code~\cite{RANDOM} for generating random numbers. +% +% \DescribeMacro{\generategrid} +% \cs{generategrid}\oarg{file} will generate a Sudoku puzzle starting with +% the solution given in the sudoku file \meta{file}. If the file is +% not given then it will start from a solution provided by the package. +% +% The puzzle is generated by taking the solution and randomly exchanging +% rows and columns for some (random) number of times. Then clues are +% eliminated until +% it is no longer soluble by \cs{sudokusolve}. The last clue that was deleted +% is put back and then the resulting grid is presented as the puzzle. +% +% An initial set of clues are deleted before the solver is called. It can +% happen that the puzzle even then is too difficult for the solver, so +% you have to check the solution as presented is a complete one for the puzzle. +% +% \DescribeMacro{\genfile} +% \DescribeMacro{\prevfile} +% \DescribeMacro{\currfile} +% The generated puzzle, and its solution, is typeset and the puzzle is +% also output in the sudoku file \cs{genfile}. The default is: \\ +% \verb?\newcommand*{\genfile}{gensud.sud}? \\ +% Two temporary sudoku files, \cs{prevfile} and \cs{currfile}, are +% used during the generation. The defaults are: \\ +% \verb?\newcommand*{\prevfile}{genprev.sdx}? \\ +% \verb?\newcommand*{\currfile}{gencurr.sdx}? \\ +% A pre-existing version of any of these three files will be overwritten. +% +% \DescribeMacro{\setsudrandom} +% The random number generater is initialised via a seed based on +% a number (the internal value of \cs{randomi}) +% in the range $-1 \leq$ \cs{randomi} $\leq 2147483646$. +% If its value is -1 (set via \verb?\setsudrandom{-1}?) then the actual +% seed will be calculated based on the time and date. For any given +% seed the sequence of the generated random numbers is the same. +% The value of the +% seed is output via a \cs{typeout} if you need to repeat a generation. +% +% You should not attempt to set \cs{randomi} directly but use +% \cs{setsudrandom}\marg{num}. +% +% The default setting is: \\ +% \verb?\setsudrandom{-1}? \\ +% and as that means that the seed depends on the time and date, +% a new puzzle will be +% generated each time (unless the time interval is very short). The +% maximum number of puzzles that can be generated from one initial solution +% is 2,147,483,646 which is the range of the random number generator. +% +% \DescribeMacro{\initialelimination} +% The macro \cs{initialelimination} eliminates an initial set of solutions +% from the randomized starting grid. Various predefined sets are provided +% and you can either provide your own definition for \cs{initialelimination} +% or \cs{let} it to one of the predefined sets, e.g., \\ +% \verb?\let\initialelimination\elimcrossandnines? +% +% \DescribeMacro{\elimseventeen} +% \DescribeMacro{\elimnum} +% \DescribeMacro{\elimcross} +% \DescribeMacro{\elimex} +% \DescribeMacro{\elimcrossandnines} +% \DescribeMacro{\elimcrossandex} +% \DescribeMacro{\elimcrossandexandnines} +% \cs{elimseventeen} randomly eliminates 17 solutions from the grid --- +% apparently the solution to a puzzle can be ambiguous if two numbers +% are completely absent. +% \cs{elimnum}\marg{num} eliminates every solution \meta{num} +% (e.g. \verb?\elimnum{7}? will eliminate every 7 from the grid). +% \cs{elimcross} eliminates all numbers from column 5 and from row 5, while +% \cs{elimex} eliminates all numbers on the diagonals. +% +% \cs{elimcrossandnines} +% is a combination of \cs{elimcross} and \verb?\elimnum{9}?. Similarly the +% macros \cs{elimcrossandex} and \cs{elimcrossandexandnines} are combinations +% of some of the earlier macros. +% +% +% +% \StopEventually{ +% \bibliographystyle{alpha} +% \begingroup +% \raggedright +% \begin{thebibliography}{GMSN94A} +% +% \bibitem[Abr05]{SUDOKU} +% Paul Abraham. +% \newblock \emph{The sudoku package}. +% \newblock June 2005. +% \newblock (Available from CTAN in +% \texttt{macros/latex/contrib/sudoku}) +% +% \bibitem[Ars95]{RANDOM} +% Donald Arseneau. +% \newblock \emph{Generating random numbers in \TeX}. +% \newblock 1995. +% \newblock (Available from CTAN in +% \texttt{macros/generic/random.tex}) +% +% +% \bibitem[MG04]{COMPANION} +% Frank Mittelbach and Michel Goossens. +% \newblock \emph{The LaTeX Companion}. +% \newblock Second edition. +% \newblock Addison-Wesley Publishing Company, 2004. +% \newblock \textsc{isbn} 0-201-36299-6. +% +% \bibitem[PJ05]{PRACTEX} +% \TeX\ Users Group. +% \newblock Distractions: Sudoku. +% \newblock \emph{The PracTeX Journal}. +% \newblock 2005-4. +% \newblock \url{http://tug.org/pracjourn2005-4/distract} +% +% \bibitem[SOL]{SOL} +% \emph{Sudoku Online: Home of the Sudokulist}. +% \newblock \url{http://www.sudoku.org.uk} +% +% \bibitem[SSBL]{SSBL} +% \emph{Sudoku Solver ... by logic}. +% \newblock \url{http://www.sudokusolver.co.uk} +% +% +% ^^A \bibitem[Wil04]{MEMOIR} +% ^^A Peter Wilson. +% ^^A \newblock \emph{The LaTeX \Lpack{memoir} class for configurable +% ^^A typesetting: Source code}. +% ^^A \newblock January 2004. +% ^^A \newblock (Available from CTAN in +% ^^A \texttt{macros/latex/contrib/memoir}) +% +% +% \end{thebibliography} +% \endgroup +% +% \PrintIndex +% } +% +% \section{Code} +% +% \subsection{The \Lpack{printsudoku} package} +% +% \begin{macrocode} +%<*print> +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{printsudoku}[2006/02/16 v1.0 typeset sudoku puzzles] + +% \end{macrocode} +% +% \begin{macro}{\s@dread} +% \begin{macro}{\s@dwrite} +% We are going to be reading and writing some files. +% \begin{macrocode} +\newread\s@dread +\newwrite\s@dwrite + +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\reads@dgame} +% \cs{reads@dgame}\marg{file} opens a sudoku file \meta{file} for reading. +% \begin{macrocode} +%%%% open game file +\newcommand*{\reads@dgame}[1]{% + \closein\s@dread + \openin\s@dread=#1} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\halfs@dcell} +% \begin{macro}{\cellsize} +% \begin{macro}{\cluefont} +% We're going to use a \Lenv{picture} environment for drawing the grid, +% and to keep numbers neatly we'll use the length \cs{halfs@dcell} as +% the \cs{unitlength}. \cs{cellsize}\marg{length} is the use command for +% setting the size of a cell. The clues are typeset using the \cs{cluefont} +% font. +% \begin{macrocode} +%%% set size of a game cell +\newlength\halfs@dcell +\newcommand*{\cellsize}[1]{% + \halfs@dcell=#1\relax + \halfs@dcell=0.5\halfs@dcell} +\cellsize{2.5\baselineskip} +%% set font for the numbers +\newcommand*{\cluefont}[1]{\def\s@dfont{#1}} +\cluefont{\Huge} + +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\s@dncol} +% \begin{macro}{\s@dnrow} +% \begin{macro}{\s@dcolpos} +% \begin{macro}{\s@drowpos} +% Counts for looping and cell positions +% \begin{macrocode} +%% counts for looping and cell positions +\newcount\s@dncol +\newcount\s@dnrow +\newcount\s@dcolpos +\newcount\s@drowpos + +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\adds@dclues} +% \cs{adds@dclues} inserts the clues into the game grid. It reads the +% sudoku file line by line insert the clues into the grid for one line +% before going on to the next line. +% \begin{macrocode} +%% insert the clues into the game array +\newcommand*{\adds@dclues}{% + \firsts@dcluetrue + \s@dnrow\@ne + \loop + \ifnum\s@dnrow<10\relax + \read\s@dread to \s@dline + \firsts@dcluetrue + \s@drowpos=\s@dnrow + \multiply\s@drowpos\tw@ + \advance\s@drowpos\m@ne + \s@dncol\@ne + \dos@dcols + \advance\s@dnrow\@ne + \repeat + \closein\s@dread} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\dos@dcols} +% \cs{dos@dcols} inserts one row of clues into the game grid. +% \begin{macrocode} +%% insert a row of clues +\newcommand*{\dos@dcols}{% +\bgroup + \loop + \ifnum\s@dncol<10\relax + \s@dcolpos=\s@dncol + \multiply\s@dcolpos\tw@ + \advance\s@dcolpos\m@ne + \put(\s@dcolpos,-\s@drowpos){\makebox(0,0){\s@dfont\gets@dclue}}% + \advance\s@dncol\@ne + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\gettwo} +% \begin{macro}{\nowt} +% \begin{macro}{\istchar} +% \begin{macro}{\restchars} +% \begin{macro}{\splitoff} +% \cs{splitoff}\marg{string} gets the next character in a string. The next +% character is made available as \cs{istchar} and the remainder of the +% string as \cs{restchars}. This is explained in a forthcoming +% \emph{Glisterings} column in \emph{TUGboat}. +% \begin{macrocode} +%% get the next character in a string +\def\gettwo#1#2\nowt{% + \gdef\istchar{#1}\gdef\restchars{#2}} +\def\splitoff#1{\gettwo#1\nowt} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\s@dfstop} +% We use this for checking if a character extracted from a string is a `.'. +% \begin{macrocode} +%% a full stop (period) +\gdef\s@dfstop{.} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\iffirsts@dclue} +% \begin{macro}{\firsts@dcluetrue} +% \begin{macro}{\firsts@dcluefalse} +% \begin{macro}{\gets@dclue} +% \cs{gets@dclue} gets the next clue (character) from a line of clues. +% We do slightly different things if we are dealing with the first clue +% or the others. +% \begin{macrocode} +%% get the next clue in the line +\newif\iffirsts@dclue +\firsts@dcluetrue +\newcommand*{\gets@dclue}{% + \iffirsts@dclue + \expandafter\splitoff\expandafter{\s@dline}% + \global\firsts@dcluefalse + \else + \expandafter\splitoff\expandafter{\restchars}% + \fi + \ifx\s@dfstop\istchar + \else + \istchar + \fi} + +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\s@dgame} +% \cs{s@dgame} typesets the grid, then adds in the clues. +% \begin{macrocode} +%% typeset the grid, then add the clues +\newcommand*{\s@dgame}{% + \setlength\unitlength\halfs@dcell + \begin{picture}(18,18)(0,-18) + \thinlines + \multiput(0,0)(2,0){10}{\line(0,-1){18}} + \multiput(0,0)(0,-2){10}{\line(1,0){18}} + \thicklines \linethickness{1pt} + \multiput(0,0)(6,0){4}{\line(0,-1){18}} + \multiput(0,0)(0,-6){4}{\line(1,0){18}} + \adds@dclues + \end{picture}} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\sudoku} +% \cs{sudoku}\marg{file} reads a game from \meta{file} and then typesets it. +% \begin{macrocode} +%% the whole shebang, where #1 is the name of the game file +\newcommand*{\sudoku}[1]{% + \reads@dgame{#1}% + \s@dgame} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\puzzlefile} +% \begin{macro}{\writepuzzle} +% \begin{macro}{\writes@dpuzzend} +% \begin{macro}{\sudpuzznewline} +% \cs{writepuzzle} takes nine arguments --- the nine lines specifying a puzzle +% --- and writes them to the \cs{puzzlefile} file. +% +% \cs{writes@dpuzzend}\oarg{comment} writes \meta{comment} at the end of the +% \cs{puzzlefile} file. +% +% \cs{sudpuzznewline} provides a \cs{newline} macro for use in a comment being +% written to a puzzle file. +% \begin{macrocode} +\newcommand*{\puzzlefile}{puzz.sud} +\newcommand*{\writepuzzle}[9]{% + \immediate\closeout\s@dwrite + \immediate\openout\s@dwrite=\puzzlefile + \immediate\write\s@dwrite{#1}% + \immediate\write\s@dwrite{#2}% + \immediate\write\s@dwrite{#3}% + \immediate\write\s@dwrite{#4}% + \immediate\write\s@dwrite{#5}% + \immediate\write\s@dwrite{#6}% + \immediate\write\s@dwrite{#7}% + \immediate\write\s@dwrite{#8}% + \immediate\write\s@dwrite{#9}% + \writes@dpuzzend} +\newcommand*{\writes@dpuzzend}[1][\@empty]{ + \ifx\@empty #1\else + \immediate\write\s@dwrite{ }% + \immediate\write\s@dwrite{#1}% + \fi + \immediate\closeout\s@dwrite} +\newcommand*{\sudpuzznewline}{^^J} + +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% The end of the package. +% \begin{macrocode} +% +% \end{macrocode} +% +% \subsection{The \Lpack{solvesudoku} package} +% +% The package requires the \Lpack{printsudoku} package to do some puzzle +% typesetting. +% +% \begin{macrocode} +%<*solve> +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{solvesudoku}[2006/02/16 v1.0 solve sudoku puzzles] +\RequirePackage{printsudoku} + +% \end{macrocode} +% +% \subsubsection{Setup} +% +% \begin{macro}{\commentary} +% It can be useful to control the amount of output to the log file. +% \begin{macrocode} +\newcommand{\commentary}[1]{\typeout{#1}} + +% \end{macrocode} +% \end{macro} +% +% The following counts are defined in the \Lpack{printsudoku} package: \\ +% \verb?\s@dncol, \s@dnrow, \s@dcolpos, \s@drowpos? +% +% \begin{macro}{\s@lcnta} +% \begin{macro}{\solcnt} +% \begin{macro}{\tenscnt} +% \begin{macro}{\tempcntz} +% \begin{macro}{\tempcnty} +% \begin{macro}{\tmpsetctr} +% \begin{macro}{\tmpsetansctr} +% \begin{macro}{\boxctr} +% \begin{macro}{\sumctr} +% \begin{macro}{\toprangectr} +% A bunch of \cs{count}s. They could probably be reduced in number +% but they help me to keep the code less mysterious. +% \begin{macrocode} +%%% too many counts, maybe they should be reduced +\newcount\s@lcnta % a cell number +\newcount\solcnt % number of solved cells +\newcount\settonumcnt +\newcount\tenscnt +\newcount\tempcntz +\newcount\tempcnty +\newcount\tmpsetctr +\newcount\tmpsetansctr +\newcount\boxctr +\newcount\sumctr +\newcount\toprangectr +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\lonecellctr} +% \begin{macro}{\reducedctr} +% \begin{macro}{\numlistctr} +% \begin{macro}{\difficultyctr} +% \begin{macro}{\s@dtempcnta} +% \begin{macro}{\s@dtempcntb} +% \begin{macro}{\s@dtemploopcnta} +% \begin{macro}{\maxrangectr} +% \begin{macro}{\asetctr} +% \begin{macro}{\secondctr} +% \begin{macrocode} +\newcount\lonecellctr +\newcount\reducedctr +\newcount\numlistctr +\newcount\difficultyctr +\newcount\s@dtempcnta +\newcount\s@dtempcntb +\newcount\s@dtemploopcnta +\newcount\maxrangectr +\newcount\asetctr +\newcount\secondctr +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\digitictr} +% \begin{macro}{\digitiictr} +% \begin{macro}{\numdigitsctr} +% \begin{macro}{\numcluesctr} +% \begin{macrocode} +\newcount\digitictr +\newcount\digitiictr +\newcount\numdigitsctr +\newcount\numcluesctr + +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\iffirsts@dclue} +% \begin{macro}{\iffirstchar} +% \begin{macro}{\ifnotgotthechar} +% \begin{macro}{\ifsetchanged} +% \begin{macro}{\ifchanged} +% \begin{macro}{\ifanychanged} +% \begin{macro}{\iflonerchanged} +% \begin{macro}{\ifstilldigits} +% \begin{macro}{\ifkeepon} +% \begin{macro}{\ifpairchanged} +% \begin{macrocode} +%%% \iffirsts@dclue% defined in printsudoku package +\newif\iffirstchar +\newif\ifnotgotthechar +\newif\ifsetchanged +\newif\ifchanged +\newif\ifanychange +\newif\iflonerchanged +\newif\ifstilldigits +\newif\ifkeepon +\newif\ifpairchanged + +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\newknt} +% \begin{macro}{\useknt} +% \begin{macro}{\createsudsets} +% \cs{newknt}\marg{name} creates a new count \cs{name}, which can include +% analphabetic characters. \cs{useknt}\marg{name} calls the \cs{name} count. +% These are like the \LaTeX\ kernel \cs{@namedef} and \cs{@nameuse}. +% In particular we will use 81 `numbered' counts, one for each cell +% in the sudoku grid, using \cs{createsudsets} to generate them. +% \begin{macrocode} +%% create and use a numbered count +%% we'll use 81 of these, one for each cell in the grid +\newcommand*{\newknt}[1]{\expandafter\newcount\csname #1\endcsname} +\newcommand*{\useknt}[1]{\csname #1\endcsname} +%% create potential answer sets +\newcommand*{\createsudsets}{% +\global\s@lcnta\@ne +\global\solcnt\z@ +\loop + \ifnum\s@lcnta<82\relax + \newknt{s@lans\the\s@lcnta}% + \advance\s@lcnta\@ne +\repeat} +\createsudsets + +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsubsection{Binary solution sets} +% +% The major concern was deciding on the datastructure for the problem +% (the value of \verb?\useknt{\s@lans\the\s@lcnta}}? for the \cs{s@lcnta} cell). +% In the end I used a 9 digit `binary solution set' for the potential +% solutions for +% each cell. ($[111111111] \leftrightarrow 123456789$ and +% $[101010101] \leftrightarrow 13579$). A cell +% solution, say N, is represented as the `set' -N (e.g., a +% potential solution 3 is represented as $[001000000]$ and the actual solution +% 3 is represented by $[-3]$). +% +% +% \begin{macro}{\initialisesuddata} +% This sets each of the 81 cells to 111111111. +% \begin{macrocode} +%% initialise potential answer sets +\newcommand*{\initialisesuddata}{\bgroup +\global\s@lcnta\@ne +\global\solcnt\z@ +\global\difficultyctr\z@ +\global\numcluesctr\z@ +\loop + \ifnum\s@lcnta<82\relax + \global\useknt{s@lans\the\s@lcnta}=111111111\relax + \advance\s@lcnta\@ne +\repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%%%%%%%%%%%%%%%%%%%%%%%% utility macros for `binary solution sets' %%%%%%%%%%%%%%%% + +% \end{macrocode} +% +% \begin{macro}{\settonum} +% \cs{settonum}\marg{set}\marg{cnt} converts a potential solution +% binary set \meta{set} to the corresponding set of digits; that is +% \verb?[11....1] -> 12...9?. The result of the conversion is assigned +% to the \cs{count} \meta{cnt} which must be supplied by the calling macro. +% If the set is negative then the result is that number +% (e.g.\verb?[-3] -> -3?). If the set contains only a single non-zero +% entry, that is converted to the negative of the corresponding digit +% (e.g. \verb?[100] -> -7?). +% +% \begin{macrocode} +%%\settonum{110011...}{cnt} +%% converts a potential solution set to a number ([11....1] -> 12...9) +%% returns the input if it is negative ([-3] -> -3) +%% returns a negative number if the set represents a single digit ([10] -> -8) +\newcommand*{\settonum}[2]{% + \settonumcnt=#1\relax + \tempcnty=\z@ + \tenscnt=\@ne + \ifnum\settonumcnt<\z@ % just return the number + \tempcnty=\settonumcnt + #2=\tempcnty + \else + \ifodd\settonumcnt % 9 flagged + \tempcntz=9\relax + \multiply\tempcntz \tenscnt + \advance \tempcnty by \tempcntz + \multiply\tenscnt 10\relax + \fi + \divide\settonumcnt by 10\relax + \ifodd\settonumcnt % 8 flagged + \tempcntz=8\relax + \multiply\tempcntz \tenscnt + \advance \tempcnty \tempcntz + \multiply\tenscnt 10\relax + \fi + \divide\settonumcnt by 10\relax + \ifodd\settonumcnt % 7 flagged + \tempcntz=7\relax + \multiply\tempcntz \tenscnt + \advance \tempcnty \tempcntz + \multiply\tenscnt 10\relax + \fi + \divide\settonumcnt by 10\relax + \ifodd\settonumcnt % 6 flagged + \tempcntz=6\relax + \multiply\tempcntz \tenscnt + \advance \tempcnty \tempcntz + \multiply\tenscnt 10\relax + \fi + \divide\settonumcnt by 10\relax + \ifodd\settonumcnt % 5 flagged + \tempcntz=5\relax + \multiply\tempcntz \tenscnt + \advance \tempcnty \tempcntz + \multiply\tenscnt 10\relax + \fi + \divide\settonumcnt by 10\relax + \ifodd\settonumcnt % 4 flagged + \tempcntz=4\relax + \multiply\tempcntz \tenscnt + \advance \tempcnty \tempcntz + \multiply\tenscnt 10\relax + \fi + \divide\settonumcnt by 10\relax + \ifodd\settonumcnt % 3 flagged + \tempcntz=3\relax + \multiply\tempcntz \tenscnt + \advance \tempcnty \tempcntz + \multiply\tenscnt 10\relax + \fi + \divide\settonumcnt by 10\relax + \ifodd\settonumcnt % 2 flagged + \tempcntz=2\relax + \multiply\tempcntz \tenscnt + \advance \tempcnty \tempcntz + \multiply\tenscnt 10\relax + \fi + \divide\settonumcnt by 10\relax + \ifodd\settonumcnt % 1 flagged + \tempcntz=1\relax + \multiply\tempcntz \tenscnt + \advance \tempcnty \tempcntz +%% \multiply\tenscnt 10\relax + \fi + \ifnum \tempcnty<10 + \ifnum\tempcnty>\z@ + \tempcnty = -\tempcnty + \fi + \fi + #2=\tempcnty +\fi} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\numofnuminset} +% \cs{numofnuminset}\marg{digit}\marg{set}\marg{cnt} set the \cs{count} +% \meta{cnt}to the number of times the digit \meta{digit} is represented +% in the binary set \meta{set}. For example, the number of digits in the set +% \verb?[200000013]? are \verb?1 -> 2?, \verb?2 -> 0?, \verb?...?, +% \verb?8 -> 1? and \verb?9 -> 3?. +% \begin{macrocode} +%%\numofnuminset{digit}{set}{returnctr} +%% returns the number of times digit is represented in the set +%% e.g. if the set is [200000013] then 1 -> 2, 2 -> 0,... 8 -> 1, 9 -> 3 +\newcommand*{\numofnuminset}[3]{% + \tmpsetctr=#2\relax + \tmpsetansctr=\tmpsetctr + \ifnum\tmpsetctr<\z@% solution, not a set + \tmpsetansctr=\z@ + \else + \ifcase #1\relax + \or % 1 + \divide\tmpsetansctr by 100000000\relax + \or % 2 + \divide\tmpsetansctr by 10000000\relax + \tmpsetctr=\tmpsetansctr + \divide\tmpsetctr 10\relax \multiply\tmpsetctr 10\relax + \advance\tmpsetansctr -\tmpsetctr + \or % 3 + \divide\tmpsetansctr by 1000000\relax + \tmpsetctr=\tmpsetansctr + \divide\tmpsetctr 10\relax \multiply\tmpsetctr 10\relax + \advance\tmpsetansctr -\tmpsetctr + \or % 4 + \divide\tmpsetansctr by 100000\relax + \tmpsetctr=\tmpsetansctr + \divide\tmpsetctr 10\relax \multiply\tmpsetctr 10\relax + \advance\tmpsetansctr -\tmpsetctr + \or % 5 + \divide\tmpsetansctr by 10000\relax + \tmpsetctr=\tmpsetansctr + \divide\tmpsetctr 10\relax \multiply\tmpsetctr 10\relax + \advance\tmpsetansctr -\tmpsetctr + \or % 6 + \divide\tmpsetansctr by 1000\relax + \tmpsetctr=\tmpsetansctr + \divide\tmpsetctr 10\relax \multiply\tmpsetctr 10\relax + \advance\tmpsetansctr -\tmpsetctr + \or % 7 + \divide\tmpsetansctr by 100\relax + \tmpsetctr=\tmpsetansctr + \divide\tmpsetctr 10\relax \multiply\tmpsetctr 10\relax + \advance\tmpsetansctr -\tmpsetctr + \or % 8 + \divide\tmpsetansctr by 10\relax + \tmpsetctr=\tmpsetansctr + \divide\tmpsetctr 10\relax \multiply\tmpsetctr 10\relax + \advance\tmpsetansctr -\tmpsetctr + \or % 9 + \tmpsetctr=\tmpsetansctr + \divide\tmpsetctr 10\relax \multiply\tmpsetctr 10\relax + \advance\tmpsetansctr -\tmpsetctr + \else % error + \tmpsetansctr=\z@ + \fi + \fi + #3=\tmpsetansctr} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\deletenumfromset} +% \cs{deletenumfromset}\marg{digit}\marg{set}\marg{cnt} removes the +% \meta{digit} from the \meta{set} and sets the \cs{count} \meta{cnt} +% to the reulting modified set. If \meta{digit} was the only member +% then the result is that digit negated. For example: \\ +% \verb?9? from \verb?[...11] -> [...10]? \\ +% \verb?8? from \verb?[0...010] -> -8? +% \begin{macrocode} +%%\deletenumfromset{digit}{set}{returnctr} +%% deletes num from the [set], returning the modified set or a -ve number if +%% the digit was the only member. +%% e.g., 9 from [...11] -> [...10], 8 from [0...010] -> -8 +\newcommand*{\deletenumfromset}[3]{ + \global\setchangedfalse + \tmpsetctr=#2\relax + \tmpsetansctr=#2\relax +\ifnum\tmpsetctr<\z@ % represents a solved number, do nothing +\else + \ifcase #1\relax + \or % 1 + \divide\tmpsetctr by 100000000\relax + \ifodd\tmpsetctr% it's there + \advance\tmpsetansctr -100000000\relax + \global\setchangedtrue + \fi + \or % 2 + \divide\tmpsetctr by 10000000\relax + \ifodd\tmpsetctr% it's there + \advance\tmpsetansctr -10000000\relax + \global\setchangedtrue + \fi + \or % 3 + \divide\tmpsetctr by 1000000\relax + \ifodd\tmpsetctr% it's there + \advance\tmpsetansctr -1000000\relax + \global\setchangedtrue + \fi + \or % 4 + \divide\tmpsetctr by 100000\relax + \ifodd\tmpsetctr% it's there + \advance\tmpsetansctr -100000\relax + \global\setchangedtrue + \fi + \or % 5 + \divide\tmpsetctr by 10000\relax + \ifodd\tmpsetctr% it's there + \advance\tmpsetansctr -10000\relax + \global\setchangedtrue + \fi + \or % 6 + \divide\tmpsetctr by 1000\relax + \ifodd\tmpsetctr% it's there + \advance\tmpsetansctr -1000\relax + \global\setchangedtrue + \fi + \or % 7 + \divide\tmpsetctr by 100\relax + \ifodd\tmpsetctr% it's there + \advance\tmpsetansctr -100\relax + \global\setchangedtrue + \fi + \or % 8 + \divide\tmpsetctr by 10\relax + \ifodd\tmpsetctr% it's there + \advance\tmpsetansctr -10\relax + \global\setchangedtrue + \fi + \or % 9 + \ifodd\tmpsetctr% it's there + \advance\tmpsetansctr -1\relax + \global\setchangedtrue + \fi + \fi +\fi + #3=\tmpsetansctr} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\displaystatus} +% This macro typesets a tabular showing the current real and potential +% solutions for the grid. A real solution is shown as a negative number; +% positive numbers are the potential solution digits for the cell. +% \begin{macrocode} +%% typeset current answers plus potential answer digits +\newcommand*{\displaystatus}{% +\begin{tabular}{||c|c|c||c|c|c||c|c|c||}\hline\hline +\settonum{\the\useknt{s@lans1}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans2}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans3}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans4}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans5}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans6}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans7}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans8}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans9}}{\s@dtempcnta}\the\s@dtempcnta \\ \hline +\settonum{\the\useknt{s@lans10}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans11}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans12}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans13}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans14}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans15}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans16}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans17}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans18}}{\s@dtempcnta}\the\s@dtempcnta \\ \hline +\settonum{\the\useknt{s@lans19}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans20}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans21}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans22}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans23}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans24}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans25}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans26}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans27}}{\s@dtempcnta}\the\s@dtempcnta \\ \hline\hline +\settonum{\the\useknt{s@lans28}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans29}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans30}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans31}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans32}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans33}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans34}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans35}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans36}}{\s@dtempcnta}\the\s@dtempcnta \\ \hline +\settonum{\the\useknt{s@lans37}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans38}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans39}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans40}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans41}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans42}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans43}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans44}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans45}}{\s@dtempcnta}\the\s@dtempcnta \\ \hline +\settonum{\the\useknt{s@lans46}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans47}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans48}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans49}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans50}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans51}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans52}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans53}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans54}}{\s@dtempcnta}\the\s@dtempcnta \\ \hline\hline +\settonum{\the\useknt{s@lans55}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans56}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans57}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans58}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans59}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans60}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans61}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans62}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans63}}{\s@dtempcnta}\the\s@dtempcnta \\ \hline +\settonum{\the\useknt{s@lans64}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans65}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans66}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans67}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans68}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans69}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans70}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans71}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans72}}{\s@dtempcnta}\the\s@dtempcnta \\ \hline +\settonum{\the\useknt{s@lans73}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans74}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans75}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans76}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans77}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans78}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans79}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans80}}{\s@dtempcnta}\the\s@dtempcnta & +\settonum{\the\useknt{s@lans81}}{\s@dtempcnta}\the\s@dtempcnta \\ \hline\hline +\end{tabular}} + +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Problem initialisation} +% +% \begin{macrocode} +%%%%%%%%%%%%%%%%%%%% get the problem and initialise the solution %%%%%%%%% + +% \end{macrocode} +% +% \begin{macro}{\getproblem} +% \cs{getproblem}\marg{file} initialises the solution grid and reads the +% puzzle from the sudoku file \meta{file}. It calls \cs{initialsoln} +% to read the file and insert the clues into the grid. +% \begin{macrocode} +%% read the problem and initialise the problem (solution) +\newcommand*{\getproblem}[1]{\bgroup + \initialisesuddata + \global\solcnt\z@ + \immediate\closein\s@dread + \immediate\openin\s@dread=#1 + \initialsoln + \typeout{Sudoku problem #1, \the\solcnt\space initial clues} +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\initialsoln} +% Get the clues from the puzzle file, line by line, and insert them into +% the grid. \cs{s@dline} holds one line from the file. +% \begin{macrocode} +%% insert the clues from the input game file +\newcommand*{\initialsoln}{% + \firsts@dcluetrue + \s@dnrow\@ne + \s@lcnta\@ne + \loop + \ifnum\s@dnrow<10\relax + \read\s@dread to \s@dline + \firsts@dcluetrue + \s@dncol\@ne + \dos@dinitialcols + \advance\s@dnrow\@ne + \repeat + \immediate\closein\s@dread} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\dos@dinitialcols} +% Insert the clues from one line of the puzzle file into one row of the grid. +% \begin{macrocode} +%% insert the clues from one line of the game file +\newcommand*{\dos@dinitialcols}{\bgroup + \loop + \ifnum\s@dncol<10\relax + \fixentry + \advance\s@dncol\@ne + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\fixentry} +% Inserts a clue from the current line into the grid. +% \begin{macrocode} +%% insert a clue from the current line of the game file +\newcommand*{\fixentry}{% + \iffirsts@dclue + \expandafter\splitoff\expandafter{\s@dline}% + \global\firsts@dcluefalse + \else + \expandafter\splitoff\expandafter{\restchars}% + \fi + \ifx\s@dfstop\istchar + \else + \global\useknt{s@lans\the\s@lcnta}=-\istchar + \global\advance\solcnt\@ne + \global\advance\numcluesctr\@ne + \fi + \global\advance\s@lcnta\@ne} + + +% \end{macrocode} +% \end{macro} +% +% \subsection{Solution methods} +% +% +% Three facts are used to generate a solution. +% \begin{enumerate} +% \item A digit must be unique within a row, a column, and a block +% Thus, if a solution, say N, is known for a cell, then the +% potential solution N must be deleted from all cells in the +% row, column, and block that the solved cell is in. I have +% called this a simple reduction. The simple reductions are repeated +% until there are no changes to the potential solutions. +% +% \item If among all the cells in a row (column, block) there is a digit +% that occurs only once among all the potential solutions, then that +% digit is the solution for its cell. I have termed this a loner. +% If a loner solution is found then simple reductions are repeated. +% +% \item If among all the cells in a row (column, block) there are two digits +% which occur twice only in the row, each time as a pair (e.g., 39 +% and 39) then one or other of the two digits must be a solution for +% a cell in which the pairs occur. This means that the two digits in +% the pair cannot occur anywhere else in the row (column, block). +% If there are no loners then the problem is examined for pairs. If +% there is any change in a potential solution then the simple +% reduction process is applied. +% \end{enumerate} +% +% The process stops either when all 81 cells have been solved or there +% is no change in any potential solution after going through all the above +% reductions. +% +% There are more sophisticated solution techniques that could be applied +% but they are also increasingly difficult to code in \TeX. +% +% \begin{macro}{\reduceacell} +% \cs{reduceacell} looks at the solution set for the current cell (the +% \cs{s@lcnta} cell) and if the cell has been solved then it deletes the +% solution digit from the row, column, and box in which the cell appears. +% This may result in new solutions for other cells. +% +% Given a cell number $N$ ($080\relax + \keeponfalse + \fi + \ifanychange\else + \keeponfalse + \fi} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\keepreducingcells} +% Keep on trying the simple reduction. +% \begin{macrocode} +%% Keep performing the simple reduction +\newcommand*{\keepreducingcells}{\bgroup +\commentary{Simple reductions}% + \ifnum\difficultyctr<\tw@ + \global\difficultyctr\tw@ + \fi + \changedtrue + \loop + \ifchanged + \reduceallcells + \checksimplereductions + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\checksimplereductions} +% Determines whether or not to keep on trying simple reductions. +% \begin{macrocode} +\newcommand*{\checksimplereductions}{% + \ifchanged\else + \typesimplestatus + \fi + \ifnum\solcnt>80\relax% solution found! + \changedfalse + \fi} + +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%%%%%%%%%%%%%%%%%%%%% reduce loners %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% \end{macrocode} +% +% \begin{macro}{\reduceloners} +% Reduce via the loner digits, trying rows first, and if no change +% then trying columns, and if still no change then trying boxes. +% \begin{macrocode} +%% reduce the loner digits, per row, column and box +\newcommand*{\reduceloners}{% +\commentary{reduceloners}% + \global\lonerchangedfalse + \ifnum\difficultyctr<4\relax + \global\difficultyctr=4\relax + \fi + \ifnum\solcnt>80\else + \bgroup + \reducerowloners + \iflonerchanged\else + \reducecolloners + \iflonerchanged\else + \reduceboxloners + \fi + \fi + \typelonestatus + \egroup + \fi} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\reducerowloners} +% Loop through the rows and reduce the first loner found. +% \begin{macrocode} +%% Loop through the rows, reducing loners +\newcommand*{\reducerowloners}{% + \sumctr\z@ + \s@dnrow\@ne + \loop + \ifnum\s@dnrow<10\relax + \s@lcnta=\s@dnrow \advance\s@lcnta\m@ne + \multiply\s@lcnta 9\relax \advance\s@lcnta\@ne + \sumrowsets + \ifnum\sumctr>\z@ + \getloner{\the\sumctr}{\s@dtempcntb} + \ifnum\s@dtempcntb=\z@ + \else + \reducelonerrowcell{\the\s@lcnta}{\the\s@dtempcntb} + \iflonerchanged + \advance\s@dnrow 10\relax + \fi + \fi + \fi + \advance\s@dnrow\@ne + \repeat} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\sumrowsets} +% Add together all the solution binary sets for the unsolved cells +% in the current row (\cs{s@lcnta}). The result is in \cs{sumctr}. +% \begin{macrocode} +%% add the sets in the current row +\newcommand*{\sumrowsets}{% + \bgroup + \s@dncol=\s@lcnta + \toprangectr=\s@dncol + \advance\toprangectr 9\relax + \global\sumctr\z@ + \loop + \ifnum\s@dncol<\toprangectr + \ifnum\useknt{s@lans\the\s@dncol}>\z@ + \global\advance\sumctr\useknt{s@lans\the\s@dncol} + \fi + \advance\s@dncol\@ne + \repeat + \egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\getloner} +% \cs{getloner}\marg{setsum}\marg{cnt} examines (the sum of) a solution set +% and returns the first loner (i.e., the first occurrence of the digit 1), or +% zero if there is none. The result is converted to a solution digit and +% assigned to the \cs{count} \meta{cnt}. +% +% For example, given the set \verb?[000200110]? it will return \verb?7? (the +% set indicates two 4s, one 7, and one 8). +% \begin{macrocode} +%% get the loner from a setsum +%% \getloner{setsum}{returnctr} returnes the (first) loner in a potential set, +%% or zero +\newcommand*{\getloner}[2]{\bgroup + \ifnum #1>\z@ + \s@dtemploopcnta\@ne + \loop + \ifnum\s@dtemploopcnta<10\relax + \numofnuminset{\the\s@dtemploopcnta}{#1}{\s@dtempcnta} + \ifnum\s@dtempcnta=\@ne% found a lone digit + \s@dtempcnta=\s@dtemploopcnta + \s@dtemploopcnta=100\relax + \fi + \advance\s@dtemploopcnta\@ne + \repeat + \ifnum\s@dtemploopcnta>99 \else \s@dtempcnta=\z@ \fi + \global#2=\s@dtempcnta + \else + \s@dtempcnta=\z@ + \global#2=\s@dtempcnta + \fi +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\reducelonerowcell} +% \cs{reducelonerowcell}\marg{rowcell}\marg{digit}. +% Given (the cell at) the start of a row and a lone digit, find the cell +% in the row with that digit in its solution set, and make the digit the +% solution of that cell. +% \begin{macrocode} +%% \reducelonerowcell{startofrowcell}{digit} +%% given a row and a lone digit, find the cell containing the digit +%% and make the digit a solution of that cell. +\newcommand*{\reducelonerrowcell}[2]{\bgroup + \s@dncol=#1 + \toprangectr=\s@dncol + \advance\toprangectr 9\relax + \ifnum #2<\@ne + \advance\s@dncol 100\relax + \fi + \loop + \ifnum\s@dncol<\toprangectr + \numofnuminset{#2}{\the\useknt{s@lans\the\s@dncol}}{\lonecellctr} + \ifnum\lonecellctr=\@ne% this cell has the loner + \lonecellctr=#2 + \global\useknt{s@lans\the\s@dncol}=-\lonecellctr + \global\lonerchangedtrue + \global\advance\solcnt\@ne +\commentary{\the\solcnt\space solved (#2 loner in row starting #1)}% + \s@dncol=\toprangectr + \fi + \advance\s@dncol\@ne + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\reducecolloners} +% Loop through the columns and reduce the first loner found. +% \begin{macrocode} +%% Loop through the columns, reducing loners +\newcommand*{\reducecolloners}{\bgroup + \sumctr\z@ + \s@dncol\@ne + \loop + \ifnum\s@dncol<10\relax + \s@lcnta=\s@dncol + \sumcolsets + \ifnum\sumctr>\z@ + \getloner{\the\sumctr}{\s@dtempcntb} + \ifnum\s@dtempcntb=\z@ + \else + \reducelonercolcell{\the\s@lcnta}{\the\s@dtempcntb} + \iflonerchanged + \advance\s@dncol 10\relax + \fi + \fi + \fi + \advance\s@dncol\@ne + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\sumcolsets} +% Sum all the solution sets of the unsolved cells in the current column +% (\cs{s@lcnta}). The result is in \cs{sumctr}. +% \begin{macrocode} +%% add the sets in the current column +\newcommand*{\sumcolsets}{\bgroup + \s@dnrow=\s@lcnta + \toprangectr=\s@dnrow + \advance\toprangectr 73\relax + \global\sumctr\z@ + \loop + \ifnum\s@dnrow<\toprangectr + \ifnum\useknt{s@lans\the\s@dnrow}>\z@ + \global\advance\sumctr\useknt{s@lans\the\s@dnrow} + \fi + \advance\s@dnrow 9\relax + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\reducelonercolcell} +% \cs{reducelonercolcell}\marg{colcell}\marg{digit}. +% Given (the cell at) the start of a column and a lone digit, find the cell +% in the column with that digit in its solution set, and make the digit +% the solution of that cell. +% \begin{macrocode} +%% \reducelonercolcell{startofcolcell}{digit} +%% given a col and a lone digit, find the cell containing the digit +%% and make the digit a solution of that cell. +\newcommand*{\reducelonercolcell}[2]{\bgroup + \s@dnrow=#1 + \toprangectr=\s@dnrow + \advance\toprangectr 73\relax + \ifnum #2<\@ne + \advance\s@dnrow 7300\relax + \fi + \loop + \ifnum\s@dnrow<\toprangectr + \numofnuminset{#2}{\the\useknt{s@lans\the\s@dnrow}}{\lonecellctr} + \ifnum\lonecellctr=\@ne% this cell has the loner + \lonecellctr=#2 + \global\useknt{s@lans\the\s@dnrow}=-\lonecellctr + \global\lonerchangedtrue + \global\advance\solcnt\@ne +\commentary{\the\solcnt\space solved (#2 loner in column starting #1)}% + \s@dnrow=\toprangectr + \fi + \advance\s@dnrow 9\relax + \repeat + \egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\reduceboxloners} +% Loop through the boxes and reduce the first loner found. +% \begin{macrocode} +%% Loop through the boxes, reducing loners +\newcommand*{\reduceboxloners}{\bgroup + \sumctr\z@ + \boxctr\@ne + \loop + \ifnum\boxctr<10\relax +% \end{macrocode} +% The next bit of code calculates the corner cell of the Nth box. +% \begin{macrocode} + \ifcase\boxctr + \or \s@lcnta=\@ne + \or \s@lcnta=4\relax + \or \s@lcnta=7\relax + \or \s@lcnta=28\relax + \or \s@lcnta=31\relax + \or \s@lcnta=34\relax + \or \s@lcnta=55\relax + \or \s@lcnta=58\relax + \or \s@lcnta=61\relax + \fi + \sumboxsets + \ifnum\sumctr>\z@ + \getloner{\the\sumctr}{\s@dtempcntb} + \ifnum\s@dtempcntb=\z@ + \else + \reducelonerboxcell{\the\s@lcnta}{\the\s@dtempcntb} + \iflonerchanged + \advance\boxctr 10\relax + \fi + \fi + \fi + \advance\boxctr\@ne + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\sumboxsets} +% Sum all the solution sets of the unsolved cells in the current box +% (\cs{s@lcnta}). The result is in \cs{sumctr}. +% \begin{macrocode} +%% add the sets in the current box +\newcommand*{\sumboxsets}{\bgroup + \s@dncol=\s@lcnta + \toprangectr=\s@dncol + \advance\toprangectr 3\relax + \global\sumctr\z@ + \loop + \ifnum\s@dncol<\toprangectr + \s@dnrow=\s@dncol + \ifnum\useknt{s@lans\the\s@dnrow}>\z@ + \global\advance\sumctr\useknt{s@lans\the\s@dnrow} + \fi + \advance\s@dnrow 9\relax + \ifnum\useknt{s@lans\the\s@dnrow}>\z@ + \global\advance\sumctr\useknt{s@lans\the\s@dnrow} + \fi + \advance\s@dnrow 9\relax + \ifnum\useknt{s@lans\the\s@dnrow}>\z@ + \global\advance\sumctr\useknt{s@lans\the\s@dnrow} + \fi + \advance\s@dncol\@ne + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\reducelonerboxcell} +% \cs{reducelonerboxcell}\marg{boxcell}\marg{digit}. +% Given (the cell at) the start of a box and a lone digit, find the cell +% in the box with that digit in its solution set, and make the digit +% the solution of that cell. +% \begin{macrocode} +%% \reducelonerboxcell{startofboxcell}{digit} +%% given a box and a lone digit, find the cell containing the digit +%% and make the digit a solution of that cell. +\newcommand*{\reducelonerboxcell}[2]{\bgroup + \s@dncol=\s@lcnta + \toprangectr=\s@dncol + \advance\toprangectr 3\relax + \global\sumctr\z@ + \loop + \ifnum\s@dncol<\toprangectr + \s@dnrow=\s@dncol + \numofnuminset{#2}{\the\useknt{s@lans\the\s@dnrow}}{\lonecellctr} + \ifnum\lonecellctr=\@ne% this cell has the loner + \lonecellctr=#2 + \global\useknt{s@lans\the\s@dnrow}=-\lonecellctr + \global\lonerchangedtrue + \global\advance\solcnt\@ne +\commentary{\the\solcnt\space solved (#2 loner in box starting #1)}% + \s@dncol=\toprangectr + \fi + \iflonerchanged\else + \advance\s@dnrow 9\relax + \numofnuminset{#2}{\the\useknt{s@lans\the\s@dnrow}}{\lonecellctr} + \ifnum\lonecellctr=\@ne% this cell has the loner + \lonecellctr=#2 + \global\useknt{s@lans\the\s@dnrow}=-\lonecellctr + \global\lonerchangedtrue + \global\advance\solcnt\@ne +\commentary{\the\solcnt\space solved (#2 loner in box starting #1)}% + \s@dncol=\toprangectr + \fi + \fi + \iflonerchanged\else + \advance\s@dnrow 9\relax + \numofnuminset{#2}{\the\useknt{s@lans\the\s@dnrow}}{\lonecellctr} + \ifnum\lonecellctr=\@ne% this cell has the loner + \lonecellctr=#2 + \global\useknt{s@lans\the\s@dnrow}=-\lonecellctr + \global\lonerchangedtrue + \global\advance\solcnt\@ne +\commentary{\the\solcnt\space solved (#2 loner in box starting #1)}% + \s@dncol=\toprangectr + \fi + \fi + \advance\s@dncol\@ne + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%%%%%%%%%%%%%%%%%%%%% reduce pairs %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% \end{macrocode} +% +% \begin{macro}{\reducepairs} +% Perform pair reduction, reducing the first pair found. First try +% by row, then by column, and lastly by box. +% \begin{macrocode} +%% reduce the pairs, per row, column and box +\newcommand*{\reducepairs}{\bgroup +\commentary{reducepairs}% **************************************}% + \global\pairchangedfalse + \ifnum\difficultyctr<8\relax + \global\difficultyctr=8\relax + \fi + \ifnum\solcnt>80\else + \reducerowpairs + \ifpairchanged\else + \reducecolpairs + \ifpairchanged\else + \reduceboxpairs + \fi + \fi + \fi +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\reducerowpairs} +% Loop through the rows and reduce the first pair found. +% \begin{macrocode} +%% Loop through the rows, reducing pairs +\newcommand*{\reducerowpairs}{% + \sumctr\z@ + \s@dnrow\@ne + \loop + \ifnum\s@dnrow<10\relax + \s@lcnta=\s@dnrow \advance\s@lcnta\m@ne + \multiply\s@lcnta 9\relax \advance\s@lcnta\@ne + \sumrowsets + \ifnum\sumctr>\z@ + \reducearowpair{\the\s@lcnta} + \ifpairchanged + \advance\s@dnrow 10\relax + \fi + \fi + \advance\s@dnrow\@ne + \repeat} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\reducearowpair} +% \cs{reducearowpair}\marg{rowcell} reduces a pair in the row starting +% with cell \meta{rowcell}. +% \begin{macrocode} +%% reducearowpair{row} +\newcommand*{\reducearowpair}[1]{% + \bgroup + \s@dncol=#1\relax + \toprangectr=\s@dncol + \advance\toprangectr 9\relax + \maxrangectr=\toprangectr + \advance\maxrangectr\m@ne + \global\sumctr\z@ + \loop + \ifnum\s@dncol<\maxrangectr + \asetctr=\useknt{s@lans\the\s@dncol}% + \ifnum\asetctr>\z@ + \findrowpair + \fi + \advance\s@dncol\@ne + \repeat + \egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\findrowpair} +% \cs{findrowpair} attempts to find a pair in the current row. +% \begin{macrocode} +\newcommand*{\findrowpair}{\bgroup + \secondctr=\s@dncol + \advance\secondctr\@ne + \loop + \ifnum\secondctr<\toprangectr + \ifnum\asetctr=\useknt{s@lans\the\secondctr} + \checksetforpair{\the\asetctr} + \ifnum\numdigitsctr=\tw@ +%% first row cell is \s@lcnta +%% first pair cell is \s@dncol, second pair cell is \secondctr +%% digits are \digitictr and \digitiictr + \deleterowpairdigits + \fi + \fi + \advance\secondctr\@ne + \repeat + \egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\checksetforpair} +% \cs{checksetforpair}\marg{set} attempts to find a pair in a set. +% It sets \cs{digitictr} and \cs{digitiictr} as the first and second digits +% in the set and \cs{numdigitsctr} to the total number of digits in the +% set (which is 2 for a pair). +% \begin{macrocode} +%% \checksetforpair{set} returns with: +%% \digitictr = first digit +%% \digitiictr = second digit +%% \numdigitsctr = number of digits (2 for a pair) +\newcommand*{\checksetforpair}[1]{\bgroup + \s@dtemploopcnta\@ne + \global\numdigitsctr\z@ + \global\digitictr\z@ + \global\digitiictr\z@ + \loop + \ifnum\s@dtemploopcnta<10\relax + \numofnuminset{\the\s@dtemploopcnta}{#1}{\s@dtempcnta} + \ifnum\s@dtempcnta=\@ne + \global\advance\numdigitsctr\@ne + \ifcase\numdigitsctr + \or \global\digitictr=\s@dtemploopcnta + \or \global\digitiictr=\s@dtemploopcnta + \else \advance\s@dtemploopcnta 10\relax + \fi + \fi + \advance\s@dtemploopcnta\@ne + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\deleterowpairdigits} +% \cs{deleterowpairdigits} deletes the pair digits from non-pair cells +% in a row. The first cell in the row is \cs{s@lcnta}, the cells that +% contain the two pairs are \cs{s@dncol} and \cs{secondctr}, and the +% digits are \cs{digitictr} and \cs{digitiictr}. +% \begin{macrocode} +%% first row cell is \s@lcnta +%% first pair cell is \s@dncol, second pair cell is \secondctr +%% digits are \digitictr and \digitiictr +\newcommand*{\deleterowpairdigits}{\bgroup + \global\pairchangedfalse + \s@dtemploopcnta=\s@lcnta + \toprangectr=\s@dtemploopcnta \advance\toprangectr 9\relax + \loop + \ifnum\s@dtemploopcnta<\toprangectr + \ifnum\s@dtemploopcnta=\s@dncol + \else + \ifnum\s@dtemploopcnta=\secondctr + \else + \deletenumfromset{\the\digitictr}% + {\the\useknt{s@lans\the\s@dtemploopcnta}}{\s@dtempcnta} + \ifsetchanged + \global\useknt{s@lans\the\s@dtemploopcnta}=\s@dtempcnta + \global\pairchangedtrue + \fi + \deletenumfromset{\the\digitiictr}% + {\the\useknt{s@lans\the\s@dtemploopcnta}}{\s@dtempcnta} + \ifsetchanged + \global\useknt{s@lans\the\s@dtemploopcnta}=\s@dtempcnta + \global\pairchangedtrue + \fi + \fi + \fi + \advance\s@dtemploopcnta\@ne + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\reducecolpairs} +% Loop through the rows and reduce the first pair found. +% \begin{macrocode} +%% Loop through the columns, reducing pairs +\newcommand*{\reducecolpairs}{% + \sumctr\z@ + \s@dncol\@ne + \loop + \ifnum\s@dncol<10\relax + \s@lcnta=\s@dncol + \sumcolsets + \ifnum\sumctr>\z@ + \reduceacolpair{\the\s@lcnta} + \ifpairchanged + \advance\s@dncol 10\relax + \fi + \fi + \advance\s@dncol\@ne + \repeat} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\reduceacolpair} +% \cs{reduceacolpair}\marg{colcell} reduces a pair in the column starting +% with cell \meta{colcell}. +% \begin{macrocode} +%% reduceacolpair{col} +\newcommand*{\reduceacolpair}[1]{\bgroup + \s@dnrow=#1\relax + \toprangectr=\s@dnrow + \advance\toprangectr 73\relax + \maxrangectr=\toprangectr + \advance\maxrangectr -9\relax + \global\sumctr\z@ + \loop + \ifnum\s@dnrow<\maxrangectr + \asetctr=\useknt{s@lans\the\s@dnrow}% + \ifnum\asetctr>\z@ + \findcolpair + \fi + \advance\s@dnrow 9\relax + \repeat + \egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\findcolpair} +% \cs{findcolpair} attempts to find a pair in the current column. +% \begin{macrocode} +\newcommand*{\findcolpair}{\bgroup + \secondctr=\s@dnrow + \advance\secondctr 9\relax + \loop + \ifnum\secondctr<\toprangectr + \ifnum\asetctr=\useknt{s@lans\the\secondctr} + \checksetforpair{\the\asetctr} + \ifnum\numdigitsctr=\tw@ +%% first row cell is \s@lcnta +%% first pair cell is \s@dnrow, second pair cell is \secondctr +%% digits are \digitictr and \digitiictr + \deletecolpairdigits + \fi + \fi + \advance\secondctr 9\relax + \repeat + \egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\deletecolpairdigits} +% \cs{deletecolpairdigits} deletes the pair digits from non-pair cells +% in a column. The first cell in the column is \cs{s@lcnta}, the cells that +% contain the two pairs are \cs{s@dncol} and \cs{secondctr}, and the +% digits are \cs{digitictr} and \cs{digitiictr}. +% \begin{macrocode} +%% first col cell is \s@lcnta +%% first pair cell is \s@dnrow, second pair cell is \secondctr +%% digits are \digitictr and \digitiictr +\newcommand*{\deletecolpairdigits}{\bgroup + \global\pairchangedfalse + \s@dtemploopcnta=\s@lcnta + \toprangectr=\s@dtemploopcnta \advance\toprangectr 73\relax + \loop + \ifnum\s@dtemploopcnta<\toprangectr + \ifnum\s@dtemploopcnta=\s@dnrow + \else + \ifnum\s@dtemploopcnta=\secondctr + \else + \deletenumfromset{\the\digitictr}% + {\the\useknt{s@lans\the\s@dtemploopcnta}}{\s@dtempcnta} + \ifsetchanged + \global\useknt{s@lans\the\s@dtemploopcnta}=\s@dtempcnta + \global\pairchangedtrue + \fi + \deletenumfromset{\the\digitiictr}% + {\the\useknt{s@lans\the\s@dtemploopcnta}}{\s@dtempcnta} + \ifsetchanged + \global\useknt{s@lans\the\s@dtemploopcnta}=\s@dtempcnta + \global\pairchangedtrue + \fi + \fi + \fi + \advance\s@dtemploopcnta 9\relax + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\reduceboxpairs} +% Loop through the boxes and reduce the first pair found. +% \begin{macrocode} +%% Loop through the boxes, reducing pairs +\newcommand*{\reduceboxpairs}{\bgroup + \sumctr\z@ + \boxctr\@ne + \loop + \ifnum\boxctr<10\relax + \ifcase\boxctr + \or \s@lcnta=\@ne + \or \s@lcnta=4\relax + \or \s@lcnta=7\relax + \or \s@lcnta=28\relax + \or \s@lcnta=31\relax + \or \s@lcnta=34\relax + \or \s@lcnta=55\relax + \or \s@lcnta=58\relax + \or \s@lcnta=61\relax + \fi + \sumboxsets + \ifnum\sumctr>\z@ + \reduceaboxpair{\the\s@lcnta} + \ifpairchanged + \advance\boxctr 10\relax + \fi + \fi + \advance\boxctr\@ne + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\getnthboxcell} +% \cs{getnthboxcell}\marg{n}\marg{firstcell}\marg{cnt}. Given the first cell +% (\meta{firstcell}) in a box and a number, \meta{n}, between 1 and 9, set +% the \cs{count} \meta{cnt} to the cell number of the \meta{n}th cell in the +% box. +% \begin{macrocode} +%% \getnthboxcell{n}{firstcell}{returnctr} +\newcommand*{\getnthboxcell}[3]{\bgroup + \s@dtempcnta=#2 + \ifcase#1 + \or + \or \advance\s@dtempcnta 9\relax + \or \advance\s@dtempcnta 18\relax + \or \advance\s@dtempcnta \@ne + \or \advance\s@dtempcnta 10\relax + \or \advance\s@dtempcnta 19\relax + \or \advance\s@dtempcnta \tw@ + \or \advance\s@dtempcnta 11\relax + \or \advance\s@dtempcnta 20\relax + \fi + \global #3=\s@dtempcnta +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\reduceaboxpair} +% \cs{reduceaboxpair}\marg{boxcell} reduces a pair in the box starting +% with cell \meta{boxcell}. +% \begin{macrocode} +%% \reduceaboxpair{startofboxcell} +\newcommand*{\reduceaboxpair}[1]{\bgroup + \s@dtemploopcnta\@ne + \toprangectr=\s@dtemploopcnta + \advance\toprangectr 9\relax + \maxrangectr=\toprangectr + \advance\maxrangectr\m@ne + \loop + \ifnum\s@dtemploopcnta<\maxrangectr + \getnthboxcell{\the\s@dtemploopcnta}{#1}{\s@dtempcnta} + \asetctr=\useknt{s@lans\the\s@dtempcnta} + \ifnum\asetctr>\z@ + \s@dnrow=\s@dtemploopcnta + \findboxpair{#1} + \fi + \advance\s@dtemploopcnta\@ne + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\findboxpair} +% \cs{findboxpair} attempts to find a pair in the current box, and then does +% a pair reduction for the box. +% \begin{macrocode} +%% \findboxpair{startofboxcell} +\newcommand*{\findboxpair}[1]{% + \bgroup + \secondctr=\s@dtemploopcnta + \advance\secondctr\@ne + \loop + \ifnum\secondctr<\toprangectr + \getnthboxcell{\the\secondctr}{#1}{\s@dtempcntb} + \ifnum\asetctr=\useknt{s@lans\the\s@dtempcntb} + \checksetforpair{\the\asetctr} + \ifnum\numdigitsctr=\tw@ +%% first box cell is #1 (=\s@lcnta) +%% first pair cell is \s@dnrow, second pair cell is \secondctr +%% digits are \digitictr and \digitiictr + \deleteboxpairdigits{#1} + \fi + \fi + \advance\secondctr \@ne + \repeat + \egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\deleteboxpairdigits} +% \cs{deleteboxpairdigits}\marg{boxcell} deletes the pair digits from +% non-pair cells +% in a box. The first cell in the box is \meta{boxcell}, the cells that +% contain the two pairs are \cs{s@dnrow} and \cs{secondctr}, and the +% digits are \cs{digitictr} and \cs{digitiictr}. +% \begin{macrocode} +%% first box cell is #1 +%% first pair cell is \s@dnrow, second pair cell is \secondctr +%% digits are \digitictr and \digitiictr +\newcommand*{\deleteboxpairdigits}[1]{\bgroup + \global\pairchangedfalse + \s@dtemploopcnta=\@ne + \toprangectr=\s@dtemploopcnta \advance\toprangectr 9\relax + \loop + \ifnum\s@dtemploopcnta<\toprangectr + \ifnum\s@dtemploopcnta=\s@dnrow + \else + \ifnum\s@dtemploopcnta=\secondctr + \else + \getnthboxcell{\the\s@dtemploopcnta}{#1}{\s@dtempcntb} + \deletenumfromset{\the\digitictr}% + {\the\useknt{s@lans\the\s@dtempcntb}}{\s@dtempcnta} + \ifsetchanged + \global\useknt{s@lans\the\s@dtempcntb}=\s@dtempcnta + \global\pairchangedtrue + \fi + \deletenumfromset{\the\digitiictr}% + {\the\useknt{s@lans\the\s@dtempcntb}}{\s@dtempcnta} + \ifsetchanged + \global\useknt{s@lans\the\s@dtempcntb}=\s@dtempcnta + \global\pairchangedtrue + \fi + \fi + \fi + \advance\s@dtemploopcnta \@ne + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Checking the solution} +% +% \begin{macrocode} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% check solution %%%%%%%%%%%%%%%%%%%%%%%%% + +% \end{macrocode} +% +% We have found a solution when all the binary sets are negative. +% It's less efficient, but probably more useful, to check each +% row, column, and block (3 times 81 tests instead of 81). +% +% \begin{macro}{\checksolution} +% Check the solution by rows, columns, and boxes. +% \begin{macrocode} +\newcommand*{\checksolution}{% + \checkrows + \checkcols + \checkboxes} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\checkrows} +% Check the row solutions. A row is said to be correct if a solution has +% been assigned to each cell in the row, thus relying on the assumption +% that the solver never makes a mistake. The check is not sufficient for +% a solution obtained in another manner. +% \begin{macrocode} +\newcommand*{\checkrows}{% + \sumctr\z@ + \s@dnrow\@ne + \loop + \ifnum\s@dnrow<10\relax + \s@lcnta=\s@dnrow \advance\s@lcnta\m@ne + \multiply\s@lcnta 9\relax \advance\s@lcnta\@ne + \sumrowsets + \ifnum\sumctr=\z@\else +\typeout{Row \the\s@dnrow\space is incorrect}% + Row \the\s@dnrow\space is incorrect. \\ + \fi + \advance\s@dnrow\@ne + \repeat} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\checkcols} +% Check the column solutions. +% \begin{macrocode} +\newcommand*{\checkcols}{% +\bgroup + \sumctr\z@ + \s@dncol\@ne + \loop + \ifnum\s@dncol<10\relax + \s@lcnta=\s@dncol + \sumcolsets + \ifnum\sumctr=\z@\else +\typeout{Column \the\s@dncol\space is incorrect}% + Column \the\s@dncol\space is incorrect. \\ + \fi + \advance\s@dncol\@ne + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\checkboxes} +% Check the box solutions. +% \begin{macrocode} +\newcommand*{\checkboxes}{% +\bgroup + \sumctr\z@ + \boxctr\@ne + \loop + \ifnum\boxctr<10\relax +\ifcase\boxctr +\or \s@lcnta=\@ne +\or \s@lcnta=4\relax +\or \s@lcnta=7\relax +\or \s@lcnta=28\relax +\or \s@lcnta=31\relax +\or \s@lcnta=34\relax +\or \s@lcnta=55\relax +\or \s@lcnta=58\relax +\or \s@lcnta=61\relax +\fi + \sumboxsets + \ifnum\sumctr=\z@\else +\typeout{Box \the\boxctr\space is incorrect}% + Box \the\boxctr\space is incorrect. \\ + \fi + \advance\boxctr\@ne + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\typesimplestatusX} +% May be used to display the cuurrent status of the (partial) solution +% following simple reductions. +% \begin{macrocode} +%% typeset the current status of the partial solution +\newcommand*{\typesimplestatusX}{% +\par\noindent\begin{minipage}{\linewidth} +\begin{center} +Simple reductions stopped (with \the\solcnt\space solutions)\\ +%\footnotesize +\displaystatus +\end{center} +\end{minipage}} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\typelonestatusX} +% May be used to display the current status of the (partial) solution after a +% loner reduction. +% \begin{macrocode} +%% typeset the current status after loner processing +\newcommand*{\typelonestatusX}{% +\par\noindent\begin{minipage}{\linewidth} +\begin{center} +Loners processed (with \the\solcnt\space solutions)\\ +%\footnotesize +\displaystatus +\end{center} +\end{minipage}} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hideprogress} +% \begin{macro}{\showprogess} +% Normally the progress towards a solution is not displayed. It will be +% displayed in the document, though, after the \cs{showprogress} declaration. +% The \cs{hideprogress} declaration switches off the displays. +% \begin{macrocode} +%% For curiosity as to how a solution is developing call the \showprogess +%% declaration (\hideprogess turns this off). +\newcommand*{\hideprogress}{% + \let\typesimplestatus\relax + \let\typelonestatus\relax} +\newcommand*{\showprogress}{% + \let\typesimplestatus\typesimplestatusX + \let\typelonestatus\typelonestatusX} +\hideprogress +%\showprogress + +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macrocode} +%%%%%%%%%%%%%%%%%% write solution to a game file %%%%%%%%%%%%%%% + +% \end{macrocode} +% +% \begin{macro}{\sudsolnfile} +% \begin{macro}{\writegame} +% \cs{writegame} writes the (partial) solution to the file \cs{sudsolnfile} +% (default \file{sud.out}). +% \begin{macrocode} +%% write out the solution to game file \sudsolnfile. +\newcommand*{\sudsolnfile}{sud.out} +\newcommand*{\writegame}{% + \immediate\closeout\s@dwrite + \immediate\openout\s@dwrite=\sudsolnfile + \s@dnrow\@ne + \loop + \ifnum\s@dnrow<81\relax + \gatherline{\the\s@dnrow} + \immediate\write\s@dwrite{\sudaline} + \advance\s@dnrow 9\relax + \repeat + \immediate\closeout\s@dwrite} + +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\gatherline} +% \begin{macro}{\sudaline} +% \cs{gatherline}\marg{rowstartcell} collects the solutions from one +% row in the grid +% and converts them into the corresponding characters for one line +% in a sudoku file, putting the characters into the \cs{sudaline} macro. +% \begin{macrocode} +%% \gatherline{colstart} +%% collect all the characters for one line in a game file +\newcommand*{\gatherline}[1]{\bgroup + \gdef\sudaline{} + \s@dncol=#1\relax + \toprangectr=\s@dncol + \advance\toprangectr 9\relax + \loop + \ifnum\s@dncol<\toprangectr + \s@dtempcnta=\useknt{s@lans\the\s@dncol} + \ifnum\s@dtempcnta>\m@ne + \g@addto@macro{\sudaline}{.} + \else + \s@dtempcnta=-\s@dtempcnta + \ifcase\s@dtempcnta + \or \g@addto@macro{\sudaline}{1} + \or \g@addto@macro{\sudaline}{2} + \or \g@addto@macro{\sudaline}{3} + \or \g@addto@macro{\sudaline}{4} + \or \g@addto@macro{\sudaline}{5} + \or \g@addto@macro{\sudaline}{6} + \or \g@addto@macro{\sudaline}{7} + \or \g@addto@macro{\sudaline}{8} + \or \g@addto@macro{\sudaline}{9} + \else \g@addto@macro{\sudaline}{.} + \fi + \fi + \advance\s@dncol\@ne + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macrocode} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% THE END GOAL %%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%% \sudoksolve{} %%%%%%%%%%%%%%%%%%%%%% + +% \end{macrocode} +% +% \begin{macro}{\sudokusolve} +% \cs{sudokesolve}\marg{file} reads a sudoku puzzle from the \meta{file} +% sudoku file, typesets the problem, does its best to solve it. +% It writes the solution to the \cs{sudsolnfile} file, then reads +% it back in again and typesets it. +% \begin{macrocode} +%% Read in and typeset the problem, solve it, and typeset the answer +\newcommand{\sudokusolve}[1]{% + \begin{center} + \sudoku{#1}% + \end{center} + \getproblem{#1}% + \reduceallcells + \keepreducing + \writegame + \noindent\begin{minipage}{\linewidth} + THE ANSWER + \begin{center} + \cluefont\normalsize + \cellsize{1.5\baselineskip} + \sudoku{\sudsolnfile} + \end{center} + \end{minipage}} + +% \end{macrocode} +% \end{macro} +% +% +% The end of the package. +% \begin{macrocode} +% +% \end{macrocode} +% +% +% \subsection{The \Lpack{createsudoku} package} +% +% The \Lpack{createsudoku} package lets you automatically generate +% Sudoku puzzles. The package requires Donald Arseneau's \file{random.tex} +% and also the \Lpack{solvesudoku} package, which in turn +% requires the \Lpack{printsudoku} package. +% +% \begin{macrocode} +%<*create> +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{createsudoku}[2006/02/16 v1.0 create sudoku puzzles] +\input{random} +\RequirePackage{solvesudoku} + +% \end{macrocode} +% +% \begin{macro}{\oldcommentary} +% \begin{macro}{\commentary} +% \begin{macro}{\gencommentary} +% To avoid clutter it's a good +% idea to switch off \Lpack{solvesudoku}'s commentary. On the other hand +% it could be useful for this package to provide its own commentary. +% \begin{macrocode} +\let\oldcommentary\commentary +\let\commentary\@gobble +\newcommand*{\gencommentary}[1]{\typeout{#1}} + +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\genfile} +% \begin{macro}{\prevfile} +% \begin{macro}{\currfile} +% We need a file to write out the puxzzle to, and we also need two +% temporary files. +% \begin{macrocode} +\newcommand*{\genfile}{gensud.sud} +\newcommand*{\prevfile}{genprev.sdx} +\newcommand*{\currfile}{gencurr.sdx} + +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\randomi} +% \begin{macro}{\setsudrandom} +% This sets the seed for the random number generator. The default is +% setting it to -1, which makes the seed depend on the date and time. +% \begin{macrocode} +\randomi\m@ne +\newcommand*{\setsudrandom}[1]{% + \randomi=#1\relax + \ifnum\randomi<\@ne\else + \nextrandom \nextrandom \nextrandom + \typeout{random initialised to #1}% + \fi} + +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\generategrid} +% \begin{macro}{\printsudresults} +% \cs{generategrid}\oarg{file} generates a new puzzle. If the sudoko file +% \meta{file} is specified this is taken for the starting grid, otherwise +% a default one is used. The starting grid should be a complete solution. +% +% The pairs of rows, and pairs of columns, in the starting grid are +% exchanged in a random fashion (\cs{swaps}) and then the cell solutions +% are eliminated (\cs{elimclues}) until the puzzle is sufficiently complicated. +% \begin{macrocode} +\newcommand*{\generategrid}[1][\@empty]{% + \ifx\@empty #1 + \writestartgrid + \getproblem{\prevfile} + \else + \getproblem{#1} + \fi + \swaps + \elimclues + \printsudresults} +\newcommand*{\printsudresults}{% + \sudokusolve{\genfile}% + } + +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\writestartgrid} +% Write out an initial fully solved grid to \cs{prevfile}. +% \begin{macrocode} +%% the starting data +\newcommand*{\writestartgrid}{% + \immediate\closeout\s@dwrite + \immediate\openout\s@dwrite=\prevfile + \immediate\write\s@dwrite{123456789} + \immediate\write\s@dwrite{456789123} + \immediate\write\s@dwrite{789123456} + \immediate\write\s@dwrite{234567891} + \immediate\write\s@dwrite{567891234} + \immediate\write\s@dwrite{891234567} + \immediate\write\s@dwrite{345678912} + \immediate\write\s@dwrite{678912345} + \immediate\write\s@dwrite{912345678} + \immediate\closeout\s@dwrite} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\swaps} +% \cs{swaps} randomly exchanges the contents of pairs of columns and pairs +% of rows. In order to preserve the number uniqueness constraint for boxes, +% only pairs of columns/rows that are in the same box may be exchanged. +% \begin{macrocode} +\newcommand*{\swaps}{\bgroup + \setrannum{\maxrangectr}{36}{48}% +\gencommentary{number of swaps (36--48) = maxrangectr = \the\maxrangectr} + \s@dtemploopcnta\@ne + \loop + \ifnum\s@dtemploopcnta<\maxrangectr + \setrannum{\s@dtempcntb}{1}{18}% +%%\typeout{\space\space\space swap no \the\s@dtemploopcnta\space is \the\s@dtempcntb} + \ifcase\s@dtempcntb + \or \swapcolpair{1}{2}% + \or \swapcolpair{1}{3}% + \or \swapcolpair{2}{3}% + \or \swapcolpair{4}{5}% + \or \swapcolpair{4}{6}% + \or \swapcolpair{5}{6}% + \or \swapcolpair{7}{8}% + \or \swapcolpair{7}{9}% + \or \swapcolpair{8}{9}% + \or \swaprowpair{1}{10}% + \or \swaprowpair{1}{19}% + \or \swaprowpair{10}{19}% + \or \swaprowpair{28}{37}% + \or \swaprowpair{28}{46}% + \or \swaprowpair{37}{46}% + \or \swaprowpair{55}{64}% + \or \swaprowpair{55}{73}% + \or \swaprowpair{64}{73}% + \fi + \advance\s@dtemploopcnta\@ne + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\swaprowpair} +% \cs{swaprowpair}\marg{rowstartcell1}\marg{rowstartcell2} swaps the +% contents of the two rows starting at \meta{rowstartcell1} and +% \meta{rowstartcell2}. +% \begin{macrocode} +%% swap the data in rows starting at #1, and #2 +\newcommand*{\swaprowpair}[2]{\bgroup + \s@dncol=#1\relax + \s@dcolpos=#2\relax + \s@dtemploopcnta\@ne + \maxrangectr=10\relax + \loop + \ifnum\s@dtemploopcnta<\maxrangectr + \s@dtempcnta=\useknt{s@lans\the\s@dncol}% + \global\useknt{s@lans\the\s@dncol}=\useknt{s@lans\the\s@dcolpos}% + \global\useknt{s@lans\the\s@dcolpos}=\s@dtempcnta + \advance\s@dncol\@ne + \advance\s@dcolpos\@ne + \advance\s@dtemploopcnta\@ne + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\swapcolpair} +% \cs{swapcolpair}\marg{colstartcell1}\marg{colowstartcell2} swaps the +% contents of the two columns starting at \meta{colstartcell1} and +% \meta{colstartcell2}. +% \begin{macrocode} +%% swap the data in cols starting #1 and #2 +\newcommand*{\swapcolpair}[2]{\bgroup + \s@dnrow=#1\relax + \s@drowpos=#2\relax + \s@dtemploopcnta\@ne + \maxrangectr=10\relax + \loop + \ifnum\s@dtemploopcnta<\maxrangectr + \s@dtempcnta=\useknt{s@lans\the\s@dnrow}% + \global\useknt{s@lans\the\s@dnrow}=\useknt{s@lans\the\s@drowpos}% + \global\useknt{s@lans\the\s@drowpos}=\s@dtempcnta + \advance\s@dnrow 9\relax + \advance\s@drowpos 9\relax + \advance\s@dtemploopcnta\@ne + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\elimclues} +% \cs{elimclues} first eliminates a set of clues from the (full) grid, writing +% the resulting puzzle to the two temporary files \cs{prevfile} and +% \cs{currfile}. It +% then eliminates clues one-by-one until the puzzle has been finally +% generated, the result having been written to the \cs{prevfile}, +% then writing it out to the file \cs{genfile}. +% \begin{macrocode} +\newcommand*{\elimclues}{\bgroup + \initialelimination + \writestate{\prevfile}% + \writestate{\currfile}% + \elimcluesonebyone + \getproblem{\prevfile} + \writestate{\genfile} +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\elimseventeen} +% \cs{elimseventeen} randomly eliminates the solutions for 17 cells in the +% grid (apparently if two numbers are completely eliminated as clues in a +% puzzle, then at best the solution is ambiguous). +% \begin{macrocode} +\newcommand*{\elimseventeen}{\bgroup + \s@dtemploopcnta\@ne + \maxrangectr 18\relax + \loop + \ifnum\s@dtemploopcnta<\maxrangectr + \setrannum{\s@dtempcnta}{1}{81} + \global\useknt{s@lans\the\s@dtempcnta}=111111111\relax + \advance\s@dtemploopcnta\@ne + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\elimcross} +% Eliminate all solutions in column 5 and row 5. +% \begin{macrocode} +%% eliminates all clues in column 5 and row 5 +\newcommand*{\elimcross}{\bgroup + \s@dtemploopcnta 5\relax + \loop + \ifnum\s@dtemploopcnta<78\relax% 78 = 5 + 73 + \global\useknt{s@lans\the\s@dtemploopcnta}=111111111\relax + \advance\s@dtemploopcnta 9\relax + \repeat + \s@dtemploopcnta 37\relax + \loop + \ifnum\s@dtemploopcnta<46\relax% 46 = 37 + 9 + \global\useknt{s@lans\the\s@dtemploopcnta}=111111111\relax + \advance\s@dtemploopcnta \@ne + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\elimnum} +% \cs{elimnum}\marg{num} (\verb?0 < num < 10?) eliminates all +% instances of the \meta{num} solution from the grid. +% \begin{macrocode} +\newcommand*{\elimnum}[1]{\bgroup + \s@dtemploopcnta\@ne + \loop + \ifnum\s@dtemploopcnta<82\relax + \ifnum\useknt{s@lans\the\s@dtemploopcnta}=-#1\relax + \global\useknt{s@lans\the\s@dtemploopcnta}=111111111\relax + \fi + \advance\s@dtemploopcnta \@ne + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\elimcrossandnines} +% Eliminate all 9's and the solutions in column 5 and row 5. +% \begin{macrocode} +\newcommand*{\elimcrossandnines}{\bgroup + \elimcross + \s@dtemploopcnta\@ne + \loop + \ifnum\s@dtemploopcnta<82\relax + \ifnum\useknt{s@lans\the\s@dtemploopcnta}=-9\relax + \global\useknt{s@lans\the\s@dtemploopcnta}=111111111\relax + \fi + \advance\s@dtemploopcnta \@ne + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\elimex} +% Eliminate all solutions on the diagonals of the grid. +% \begin{macrocode} +\newcommand*{\elimex}{\bgroup + \s@dtemploopcnta\@ne + \loop + \ifnum\s@dtemploopcnta<82\relax + \global\useknt{s@lans\the\s@dtemploopcnta}=111111111\relax + \advance\s@dtemploopcnta 10\relax + \repeat + \s@dtemploopcnta=9\relax + \loop + \ifnum\s@dtemploopcnta<81\relax + \global\useknt{s@lans\the\s@dtemploopcnta}=111111111\relax + \advance\s@dtemploopcnta 8\relax + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\elimcrossandex} +% Eliminate all solutions in column 5 and row 5 and on the diagonals. +% \begin{macrocode} +\newcommand*{\elimcrossandex}{\bgroup + \elimcross + \elimex +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\elimcrossandexandnines} +% Eliminate all solutions in column 5 and row 5 and on the diagonals, +% and all 9's. +% \begin{macrocode} +\newcommand*{\elimcrossandexandnines}{\bgroup + \elimcross + \elimex + \elimnum{9} +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\initialelimination} +% \cs{initialelimination} eliminates an initial set of solutions from the grid. +% Several predefined sets are provided. +% \begin{macrocode} +\let\initialelimination\elimseventeen +\let\initialelimination\elimcross +\let\initialelimination\elimcrossandnines +\let\initialelimination\elimcrossandex +\let\initialelimination\elimcrossandexandnines + +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\toomanyloops} +% \begin{macro}{\elimcluesonebyone} +% Eliminate solutions from the grid one-by-one until the puzzle cannot be +% solved. Then reinstate the last solution deleted to produce the final puzzle. +% I'm not sure if this is needed, but just in case the process stops after +% 81 attempts to remove solutions (highly unlikely but the random number +% generator could keep producing numbers corresponding to clueless cells). +% +% We use the \cs{currfile} and \cs{prevfile} to hold the current state of +% affairs and the previous state. +% \begin{macrocode} +\newcount\toomanyloops +\newcommand*{\elimcluesonebyone}{\bgroup +%%%\typeout{***elimcluesonebyone} +\toomanyloops\z@ + \s@dtempcntb=81\relax + \loop + \ifnum\s@dtempcntb>80\relax +\advance\toomanyloops\@ne +% \end{macrocode} +% Read the current puzzle from \cs{currfile} and try to solve it. +% \begin{macrocode} + \getproblem{\currfile} + \trysolution + \ifnum\solcnt=81\relax % can delete another clue +% \end{macrocode} +% The puzzle was solvable so try deleting another clue. Read the (unsolved) +% puzzle again from \cs{currfile} and write its state to \cs{prevfile}. +% \begin{macrocode} + \getproblem{\currfile} + \writestate{\prevfile} +% \end{macrocode} +% Now delete a clue, writing the resultant puzzle to \cs{currfile}, and +% go round the loop again. +% \begin{macrocode} + \deleteaclue + \writestate{\currfile}% + \s@dtempcntb=81\relax + \else % done +% \end{macrocode} +% The puzzle was not solvable, and the state before the last clue deletion +% is in file \cs{prevfile}. +% \begin{macrocode} + \typeout{Solver failed, solcnt = \the\solcnt} + \s@dtempcntb=\@ne + \fi + \ifnum\toomanyloops>80\relax + \typeout{Too much looping} + \s@dtempcntb=\@ne + \fi + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\ifacluenotdeleted} +% \begin{macro}{\deleteaclue} +% Keep calling the random number generator until it returns a cell that has +% a solution, +% then delete the solution. +% \begin{macrocode} +\newif\ifacluenotdeleted +\newcommand*{\deleteaclue}{\bgroup + \acluenotdeletedtrue + \loop + \ifacluenotdeleted + \setrannum{\s@dtempcnta}{1}{81}% + \ifnum\useknt{s@lans\the\s@dtempcnta}<\z@% found a clue + \gencommentary{Deleting clue for cell \the\s@dtempcnta}% + \global\useknt{s@lans\the\s@dtempcnta}=111111111\relax + \acluenotdeletedfalse + \fi + \repeat +\egroup} + +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\trysolution} +% \cs{trysolution} attempts to solve the current puzzle state. +% \begin{macrocode} +\newcommand*{\trysolution}{\bgroup + \reduceallcells + \keepreducing +\egroup} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\writestate} +% \cs{writestate}\marg{file} writes the current state (clues and blanks) +% to the sudoku file \meta{file}. +% \begin{macrocode} +%% \writestate{} +\newcommand*{\writestate}[1]{\bgroup + \immediate\closeout\s@dwrite + \immediate\openout\s@dwrite=#1 + \s@dnrow\@ne + \loop + \ifnum\s@dnrow<81\relax + \gatherline{\the\s@dnrow}% + \immediate\write\s@dwrite{\sudaline}% + \advance\s@dnrow 9\relax + \repeat + \immediate\closeout\s@dwrite +\egroup} + +% \end{macrocode} +% \end{macro} +% The end of the package. +% \begin{macrocode} +% +% \end{macrocode} +% +% \section{Example sudoku puzzles} +% +% LaTeXing the following file will provide you with a selection of Sudoku +% puzzles. You can try solving them yourself and/or get Latex to do it for +% you. The \Lpack{solvesudoku} package is able to solve most, but not all +% of the puzzles. +% +% \begin{macrocode} +%<*examples> +\documentclass[twoside]{article} +\usepackage{comment} +\usepackage{url} +\usepackage{printsudoku} +\newcommand*{\Lpack}[1]{\textsf{#1}} +\title{Example Sudoku Puzzles} +\author{Peter Wilson} +\date{16 February 2006} +\raggedbottom +\begin{document} +\maketitle + + A Sudoku puzzle consists of a 9 by 9 array of squares, some of which have +numbers in them, the numbers ranging from 1 through 9. The problem is to +fill in all the squares such that each row, column, and 3 by 3 box includes +the numbers 1 through 9 with no repetitions. + + This is a collection of some 54 Sudoku puzzles which I have culled +from various places. The sources include, among others: +the \emph{Sudoku Solver}~\cite{SSBL} website (labelled SE, SM, SH and SVH), +\emph{The Daily Telegraph}~\cite{DT2} (labelled TG, TM, and TT), +\emph{The Seattle Times} (labelled ST), +and some automatically generated by the \Lpack{createsudoku} +package~\cite{SUDOKUBUNDLE} (labelled CS). + +You can try solving them yourself and/or get +LaTeX to do it for +you. The \Lpack{solvesudoku} package~\cite{SUDOKUBUNDLE} is able to solve +most, but not all of the puzzles. Other LaTeX packages may do better or worse. + + The puzzles are presented in approximately increasing order of difficulty. +Each source, though, has its own set of categories which don't necessarily +agree with each other (and sometimes not within one source). I have included +an indication of the difficulty as stated by the relevant source. + +The parameters for the puzzles created via \Lpack{createsudoku} are given in +the table. + +\begin{table}[hbp] +\centering +\begin{tabular}{lll} \hline +Number & Seed & \verb?initialelimination? \\ \hline +CS1 & 1505263462 & \verb?\elimcrossandexandnines? \\ +CS2 & 1495929734 & \verb?\elimcrossandex? \\ +CS3 & 1487762722 & \verb?\elimcrossandexandnines? \\ +CS4 & 1508763610 & \verb?\elimcrossandex? \\ +CS5 & 839068723 & \verb?\elimseventeen? \\ +CS6 & 833235143 & \verb?\elimcrossandexandnines? \\ \hline +\end{tabular} +\end{table} + +\cleardoublepage + +\cluefont{\LARGE} +\cellsize{2.25\baselineskip} + +\markboth{EASY}{EASY} +\pagestyle{headings} + +\renewcommand*{\puzzlefile}{se5.sud} +\writepuzzle% +{.2...5863}{56.2.3.9.}{.3...7251}% +{..975....}{..6..47.9}{.7..286..}% +{6.58...7.}{8....1..6}{3.7.6..4.}% +[SSBL easy 5] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +SE5 (easy) \\ +\sudoku{se5.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{se10.sud} +\writepuzzle% +{..6.497..}{.82.1.6..}{79..8.145}% +{649.5.27.}{..7.6..5.}{.3..72.96}% +{.2....81.}{.7..28...}{......5.7}% +[SSBL easy 10] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +SE10 (easy) \\ +\sudoku{se10.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{se15.sud} +\writepuzzle% +{4.67.39.2}{..16.84..}{.7...4..1}% +{5...4.21.}{.2.....6.}{.68.7...9}% +{6..5...9.}{..24.93..}{9.53.17.4}% +[SSBL easy 15] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +SE15 (easy) \\ +\sudoku{se15.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{se20.sud} +\writepuzzle% +{36.9..5..}{..54.8.2.}{.....78.9}% +{2....3.68}{.83.9....}{.4.7..2.3}% +{6.71..3..}{13.8.59.2}{..9.7..56}% +[SSBL easy 20] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +SE20 (easy) \\ +\sudoku{se20.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{se25.sud} +\writepuzzle% +{....63.5.}{6.5.1.839}{..1...2..}% +{823...7..}{.5...7...}{.64.9...1}% +{4.25796.3}{.9.1.65.8}{.1...89.7}% +[SSBL easy 25] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +SE25 (easy) \\ +\sudoku{se25.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{se30.sud} +\writepuzzle% +{.3.12....}{1.87..4.6}{..98....1}% +{5....7.3.}{.73.9.2.4}{.92..65..}% +{.4...8.5.}{3...7...8}{2..4.596.}% +[SSBL easy 30] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +SE30 (easy) \\ +\sudoku{se30.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tg5.sud} +\writepuzzle% +{.6.1.9.8.}{.19...74.}{2.......1}% +{..79.26..}{.3.....2.}{..14.35..}% +{1.......5}{.75...23.}{.9.5.6.7.}% +[DT2 gentle 5] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +TG5 (gentle) \\ +\sudoku{tg5.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tg10.sud} +\writepuzzle% +{....96..4}{..1.....2}{56...8...}% +{2.8....9.}{9.63.52.7}{.3....4.6}% +{...9...58}{7.....9..}{8..45....}% +[DT2 gentle 10] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +TG10 (gentle) \\ +\sudoku{tg10.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tg15.sud} +\writepuzzle% +{...1.8...}{.57...18.}{98.....26}% +{..67419..}{.........}{..42536..}% +{72.....94}{.19...73.}{...3.9...}% +[DT2 gentle 15] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +TG15 (gentle) \\ +\sudoku{tg15.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tg20.sud} +\writepuzzle% +{...7.9...}{.8.3.6.5.}{7.9...6.8}% +{..42.18..}{.6.....4.}{..35.41..}% +{9.2...5.7}{.4.8.7.1.}{...1.2...}% +[DT2 gentle 20] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +TG20 (gentle) \\ +\sudoku{tg20.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tg25.sud} +\writepuzzle% +{7..4..5..}{.61..5.7.}{.9.7.1..6}% +{8...27...}{.........}{...34...1}% +{1..8.2.3.}{.7.1..62.}{..3..9..7}% +[DT2 gentle 25] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +TG25 (gentle) \\ +\sudoku{tg25.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tg30.sud} +\writepuzzle% +{37.4.....}{9....61.4}{....23...}% +{.4.1..9..}{.12...79.}{..5..7.4.}% +{...36....}{4.32....6}{.....9.57}% +[DT2 gentle 30] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +TG30 (gentle) \\ +\sudoku{tg30.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{st1226.sud} +\writepuzzle% +{9....4.31}{7452.....}{.8..674..}% +{.26.4...5}{5..6.9..8}{4...2.37.}% +{..759..6.}{.....1823}{21.3....7}% +[Seattle Times 2005/12/26 1 star] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +ST1226 (1 star) \\ +\sudoku{st1226.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{st0206.sud} +\writepuzzle% +{17.42...5}{..2.1..96}{849..3...}% +{....718..}{.25...67.}{..826....}% +{...5..749}{53..9.1..}{6...48.23}% +[Seattle Times 2005/02/06 1 star] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +ST0206 (1 star) \\ +\sudoku{st0206.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{st0213.sud} +\writepuzzle% +{.94.2...7}{.36...1.5}{28.35....}% +{..92...5.}{6.21.49.8}{.7...63..}% +{....13.46}{1.5...78.}{8...4.29.}% +[Seattle Times 2006/02/13 1 star] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +ST0213 (1 star) \\ +\sudoku{st0213.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{cs1.sud} +\writepuzzle% +{.46..731.}{2.36.4...}{87.3.1.45}% +{657...423}{.........}{.81...756}% +{43.8.6..1}{7..2..5.4}{..25.386.}% +[CreateSudoku 1 (level 2)] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +CS1 (level 2) \\ +\sudoku{cs1.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{cs2.sud} +\writepuzzle% +{.7.3.265.}{...6..9.7}{64.9.8.2.}% +{..9...765}{.........}{756...4.2}% +{29.5...76}{...2.15.3}{..4..7.1.}% +[CreateSudoku 2 (level 2)] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +CS2 (level 2) \\ +\sudoku{cs2.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{cs3.sud} +\writepuzzle% +{.5.8.71..}{..35.....}{78.2.1.56}% +{.34...8.1}{.........}{8.1...56.}% +{.4.7.6.12}{...4.36.8}{.781..34.}% +[CreateSudoku 3 (level 2)] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +CS3 (level 2) \\ +\sudoku{cs3.sud} +\end{center}\end{minipage} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% moderate + +\clearpage +\markboth{MODERATE}{MODERATE} + +\renewcommand*{\puzzlefile}{sm5.sud} +\writepuzzle% +{..76..24.}{.46....9.}{92..85...}% +{8....29..}{..3...4..}{..49....6}% +{...73..24}{.5....86.}{.32..67..}% +[SSBL medium 5] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +SM5 (medium) \\ +\sudoku{sm5.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{sm10.sud} +\writepuzzle% +{..57.82..}{4.......6}{.7..6..8.}% +{52.9.4.31}{.........}{86.1.7.54}% +{.9..3..6.}{7.......5}{..24.61..}% +[SSBL medium 10] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +SM10 (medium) \\ +\sudoku{sm10.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{sm15.sud} +\writepuzzle% +{85...4..2}{4...2.9..}{...8...7.}% +{..6.....1}{.4..8..3.}{2.....5..}% +{.34..7...}{.87.9...6}{6..1...47}% +[SSBL medium 15] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +SM15 (medium) \\ +\sudoku{sm15.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{sm20.sud} +\writepuzzle% +{..34.2.97}{..4....2.}{.7.6....8}% +{....9....}{.38...47.}{....1....}% +{4....5.1.}{.5....6..}{72.3.19..}% +[SSBL medium 20] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +SM20 (medium) \\ +\sudoku{sm20.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{sm25.sud} +\writepuzzle% +{...4.79..}{7.6...2..}{..5..83.6}% +{56..298..}{..8..1...}{.3.7....5}% +{.......38}{....93...}{.4.5.....}% +[SSBL medium 25] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +SM25 (medium) \\ +\sudoku{sm25.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{sm30.sud} +\writepuzzle% +{..58.....}{....79...}{..461..7.}% +{.5.3....4}{.23...65.}{9....8.3.}% +{.3..572..}{...42....}{.....61..}% +[SSBL medium 30] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +SM30 (medium) \\ +\sudoku{sm30.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tm35.sud} +\writepuzzle% +{5..3.8..6}{..4.5.8..}{2.8...1.5}% +{..62.74..}{.........}{..94.32..}% +{9.5...6.4}{..2.1.9..}{1..8.9..2}% +[DT2 moderate 35] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +TM35 (moderate) \\ +\sudoku{tm35.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tm40.sud} +\writepuzzle% +{...1...92}{9...7..36}{3....2...}% +{.3....7.9}{.8.9.5.6.}{4.5....8.}% +{...8....5}{54..2...7}{12...3...}% +[DT2 moderate 40] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +TM40 (moderate) \\ +\sudoku{tm40.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tm45.sud} +\writepuzzle% +{.1.2.8.3.}{..87.94..}{9.......6}% +{..9.8.5..}{6.......3}{..3.5.6..}% +{2.......7}{..73.51..}{.6.4.7.9.}% +[DT2 moderate 45] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +TM45 (moderate) \\ +\sudoku{tm45.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tm50.sud} +\writepuzzle% +{...9.2..4}{4..3.5...}{3.....7.6}% +{6..8..3..}{1.3...9.7}{..9..7..2}% +{9.5.....8}{...2.9..1}{2..7.4...}% +[DT2 moderate 50] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +TM50 (moderate) \\ +\sudoku{tm50.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tm55.sud} +\writepuzzle% +{7........}{24.1.8...}{.6..72..3}% +{..4.29.8.}{.7.....6.}{.9.46.7..}% +{1..68..3.}{...3.7.91}{........6}% +[DT2 moderate 55] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +TM55 (moderate) \\ +\sudoku{tm55.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tm60.sud} +\writepuzzle% +{724.9.5..}{.5..2...8}{.8.5.7...}% +{...7..64.}{....8....}{.79..6...}% +{...8.5.2.}{6...4..8.}{..8.3.174}% +[DT2 moderate 60] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +TM60 (moderate) \\ +\sudoku{tm60.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{st0914.sud} +\writepuzzle% +{.6.29..8.}{..8....3.}{.1..78...}% +{.217.9..8}{6.......3}{7..6.492.}% +{...12..4.}{.7....3..}{.5..86.7.}% +[Seattle Times 2005/09/14 2 stars] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +ST0914 (2 stars) \\ +\sudoku{st0914.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{st0207.sud} +\writepuzzle% +{.......46}{5..8.9.73}{...6..5.1}% +{.592..1..}{6...1...7}{..3..785.}% +{2.5..6...}{19.7.5..8}{34.......}% +[Seattle Times 2005/02/07 2 stars] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +ST0207 (2 stars) \\ +\sudoku{st0207.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{cs4.sud} +\writepuzzle% +{...4.597.}{..67.83.2}{78.1.2.45}% +{891...75.}{.........}{567...423}% +{.1...4.67}{..89.15..}{.4....29.}% +[CreateSudoku 4 (level 8)] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +CS4 (level 4) \\ +\sudoku{cs4.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{cs5.sud} +\writepuzzle% +{...6..978}{..498...2}{.97.21...}% +{..84.27..}{.7.....23}{3...6...9}% +{7.6..95..}{...87...1}{.2..4.867}% +[CreateSudoku 5 (level 4)] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +CS5 (level 4) \\ +\sudoku{cs5.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{cs6.sud} +\writepuzzle% +{.126.4.7.}{6.5..73.2}{.7.3.1.4.}% +{756...423}{.........}{18......6}% +{.3.8.6..1}{2.1.....7}{..72...3.}% +[CreateSudoku 6 (level 4)] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +CS6 (level 4) \\ +\sudoku{cs6.sud} +\end{center}\end{minipage} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% hard + +\clearpage +\markboth{HARD}{HARD} + +\renewcommand*{\puzzlefile}{sh5.sud} +\writepuzzle% +{..9..5...}{47...2...}{.836.4.1.}% +{.15....8.}{...3.7...}{.2....74.}% +{.4.5.187.}{...7...52}{...2..1..}% +[SSBL hard 5] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +SH5 (hard) \\ +\sudoku{sh5.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{sh10.sud} +\writepuzzle% +{.3.921..5}{15.83....}{.........}% +{59......4}{37.....81}{6......53}% +{.........}{....19.26}{9..574.1.}% +[SSBL hard 10] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +SH10 (hard) \\ +\sudoku{sh10.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{sh15.sud} +\writepuzzle% +{2..9.....}{.7..6..59}{...4...61}% +{7.1..2..4}{....4....}{8..1..9.6}% +{12...3...}{53..2..7.}{.....9..2}% +[SSBL hard 15] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +SH15 (hard) \\ +\sudoku{sh15.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{sh20.sud} +\writepuzzle% +{.6.2...3.}{9...3...1}{....9.2..}% +{1..7.....}{.32...46.}{.....4..2}% +{..7.4....}{2...5...8}{.4...6.5.}% +[SSBL hard 20] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +SH20 (hard) \\ +\sudoku{sh20.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{sh25.sud} +\writepuzzle% +{4....1..8}{..7.3845.}{..24...1.}% +{28.9.....}{..4...5..}{.....4.86}% +{.4...92..}{.2134.8..}{9..6....1}% +[SSBL hard 25] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +SH25 (hard) \\ +\sudoku{sh25.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{sh30.sud} +\writepuzzle% +{....5..9.}{.53..78..}{78.4.....}% +{3....9.2.}{.72...38.}{.1.3....4}% +{.....1.35}{..58..41.}{.2..3....}% +[SSBL hard 30] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +SH30 (hard) \\ +\sudoku{sh30.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tt100.sud} +\writepuzzle% +{...896..7}{..23.5...}{..8...5.1}% +{15...9...}{3.......9}{...6...54}% +{8.1...7..}{...9.18..}{6..428...}% +[DT2 tough 100] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +TT100 (tough) \\ +\sudoku{tt100.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tt105.sud} +\writepuzzle% +{..5.7..46}{6..25....}{.3...6...}% +{2..7.....}{.78...35.}{.....1..7}% +{...8...2.}{....97..5}{81..2.9..}% +[DT2 tough 105] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +TT105 (tough) \\ +\sudoku{tt105.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tt110.sud} +\writepuzzle% +{.79.1....}{.4.5....7}{1..6.....}% +{9368..1..}{..4...9..}{..7..4632}% +{.....8..1}{5....6.9.}{....4.82.}% +[DT2 tough 110] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +TT110 (tough) \\ +\sudoku{tt110.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tt115.sud} +\writepuzzle% +{432.5....}{.....3...}{75.1.....}% +{..5.823..}{.6.5.1.4.}{..193.2..}% +{.....6.58}{...3.....}{....2.934}% +[DT2 tough 115] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +TT115 (tough) \\ +\sudoku{tt115.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tt120.sud} +\writepuzzle% +{..8.1.7..}{.4.67.8..}{..2..461.}% +{.9....1.8}{.........}{2.1....9.}% +{.759..4..}{..4.52.6.}{..9.3.5..}% +[DT2 tough 120] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +TT120 (tough) \\ +\sudoku{tt120.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{st1130.sud} +\writepuzzle% +{8..356...}{5....4.1.}{34.......}% +{7.156..2.}{.6.....7.}{.2..796.5}% +{.......32}{.9.4....8}{...682..9}% +[Seattle Times 2005/11/30 3 stars] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +ST1130 (3 stars) \\ +\sudoku{st1130.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{st1207.sud} +\writepuzzle% +{...483..6}{.....57.2}{......38.}% +{..8..16..}{.26.5.17.}{..57..2..}% +{.82......}{9.18.....}{4..527...}% +[Seattle Times 2005/12/07 3 stars] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +ST1207 (3 stars) \\ +\sudoku{st1207.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{st1209.sud} +\writepuzzle% +{...6.....}{.4..8..5.}{.519..2.8}% +{..729...3}{.9.....1.}{4...679..}% +{6.8..957.}{.7..2..9.}{.....4...}% +[Seattle Times 2005/12/09 5 stars] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +ST1209 (5 stars) \\ +\sudoku{st1209.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{st1221.sud} +\writepuzzle% +{.....392.}{4....5.7.}{29.4...63}% +{..4....5.}{...2.1...}{.5....3..}% +{74...2.96}{.6.5....7}{.217.....}% +[Seattle Times 2005/12/21 3 stars] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +ST1221 (3 stars) \\ +\sudoku{st1221.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{st1228.sud} +\writepuzzle% +{6..1..5..}{......379}{.942.....}% +{..5...8.3}{.4.....9.}{9.7...6..}% +{.....623.}{138......}{..6..8..7}% +[Seattle Times 2005/12/28 3 stars] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +ST1228 (3 stars) \\ +\sudoku{st1228.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{st0126.sud} +\writepuzzle% +{..36...7.}{1...352..}{..4......}% +{..6....29}{7.......4}{32....5..}% +{......1..}{..824...5}{.4...93..}% +[Seattle Times 2006/01/26 4 stars] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +ST0126 (4 stars) \\ +\sudoku{st0126.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{st0127.sud} +\writepuzzle% +{25.8.....}{....9.8.2}{9..4.7...}% +{64.....9.}{.9.1.3.4.}{.7.....21}% +{...5.4..7}{7.6.8....}{.....1.83}% +[Seattle Times 2006/01/27 5 stars] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +ST0127 (5 stars) \\ +\sudoku{st0127.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{st0204.sud} +\writepuzzle% +{.5..2.8.6}{.....6..3}{.6..132..}% +{.7....96.}{4.......1}{.16....3.}% +{..723..8.}{6..7.....}{2.4.9..7.}% +[Seattle Times 2006/02/04 6 stars] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +ST0204 (6 stars) \\ +\sudoku{st0204.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{st0208.sud} +\writepuzzle% +{21.9....7}{5.9..421.}{..7......}% +{..875....}{3.14.95.8}{....361..}% +{......4..}{.325..9.1}{1....8.25}% +[Seattle Times 2005/02/08 3 stars] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +ST0208 (3 stars) \\ +\sudoku{st0208.sud} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{st0209.sud} +\writepuzzle% +{..9......}{.523.1...}{8.12.6...}% +{..4....1.}{97..2..84}{.2....9..}% +{...8.41.5}{...6.524.}{......8..}% +[Seattle Times 2005/02/09 4 stars] +\vfill +\begin{minipage}{0.95\linewidth}\begin{center} +ST0209 (4 stars) \\ +\sudoku{st0209.sud} +\end{center}\end{minipage} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% answers + +\clearpage +\pagestyle{empty} +\cleardoublepage +\pagestyle{myheadings} +\markboth{SOLUTIONS}{SOLUTIONS} + +\cluefont{\normalsize} +\cellsize{1.5\baselineskip} + +\renewcommand*{\puzzlefile}{se5.ans} +\writepuzzle% +{724195863}{561283497}{938647251}% +{189756324}{256314789}{473928615}% +{645839172}{892471536}{317562948}% +[SSBL easy 5 solution] +\renewcommand*{\puzzlefile}{se10.ans} +\writepuzzle% +{156349782}{482715639}{793286145}% +{649853271}{217964358}{835172496}% +{524697813}{371528964}{968431527}% +[SSBL easy 10 solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +SE5 (easy solution) \\ +\sudoku{se5.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +SE10 (easy solution) \\ +\sudoku{se10.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{se15.ans} +\writepuzzle% +{456713982}{231698475}{879254631}% +{597846213}{124935867}{368172549}% +{643527198}{712489356}{985361724}% +[SSBL easy 15 solution] +\renewcommand*{\puzzlefile}{se20.ans} +\writepuzzle% +{368912547}{975438621}{412657839}% +{291543768}{783296414}{546781293}% +{657129384}{134865972}{829374156}% +[SSBL easy 20 solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +SE15 (easy solution) \\ +\sudoku{se15.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +SE20 (easy solution) \\ +\sudoku{se20.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{se25.ans} +\writepuzzle% +{278963154}{645712839}{931854276}% +{823641795}{159387462}{764295381}% +{482579613}{397126548}{516438927}% +[SSBL easy 25 solution] +\renewcommand*{\puzzlefile}{se30.ans} +\writepuzzle% +{436129875}{128753496}{759864321}% +{514287639}{673591284}{892346517}% +{941638752}{365972148}{287415963}% +[SSBL easy 30 solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +SE25 (easy solution) \\ +\sudoku{se25.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +SE30 (easy solution) \\ +\sudoku{se30.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tg5.ans} +\writepuzzle% +{764159382}{519238746}{823674951}% +{457982613}{936715428}{281463597}% +{142397865}{675841239}{398526174}% +[DT2 gentle 5 solution] +\renewcommand*{\puzzlefile}{tg10.ans} +\writepuzzle% +{382196574}{491573862}{567248139}% +{278614395}{946385217}{135729486}% +{624931758}{753862941}{819457623}% +[DT2 gentle 10 solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +TG5 (gentle solution) \\ +\sudoku{tg5.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +TG10 (gentle solution) \\ +\sudoku{tg10.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tg15.ans} +\writepuzzle% +{462198573}{357462189}{981537426}% +{236741958}{175986342}{894253617}% +{723615894}{619824735}{548379261}% +[DT2 gentle 15 solution] +\renewcommand*{\puzzlefile}{tg20.ans} +\writepuzzle% +{256789431}{481326759}{739415628}% +{594261873}{167938245}{823574196}% +{912643587}{645897312}{378152964}% +[DT2 gentle 20 solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +TG15 (gentle solution) \\ +\sudoku{tg15.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +TG20 (gentle solution) \\ +\sudoku{tg20.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tg25.ans} +\writepuzzle% +{782463519}{461295378}{395781246}% +{819527463}{634918752}{527346891}% +{256872934}{978134625}{243659187}% +[DT2 gentle 25 solution] +\renewcommand*{\puzzlefile}{tg30.ans} +\writepuzzle% +{376418529}{928756134}{154923678}% +{749132865}{612584793}{835697241}% +{597361482}{483275916}{261849357}% +[DT2 gentle 30 solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +TG25 (gentle solution) \\ +\sudoku{tg25.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +TG30 (gentle solution) \\ +\sudoku{tg30.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{st1226.ans} +\writepuzzle% +{962854731}{745213689}{183967452}% +{326748915}{571639248}{498125376}% +{837592164}{659471823}{214386597}% +[Seattle Times 2005/12/26 1 star solution] +\renewcommand*{\puzzlefile}{st0206.ans} +\writepuzzle% +{176429385}{352817496}{849653217}% +{463971852}{925384671}{718265934}% +{281536749}{534792168}{697148523}% +[Seattle Times 2005/02/06 1 star solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +ST1226 (1 star solution) \\ +\sudoku{st1226.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +ST0206 (1 star solution) \\ +\sudoku{st0206.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{st0123.ans} +\writepuzzle% +{594621837}{736489125}{281357469}% +{319278654}{652134978}{478596312}% +{927813546}{145962783}{863745291}% +[Seattle Times 2006/01/23 1 star solution] +\renewcommand*{\puzzlefile}{cs1.ans} +\writepuzzle% +{546987312}{213654978}{879321645}% +{657198423}{324765189}{981432756}% +{435876291}{768219534}{192543867}% +[CreateSudoku 1 (level 2) solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +ST0123 (1 star solution) \\ +\sudoku{st0123.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +CS1 (level 2 solution) \\ +\sudoku{cs1.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{cs2.ans} +\writepuzzle% +{978312654}{312645987}{645978321}% +{189423765}{423756198}{756189432}% +{291534876}{867291543}{534867219}% +[CreateSudoku 2 (level 2) solution] +\renewcommand*{\puzzlefile}{cs3.ans} +\writepuzzle% +{456897123}{123564789}{789231456}% +{234675891}{567918234}{891342567}% +{345786912}{912453678}{678129345}% +[CreateSudoku 3 (level 2) solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +CS2 (level 2 solution) \\ +\sudoku{cs2.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +CS3 (level 2 solution) \\ +\sudoku{cs3.ans} +\end{center}\end{minipage} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% medium + +\renewcommand*{\puzzlefile}{sm5.ans} +\writepuzzle% +{387691245}{546273198}{921485637}% +{865342971}{193567482}{274918356}% +{618739524}{759124863}{432856719}% +[SSBL medium 5 solution] +\renewcommand*{\puzzlefile}{sm10.ans} +\writepuzzle% +{635748219}{418392576}{279561483}% +{527984631}{941653827}{863127954}% +{194835762}{786219345}{352476198}% +[SSBL medium 10 solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +SM5 (medium solution) \\ +\sudoku{sm5.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +SM10 (medium solution) \\ +\sudoku{sm10.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{sm15.ans} +\writepuzzle% +{853974612}{471326958}{962815473}% +{396542781}{745681239}{218739564}% +{134267895}{587493126}{629158347}% +[SSBL medium 15 solution] +\renewcommand*{\puzzlefile}{sm20.ans} +\writepuzzle% +{863452197}{594178326}{172639548}% +{617894235}{938526471}{234713869}% +{489265713}{351947682}{726381954}% +[SSBL medium 20 solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +SM15 (medium solution) \\ +\sudoku{sm15.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +SM20 (medium solution) \\ +\sudoku{sm20.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{sm25.ans} +\writepuzzle% +{382467951}{716935284}{495218376}% +{564329817}{278651493}{139784625}% +{927146538}{651893742}{843572169}% +[SSBL medium 25 solution] +\renewcommand*{\puzzlefile}{sm30.ans} +\writepuzzle% +{765834921}{318279465}{294615378}% +{657392814}{823741659}{941568732}% +{439157286}{186423597}{572986143}% +[SSBL medium 30 solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +SM25 (medium solution) \\ +\sudoku{sm25.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +SM30 (medium solution) \\ +\sudoku{sm30.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tm35.ans} +\writepuzzle% +{591328746}{674951823}{238674195}% +{356297481}{427185369}{819463257}% +{985732614}{742516938}{163849572}% +[DT2 moderate 35 solution] +\renewcommand*{\puzzlefile}{tm40.ans} +\writepuzzle% +{874136592}{952478136}{316592874}% +{631284759}{287915463}{495367281}% +{763841925}{548629317}{129753648}% +[DT2 moderate 40 solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +TM35 (moderate solution) \\ +\sudoku{tm35.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +TM40 (moderate solution) \\ +\sudoku{tm40.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tm45.ans} +\writepuzzle% +{716248935}{538769421}{924531786}% +{179683542}{652974813}{483152679}% +{241896357}{897325164}{365417298}% +[DT2 moderate 45 solution] +\renewcommand*{\puzzlefile}{tm50.ans} +\writepuzzle% +{751962834}{468375219}{392148756}% +{627891345}{143526987}{589437162}% +{975613428}{834259671}{216784593}% +[DT2 moderate 50 solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +TM45 (moderate solution) \\ +\sudoku{tm45.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +TM50 (moderate solution) \\ +\sudoku{tm50.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tm55.ans} +\writepuzzle% +{731946528}{245138679}{968572143}% +{614729385}{572813964}{893465712}% +{159684237}{426357891}{387291456}% +[DT2 moderate 55 solution] +\renewcommand*{\puzzlefile}{tm60.ans} +\writepuzzle% +{734198562}{156324798}{982567431}% +{813752649}{465983217}{279416853}% +{341875926}{697241385}{528639174}% +[DT2 moderate 60 solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +TM55 (moderate solution) \\ +\sudoku{tm55.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +TM60 (moderate solution) \\ +\sudoku{tm60.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{st0914.ans} +\writepuzzle% +{567293184}{298461537}{413578692}% +{321759468}{649812753}{785634921}% +{936127845}{872945316}{154386279}% +[Seattle Times 2005/09/14 2 star solution] +\renewcommand*{\puzzlefile}{st0207.ans} +\writepuzzle% +{872351946}{561849273}{934672581}% +{759283164}{628514397}{413967852}% +{285436719}{196725438}{347198625}% +[Seattle Times 2005/02/07 2 star solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +ST0914 (2 star solution) \\ +\sudoku{st0914.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +ST0207 (2 star solution) \\ +\sudoku{st0207.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{cs4.ans} +\writepuzzle% +{123465978}{456798312}{789132645}% +{891243756}{234576189}{567819423}% +{912354867}{678921534}{345687291}% +[CreateSudoku 4 (level 4) solution] +\renewcommand*{\puzzlefile}{cs5.ans} +\writepuzzle% +{231654978}{564987312}{897321645}% +{918432756}{675198423}{342765189}% +{786219534}{453876291}{129543867}% +[CreateSudoku 5 (level 4) solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +CS4 (level 8 solution) \\ +\sudoku{cs4.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +CS5 (level 8 solution) \\ +\sudoku{cs5.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{cs6.ans} +\writepuzzle% +{312654978}{645987312}{978321645}% +{756198423}{423765189}{189432756}% +{534876291}{291543867}{867219534}% +[CreateSudoku 6 (level 4) solution] +\renewcommand*{\puzzlefile}{sh5.ans} +\writepuzzle% +{269175438}{471832965}{583694217}% +{715426389}{894317526}{326958741}% +{942561873}{138749652}{657283194}% +[SSBL hard 5 solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +CS6 (level 4 solution) \\ +\sudoku{cs6.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +SH5 (hard solution) \\ +\sudoku{sh5.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{sh10.ans} +\writepuzzle% +{437921865}{156837492}{289456137}% +{598163274}{374295681}{621748953}% +{713682549}{845319726}{962574318}% +[SSBL hard 10 solution] +\renewcommand*{\puzzlefile}{sh15.ans} +\writepuzzle% +{216935847}{478261359}{395478261}% +{761392584}{952846713}{843157926}% +{124783695}{539624178}{687519432}% +[SSBL hard 15 solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +SH10 (hard solution) \\ +\sudoku{sh10.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +SH15 (hard solution) \\ +\sudoku{sh15.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{sh20.ans} +\writepuzzle% +{468271935}{925438671}{713695284}% +{154762893}{832519467}{679384512}% +{587943126}{296157348}{341826759}% +[SSBL hard 20 solution] +\renewcommand*{\puzzlefile}{sh25.ans} +\writepuzzle% +{439561728}{167238459}{852497613}% +{286953174}{794816532}{513724986}% +{348179265}{621345897}{975682341}% +[SSBL hard 25 solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +SH20 (hard solution) \\ +\sudoku{sh20.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +SH25 (hard solution) \\ +\sudoku{sh25.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{sh30.ans} +\writepuzzle% +{461258793}{253917846}{789463152}% +{346789521}{572146389}{918325674}% +{894671235}{635892417}{127534968}% +[SSBL hard 30 solution] +\renewcommand*{\puzzlefile}{tt100.ans} +\writepuzzle% +{513896427}{742315698}{968742531}% +{154289376}{376154289}{289637154}% +{891563742}{425971863}{637428915}% +[DT2 tough 100 solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +SH30 (hard solution) \\ +\sudoku{sh30.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +TT100 (tough solution) \\ +\sudoku{tt100.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tt105.ans} +\writepuzzle% +{925378146}{681254793}{734916582}% +{256739418}{178462359}{349581267}% +{597843621}{462197835}{813625974}% +[DT2 tough 105 solution] +\renewcommand*{\puzzlefile}{tt110.ans} +\writepuzzle% +{379412586}{648539217}{125687349}% +{936825174}{214763958}{857194632}% +{492358761}{581276493}{763941825}% +[DT2 tough 110 solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +TT105 (tough solution) \\ +\sudoku{tt105.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +TT110 (tough solution) \\ +\sudoku{tt110.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{tt115.ans} +\writepuzzle% +{432758196}{196243587}{758169423}% +{945682371}{263571849}{871934265}% +{329416758}{584397612}{617825934}% +[DT2 tough 115 solution] +\renewcommand*{\puzzlefile}{tt120.ans} +\writepuzzle% +{968215734}{143679852}{752384619}% +{496523178}{537198246}{281746395}% +{875961423}{314852967}{629437581}% +[DT2 tough 120 solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +TT115 (tough solution) \\ +\sudoku{tt115.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +TT120 (tough solution) \\ +\sudoku{tt120.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{st1130.ans} +\writepuzzle% +{819356247}{576924813}{342817596}% +{781563924}{965248371}{423179685}% +{658791432}{297435168}{134682759} +[Seattle Times 2005/11/30 3 star solution] +\renewcommand*{\puzzlefile}{st1207.ans} +\writepuzzle% +{217483956}{834695712}{659172384}% +{798231645}{326954178}{145768239}% +{582319467}{971846523}{463527891}% +[Seattle Times 2005/12/07 3 star solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +ST1130 (3 star solution) \\ +\sudoku{st1130.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +ST1207 (3 star solution) \\ +\sudoku{st1207.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{st1209.ans} +\writepuzzle% +{839652147}{246781359}{751943268}% +{167295483}{592438716}{483167925}% +{628319574}{374526891}{915874632}% +[Seattle Times 2005/12/09 5 star solution] +\renewcommand*{\puzzlefile}{st1221.ans} +\writepuzzle% +{517863924}{436925178}{298417563}% +{174389652}{683251749}{952674381}% +{745132896}{369548217}{821796435}% +[Seattle Times 2005/12/21 3 star solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +ST1209 (5 star solution) \\ +\sudoku{st1209.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +ST1221 (3 star solution) \\ +\sudoku{st1221.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{st1228.ans} +\writepuzzle% +{673189524}{812654379}{594273186}% +{265791843}{341865792}{987342651}% +{795416238}{138927465}{426538917}% +[Seattle Times 2005/12/28 3 star solution] +\renewcommand*{\puzzlefile}{st0126.ans} +\writepuzzle% +{253698471}{197435286}{864127953}% +{416573829}{785912634}{329864517}% +{972356148}{638241795}{541789362}% +[Seattle Times 2006/01/26 4 star solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +ST1228 (3 star solution) \\ +\sudoku{st1228.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +ST0126 (4 star solution) \\ +\sudoku{st0126.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{st0127.ans} +\writepuzzle% +{253816479}{467395812}{918427536}% +{641752398}{892163745}{375948621}% +{189534267}{736289154}{524671983}% +[Seattle Times 2006/01/27 5 star solution] +\renewcommand*{\puzzlefile}{st0204.ans} +\writepuzzle% +{153427896}{742986513}{869513247}% +{375142968}{428369751}{916875432}% +{597321684}{681754329}{234698175}% +[Seattle Times 2006/02/04 6 star solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +ST0127 (5 star solution) \\ +\sudoku{st0127.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +ST0204 (6 star solution) \\ +\sudoku{st0204.ans} +\end{center}\end{minipage} + +\renewcommand*{\puzzlefile}{st0208.ans} +\writepuzzle% +{213985647}{589674213}{647213859}% +{928751364}{361429578}{754836192}% +{875192436}{432567981}{196348725}% +[Seattle Times 2005/02/08 3 star solution] +\renewcommand*{\puzzlefile}{st0209.ans} +\writepuzzle% +{639587421}{752341698}{841296753}% +{584769312}{976123584}{123458976}% +{297834165}{318675249}{465912837}% +[Seattle Times 2005/02/09 4 star solution] +\vfill +\noindent\begin{minipage}{0.47\linewidth}\begin{center} +ST0208 (3 star solution) \\ +\sudoku{st0208.ans} +\end{center}\end{minipage} +\hfill +\begin{minipage}{0.47\linewidth}\begin{center} +ST0209 (4 star solution) \\ +\sudoku{st0209.ans} +\end{center}\end{minipage} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% bibliography +\cleardoublepage + +\bibliographystyle{alpha} +\begingroup +\raggedright +\begin{thebibliography}{GMSN94A} + +\bibitem[Mep05]{DT2} +Michael Mepham. +\emph{The Daily Telegraph Sudoku 2}. +\newblock Pan Books, 2005. +\newblock ISBN 0-330-44203-3. + +\bibitem[Wil06]{SUDOKUBUNDLE} +Peter Wilson. +\emph{The sudoku bundle for displaying, solving and generating + Sudoku puzzles}. +\newblock February 2006. +\newblock (Available from CTAN in \url{macros/latex/contrib/sudokubundle}). + +\bibitem[SOL]{SOL} +\emph{Sudoku Online: Home of the Sudokulist}. +\newblock \url{http://www.sudoku.org.uk} + +\bibitem[SSBL]{SSBL} +\emph{Sudoku Solver ... by logic}. +\newblock \url{http://www.sudokusolver.co.uk} + +\end{thebibliography} +\endgroup + +\end{document} + +% +% \end{macrocode} +% +% \Finale +% +% +\endinput + +%% \CharacterTable +%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +%% Digits \0\1\2\3\4\5\6\7\8\9 +%% Exclamation \! Double quote \" Hash (number) \# +%% Dollar \$ Percent \% Ampersand \& +%% Acute accent \' Left paren \( Right paren \) +%% Asterisk \* Plus \+ Comma \, +%% Minus \- Point \. Solidus \/ +%% Colon \: Semicolon \; Less than \< +%% Equals \= Greater than \> Question mark \? +%% Commercial at \@ Left bracket \[ Backslash \\ +%% Right bracket \] Circumflex \^ Underscore \_ +%% Grave accent \` Left brace \{ Vertical bar \| +%% Right brace \} Tilde \~} + + diff --git a/macros/latex/contrib/sudokubundle/sudokubundle.ins b/macros/latex/contrib/sudokubundle/sudokubundle.ins new file mode 100644 index 0000000000..6c0fbbd778 --- /dev/null +++ b/macros/latex/contrib/sudokubundle/sudokubundle.ins @@ -0,0 +1,83 @@ +%% sudokubundle.ins +%% Author: Peter Wilson (herries dot press at earthlink dot net +%% Herries Press +%% Copyright 2006 Peter R. Wilson +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either +%% version 1.3 of this license or (at your option) any +%% later version. +%% The latest version of the license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of +%% LaTeX version 2003/06/01 or later. +%% +%% This work has the LPPL maintenance status "author-maintained". +%% +%% This work consists of the files listed in the README file. +%% +%% This file will generate fast loadable files and documentation +%% driver files from the doc files in this work when run through +%% LaTeX. +%% +%% --------------- start of docstrip commands ------------------ +%% +\def\batchfile{sudokubundle.ins} +\input docstrip.tex +\preamble + +----------------------------------------------------------------- + Author: Peter Wilson (herries dot press at earthlink dot net) + Herries Press + Copyright 2006 Peter R. Wilson + + This work may be distributed and/or modified under the + conditions of the LaTeX Project Public License, either + version 1.3 of this license or (at your option) any + later version. + The latest version of the license is in + http://www.latex-project.org/lppl.txt + and version 1.3 or later is part of all distributions of + LaTeX version 2003/06/01 or later. + + This work has the LPPL maintenance status "author-maintained". + + This work consists of the files listed in the README file. +----------------------------------------------------------------- + +\endpreamble + +\keepsilent + +%%% \Msg{*** Generating the driver file ***} +%%% \generateFile{sudokubundle.drv}{t}{\from{sudokubundle.dtx}{driver}} + +\Msg{*** Generating the LaTeX2e package files ***} + +\generateFile{printsudoku.sty}{t}{\from{sudokubundle.dtx}{print}} +\generateFile{solvesudoku.sty}{t}{\from{sudokubundle.dtx}{solve}} +\generateFile{createsudoku.sty}{t}{\from{sudokubundle.dtx}{create}} +\generateFile{somesudoku.tex}{t}{\from{sudokubundle.dtx}{examples}} + +\Msg{***********************************************************} +\Msg{*} +\Msg{* To finish the installation you have to move the following} +\Msg{* file(s) into a directory searched by TeX. For more information} +\Msg{* see the FAQ on CTAN at /help/uk-tex-faq.} +\Msg{*} +\Msg{* \space\space printsudoku.sty} +\Msg{* \space\space solvesudoku.sty} +\Msg{* \space\space createsudoku.sty} +\Msg{*} +\Msg{*} +\Msg{* To produce the documentation run the files ending with} +\Msg{* `.dtx' through LaTeX.} +\Msg{* For an index, process any name.idx file by:} +\Msg{* \space\space\space\space makeindex -s gind.ist name} +\Msg{* For a list of changes, process any name.glo file by:} +\Msg{* \space\space\space\space makeindex -s gglo.ist -o name.gls name.glo} +\Msg{*} +\Msg{* Happy TeXing} +\Msg{***********************************************************} + +\endinput diff --git a/macros/latex/contrib/sudokubundle/sudokubundle.pdf b/macros/latex/contrib/sudokubundle/sudokubundle.pdf new file mode 100644 index 0000000000..d52fac65de Binary files /dev/null and b/macros/latex/contrib/sudokubundle/sudokubundle.pdf differ -- cgit v1.2.3