Created
February 6, 2012 17:47
-
-
Save zr-tex8r/1753619 to your computer and use it in GitHub Desktop.
The Tower of Hanoi with graphics, in LaTeX
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% | |
% bxhanoi.sty : The "Tower of Hanoi" puzzle shown in graphics | |
% | |
%% package declaration | |
\NeedsTeXFormat{LaTeX2e} | |
\ProvidesPackage{bxhanoi}[2012/02/01] | |
%% variables | |
\newcount\bxhp@step | |
\newcount\bxhp@n@disks | |
\newcount\bxhp@n@rodA | |
\newcount\bxhp@n@rodB | |
\newcount\bxhp@n@rodC | |
\newcount\bxhp@xx | |
\newcount\bxhp@yy | |
%%-------------------------------------- solver logic | |
%% initialization | |
\newcommand*\towerofhanoi[1]{% | |
\bxhp@n@disks=#1\relax | |
\bxhp@init | |
\bxhp@cycle\bxhp@exit | |
} | |
\def\bxhp@init{% | |
\bxhp@step=0 | |
\bxhp@n@rodA=0 \let\bxhp@rodA\@empty | |
\bxhp@n@rodB=0 \let\bxhp@rodB\@empty | |
\bxhp@n@rodC=0 \let\bxhp@rodC\@empty | |
\loop | |
\advance\bxhp@n@rodA 1 | |
\edef\bxhp@rodA{\bxhp@rodA\the\bxhp@n@rodA/}% | |
\ifnum \bxhp@n@rodA<\bxhp@n@disks \repeat | |
\ifodd\bxhp@n@disks | |
\let\bxhp@cycle\bxhp@cycle@@odd | |
\else | |
\let\bxhp@cycle\bxhp@cycle@@even | |
\fi | |
\bxhp@show | |
} | |
\def\bxhp@debug@show{% | |
\typeout{% | |
Step \the\bxhp@step^^J% | |
A(\the\bxhp@n@rodA):\bxhp@rodA^^J% | |
B(\the\bxhp@n@rodB):\bxhp@rodB^^J% | |
C(\the\bxhp@n@rodC):\bxhp@rodC | |
}% | |
} | |
%% one step | |
\def\bxhp@cycle@@odd{% | |
\bxhp@move AC% | |
\bxhp@move AB% | |
\bxhp@move BC% | |
\bxhp@cycle | |
} | |
\def\bxhp@cycle@@even{% | |
\bxhp@move AB% | |
\bxhp@move AC% | |
\bxhp@move BC% | |
\bxhp@cycle | |
} | |
\def\bxhp@move#1#2{% | |
\expandafter\bxhp@move@a | |
\csname bxhp@rod#1\expandafter\endcsname | |
\csname bxhp@rod#2\endcsname{#1}{#2}% | |
} | |
\def\bxhp@move@a#1#2#3#4{% | |
%\bxhp@rodX \bxhp@rodY {X} {Y} | |
\advance\bxhp@step 1 | |
\bxhp@let@top\bxhp@topX#1% | |
\bxhp@let@top\bxhp@topY#2% | |
\ifnum\bxhp@topX<\bxhp@topY | |
\def\bxhp@args{#1#2#3#4\bxhp@topX}% | |
\else | |
\def\bxhp@args{#2#1#4#3\bxhp@topY}% | |
\fi | |
\expandafter\bxhp@move@b\bxhp@args | |
} | |
\def\bxhp@move@b#1#2#3#4#5{% | |
\bxhp@pop#1% | |
\advance\csname bxhp@n@rod#3\endcsname -1 | |
\bxhp@push#2#5% | |
\advance\csname bxhp@n@rod#4\endcsname 1 | |
\bxhp@show | |
\bxhp@check | |
} | |
\def\bxhp@check{% | |
\ifnum\bxhp@n@rodC=\bxhp@n@disks | |
\expandafter\bxhp@finalize | |
\fi | |
} | |
\def\bxhp@finalize#1\bxhp@exit{% | |
% no-op | |
} | |
%%-------------------------------------- stack operation | |
%% \bxhp@let@top\CS{<stack>} | |
\def\bxhp@let@top#1#2{% | |
\expandafter\bxhp@let@top@a#2\maxdimen/\bxhp@end#1% | |
} | |
\def\bxhp@let@top@a#1/#2\bxhp@end#3{% | |
\def#3{#1}% | |
} | |
%% \bxhp@pop{<stack>} | |
\def\bxhp@pop#1{% | |
\expandafter\bxhp@pop@a#1\bxhp@end#1 | |
} | |
\def\bxhp@pop@a#1/#2\bxhp@end#3{% | |
\def#3{#2}% | |
} | |
\def\bxhp@push#1#2{% | |
\edef#1{#2/#1}% | |
} | |
%%-------------------------------------- drawings | |
%% color definitions | |
\definecolor{bxhp@rod}{rgb}{1.0,0.8,0} | |
\definecolor{bxhp@count}{rgb}{0.0,0.4,0} | |
%%<*> \tohstepname | |
% The word for "step". | |
\newcommand\tohstepname{} | |
%%<*> \settohunitlength{<dimen>} | |
% Sets the value of \unitlength used in the puzzle graphics. | |
\newcommand*\settohunitlength[1]{% | |
\def\bxhp@unitlength{#1}% | |
} | |
%% \bxhp@draw@figure | |
\def\bxhp@draw@figure{% | |
\begingroup | |
\bxhp@xx\bxhp@n@disks \multiply\bxhp@xx6 | |
\bxhp@yy\bxhp@n@disks \advance\bxhp@yy2 | |
\setlength\unitlength{\bxhp@unitlength}% | |
\begin{picture}(\bxhp@xx,\bxhp@yy)% | |
\put(0,0){\color{bxhp@rod}% | |
\rule{\bxhp@xx\unitlength}{\unitlength}}% | |
\advance\bxhp@yy-1 | |
\bxhp@xx\bxhp@n@disks \multiply\bxhp@xx2 | |
\multiput(\bxhp@n@disks,1)(\bxhp@xx,0){3}{% | |
\color{bxhp@rod}\kern-.3\unitlength | |
\rule{.6\unitlength}{\bxhp@yy\unitlength}}% | |
\bxhp@put@tower(\bxhp@n@disks,1){A}% | |
\bxhp@xx\bxhp@n@disks \multiply\bxhp@xx3 | |
\bxhp@put@tower(\bxhp@xx,1){B}% | |
\bxhp@xx\bxhp@n@disks \multiply\bxhp@xx5 | |
\bxhp@put@tower(\bxhp@xx,1){C}% | |
\end{picture}% | |
\endgroup | |
} | |
%% \bxhp@show | |
\def\bxhp@show{% | |
\newpage | |
\begingroup | |
\noindent\normalsize | |
\rule[-1em]{0pt}{3em}\color{bxhp@count}% | |
\tohstepname | |
\makebox[7em][r]{\bfseries\itshape\LARGE \the\bxhp@step}% | |
\par\medskip | |
\noindent\normalsize | |
\bxhp@draw@figure | |
\par | |
\endgroup | |
} | |
%% \bxhp@elt@disk{<disk_no>} | |
% Graphics of a disk. | |
\def\bxhp@elt@disk#1{% | |
\@tempdima=.5\p@ | |
\multiply\@tempdima#1\divide\@tempdima\bxhp@n@disks | |
\@tempdimb=.5\p@ \advance\@tempdimb-\@tempdima | |
\edef\bxhp@set@color{\noexpand\color | |
[rgb]{0,\strip@pt\@tempdimb,\strip@pt\@tempdima}}% | |
\@tempdima=1.5\unitlength \@tempdima=#1\@tempdima | |
\edef\bxhp@tempa{\the\@tempdima}% | |
\makebox[\z@]{\bxhp@set@color\rule{\bxhp@tempa}{\unitlength}}% | |
} | |
%% \bxhp@put@tower(x,y){<rod>} | |
% Puts the whole graphics of a tower in a rod. | |
\def\bxhp@put@tower(#1,#2)#3{% | |
\bxhp@xx=#1\relax \bxhp@yy=#2\relax | |
\advance\bxhp@yy\csname bxhp@n@rod#3\endcsname | |
\advance\bxhp@yy-1 | |
\edef\bxhp@args{\csname bxhp@rod#3\endcsname*/}% | |
\expandafter\bxhp@put@tower@a\bxhp@args | |
} | |
\def\bxhp@put@tower@a#1/{% | |
\if*#1\else | |
\bxhp@put@tower@b{#1}% | |
\expandafter\bxhp@put@tower@a | |
\fi | |
} | |
\def\bxhp@put@tower@b#1{% | |
\put(\bxhp@xx,\bxhp@yy){\bxhp@elt@disk{#1}}% | |
\advance\bxhp@yy-1 | |
} | |
%%-------------------------------------- initial settings | |
\renewcommand\tohstepname{Step} | |
\settohunitlength{10pt} | |
%%-------------------------------------- all done | |
%% EOF |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
\documentclass[a4paper]{article} | |
\usepackage{color} % required | |
\usepackage{bxhanoi} | |
\begin{document} | |
\settohunitlength{5pt} % unit-length in figures | |
\towerofhanoi{10} % number of disks | |
\end{document} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment