%% %% This is file `probsoln.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% probsoln.dtx (with options: `probsoln.sty,package') %% %% probsoln.dtx %% Copyright 2017 Nicola Talbot %% %% 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 this license is in %% http://www.latex-project.org/lppl.txt %% and version 1.3 or later is part of all distributions of LaTeX %% version 2005/12/01 or later. %% %% This work has the LPPL maintenance status `maintained'. %% %% The Current Maintainer of this work is Nicola Talbot. %% %% This work consists of the files probsoln.dtx and probsoln.ins and the derived files probsoln.sty, sample-exclude.tex, sample.tex, sample2.tex, sample3.tex, sample4.tex, sample5.tex, sample6.tex, sample7.tex, sample8.tex, sample9.tex, prob-1stprncp.tex, prob-args.tex, prob-easy.tex, prob-easy2.tex, prob-implicit.tex, prob-mchoice.tex, prob-mixed.tex, prob-newdata.tex, prob-nosoln.tex, prob-probspaces.tex, prob-probspaces2.tex, prob-tabmchoice.tex, prob-verb.tex. %% %% \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 \~} %% randomly select 25 problems from derivatives.tex and add to %% the data set called 'deriv' %% Display the problems %% You may need to change \theenumi back here %% randomly select 25 problems from probspaces.tex and add to %% the data set called 'spaces' %% Display the problems %% You may need to change \theenumi back here \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{probsoln}[2017/07/10 v3.05 (NLCT)] \RequirePackage{ifthen} \RequirePackage{amsmath} \RequirePackage{etoolbox} \newif\ifshowanswers \showanswersfalse \let\showanswers\showanswerstrue \let\hideanswers\showanswersfalse \DeclareOption{answers}{\showanswerstrue} \DeclareOption{noanswers}{\showanswersfalse} \newif\ifusedefaultprobargs \DeclareOption{usedefaultargs}{\usedefaultprobargstrue} \DeclareOption{nousedefaultargs}{\usedefaultprobargsfalse} \usedefaultprobargsfalse \newcommand*{\prob@showdraftlabel}[2]{} \newcommand*{\draftproblemlabel}[2]{[#1,#2]} \DeclareOption{draft}{% \renewcommand*{\prob@showdraftlabel}[2]{\draftproblemlabel{#1}{#2}}} \DeclareOption{final}{% \renewcommand*{\prob@showdraftlabel}[2]{}} \ProcessOptions \RequirePackage{xkeyval} \define@boolkey{probsoln}[@prob@]{fragile}[true]{} \newcommand*{\ProbSolnFragileExt}{vrb} \newcommand*{\ProbSolnFragileFile}{\jobname} \newwrite\probsoln@write \newcount\probsoln@startyear \newcommand*{\SetStartYear}[1]{% \probsoln@startyear=#1\relax \renewcommand\SetStartMonth[1]{% \PackageError{probsoln}{\string\SetStartMonth\space can't be used after \string\SetStartYear}{}}% } \newcommand*{\GetStartYear}{\probsoln@startyear} \newcount\probsoln@startmonth \newcommand*{\SetStartMonth}[1]{% \probsoln@startmonth=#1\relax \probsoln@startyear=\year\relax \ifnum\month<\probsoln@startmonth \advance\probsoln@startyear by -1\relax \fi } \SetStartMonth{9} \newwrite\probsoln@prev \newwrite\probsoln@used \newcount\probsoln@prev@cutoff \newcommand*{\@probsoln@usedfilename}{\jobname.prb} \newcommand*{\SetUsedFileName}[1]{% \renewcommand*{\@probsoln@usedfilename}{#1}% } \newcommand*{\ClearUsedFile}[1]{% \probsoln@prev@cutoff=0\relax \@probsoln@readprev{#1}% \@for\@this@db:=\prob@databases\do{% {% \edef\@prev@list{\csname probsoln@prev@list@\@this@db\endcsname}% \ifdefempty{\@prev@list}% {}% {% \@for\@this@label:=\@prev@list\do{% \ifcsundef{@used@problem@\@this@db @\@this@label}% {% \immediate\write\probsoln@prev{% \string\previousproblem{\@this@label}{\@this@db}% {\csname @prev@problem@\@this@db @\@this@label\endcsname}}% }% {}% }% }% }% }% \immediate\closeout\probsoln@prev \immediate\closeout\probsoln@used \@disable@exclude@prev } \newcommand*{\ExcludePreviousFile}[2][3]{% \probsoln@prev@cutoff=\probsoln@startyear\relax \advance\probsoln@prev@cutoff by -#1\relax \@probsoln@readprev{#2}% \@write@prev \def\ExcludePreviousFile[2][3]{\PackageError{probsoln}{Only one instance of \string\ExcludePreviousFile\space allowed}{You've already used this command. You are only allowed to use it once}}% \def\ClearUsedFile[1]{% \PackageError{probsoln}% {\string\ClearUsedFile\space may not be used after \string\ExcludePreviousFile}{}}% } \newcommand*{\@probsoln@readprev}[1]{% \@enable@exclude@prev \InputIfFileExists{#1}% {\PackageInfo{probsoln}% {Excluded problem file `#1' found}}% {\PackageInfo{probsoln}% {Excluded problem file `#1' not found. A new one will be created}}% \InputIfFileExists{\@probsoln@usedfilename}% {\PackageInfo{probsoln}% {Current problems file `\@probsoln@usedfilename' found}}% {\PackageInfo{probsoln}% {No current problem file `\@probsoln@usedfilename' found. A new one will be created}}% \immediate\openout\probsoln@prev=#1 \immediate\openout\probsoln@used=\@probsoln@usedfilename } \newcommand*{\probsoln@prev@list@default}{} \newcommand*{\@write@prev}{% \@for\@this@db:=\prob@databases\do{% {% \edef\@prev@list{\csname probsoln@prev@list@\@this@db\endcsname}% \ifdefempty{\@prev@list}% {}% {% \@for\@this@label:=\@prev@list\do{% \immediate\write\probsoln@prev{% \string\previousproblem{\@this@label}{\@this@db}% {\csname @prev@problem@\@this@db @\@this@label\endcsname}}% }% }% }% }% } \newcommand*{\@enable@exclude@prev}{% \renewcommand*{\@add@used@problem}[2]{% \immediate\write\probsoln@used{\string\usedproblem{##1}{##2}{\number\probsoln@startyear}}% \ifcsundef{@prev@problem@##2@##1}% {% \immediate\write\probsoln@prev{% \string\previousproblem{##1}{##2}{\number\probsoln@startyear}}% \expandafter\xdef\csname @prev@problem@##2@##1\endcsname{% \number\probsoln@startyear}% }% {% \expandafter\ifnum\csname @prev@problem@##2@##1\endcsname <\probsoln@startyear \immediate\write\probsoln@prev{% \string\previousproblem{##1}{##2}{\number\probsoln@startyear}}% \expandafter\xdef\csname @prev@problem@##2@##1\endcsname{% \number\probsoln@startyear}% \fi }% }% \renewcommand*{\@fetch@excluded@list}[2]{% \def##1{}% \ifcsdef{probsoln@prev@list@##2}% {% \edef\@prev@list{\csname probsoln@prev@list@##2\endcsname}% \@for\@this@label:=\@prev@list\do{% \ifcsundef{@used@problem@##2@\@this@label}% {% \ifcsempty{##1}% {\edef##1{\@this@label}}% {\edef##1{##1,\@this@label}}% }% {}% }% }% {}% }% \renewcommand*{\@add@newprevlist}[1]{% \expandafter\gdef\csname probsoln@prev@list@##1\endcsname{}% }% \renewcommand*{\close@probsoln@prev}{% \closeout\probsoln@prev \closeout\probsoln@used }% } \newcommand*{\@disable@exclude@prev}{% \renewcommand*{\@add@used@problem}[2]{}% \renewcommand*{\@fetch@excluded@list}[2]{\def##1{}}% \renewcommand*{\@add@newprevlist}[1]{}% \renewcommand*{\close@probsoln@prev}{}% } \newcommand*{\@add@used@problem}[2]{} \newcommand*{\@fetch@excluded@list}[2]{% \def#1{}% } \newcommand*{\@add@newprevlist}[1]{} \newcommand*{\close@probsoln@prev}{} \AtEndDocument{\close@probsoln@prev} \newcommand*{\previousproblem}[3]{% \ifnum#3>\probsoln@prev@cutoff \ifcsundef{prob@db@#2}{\prob@newdb{#2}}{}% \expandafter\gdef\csname @prev@problem@#2@#1\endcsname{#3}% \edef\@prev@list{\csname probsoln@prev@list@#2\endcsname}% \ifdefempty{\@prev@list}% {% \expandafter\xdef\csname probsoln@prev@list@#2\endcsname{#1}% }% {% \expandafter\xdef\csname probsoln@prev@list@#2\endcsname{% \@prev@list,#1}% }% \fi } \newcommand*{\usedproblem}[3]{% \ifnum#3=\probsoln@startyear \expandafter\def\csname @used@problem@#2@#1\endcsname{#3}% \fi } \newcommand*{\prob@db@default}{} \newcommand*{\prob@databases}{default} \newcommand*{\prob@db@default@solutions}{} \newcommand*{\prob@newdb}[1]{% \ifcsundef{prob@db@#1}% {% \expandafter\gdef\csname prob@db@#1\endcsname{}% \xdef\prob@databases{\prob@databases,#1}% \expandafter\gdef\csname prob@db@#1@solutions\endcsname{}% \@add@newprevlist{#1}% }% {% \PackageError{probsoln}{Data set `#1' is already defined}% {Data set names must be unique}% }% } \newcommand*{\prob@currentdb}{default} \newcommand{\moveproblem}[3]{% \@moveproblem{#1}{#2}{#3}% \expandafter\let\expandafter\@tmpdblist \csname prob@db@#2\endcsname \expandafter\gdef\csname prob@db@#2\endcsname{}% \@for\@tmplab:=\@tmpdblist\do{% \ifthenelse{\equal{\@tmplab}{#1}}{}{% \expandafter\ifx\csname prob@db@#2\endcsname\@empty \expandafter\xdef\csname prob@db@#2\endcsname{\@tmplab}% \else \expandafter\xdef\csname prob@db@#2\endcsname{% \csname prob@db@#2\endcsname,% \@tmplab}% \fi }% }% } \newcommand*{\@moveproblem}[3]{% \ifcsempty{prob@db@#3}% {% \expandafter\xdef\csname prob@db@#3\endcsname{#1}% }% {% \expandafter\xdef\csname prob@db@#3\endcsname{% \csname prob@db@#3\endcsname,#1}% }% \edef\do@movedata{% \noexpand\global\noexpand\let\expandafter\noexpand \csname prob@data@#3@#1\endcsname=% \expandafter\noexpand\csname prob@data@#2@#1\endcsname \noexpand\global\noexpand\let \expandafter\noexpand \csname prob@data@#2@#1\endcsname=\noexpand\undefined }% \do@movedata \edef\do@moveargN{% \noexpand\global\noexpand\let\expandafter\noexpand \csname prob@argN@#3@#1\endcsname=% \expandafter\noexpand\csname prob@argN@#2@#1\endcsname \noexpand\global\noexpand\let \expandafter\noexpand \csname prob@argN@#2@#1\endcsname=\noexpand\undefined }% \do@moveargN \@ifundefined{prob@args@#2@#1}{}{% \edef\do@moveargs{% \noexpand\global\noexpand\let\expandafter\noexpand \csname prob@args@#3@#1\endcsname=% \expandafter\noexpand\csname prob@args@#2@#1\endcsname \noexpand\global\noexpand\let \expandafter\noexpand \csname prob@args@#2@#1\endcsname=\noexpand\undefined }% \do@moveargs }% } \newcommand{\prob@newproblem}[5]{% \@ifundefined{prob@db@#2}{\prob@newdb{#2}}{}% \@ifundefined{prob@data@#2@#3}% {% \let\@tmp=\undefined \newcommand\@tmp[#1]{#4}% \expandafter\global\expandafter\let \csname prob@data@#2@#3\endcsname=\@tmp \expandafter\xdef\csname prob@argN@#2@#3\endcsname{\number#1}% \let\@tmp=\undefined \expandafter\ifx\csname prob@db@#2\endcsname\@empty \expandafter\xdef\csname prob@db@#2\endcsname{#3}% \else \expandafter\xdef\csname prob@db@#2\endcsname{% \csname prob@db@#2\endcsname,#3}% \fi \ifx\@empty#5\@empty \else \edef\thisprob@currentdb{#2}% \edef\thisprob@currentlabel{#3}% \expandafter\@setdefaultprobargs\expandafter{#5}% \fi }% {% \PackageError{probsoln}{Problem `#3' is already defined for data base `#2'}{Problem labels must be unique for each data base}% }% } \newcommand{\@prob@gobblethree}[3]{} \newcommand{\@prob@getargs}[3]{% \message{Problem `#3' (in data base `#2') requires #1 argument(s).^^J Please specify (e.g. \csname @prob@getargs@eg@\romannumeral#1\endcsname):}% \read-1to\@tmp \expandafter\global\expandafter\let \csname prob@args@#2@#3\endcsname=\@tmp } \def\@prob@getargs@eg@i{{12}} \def\@prob@getargs@eg@ii{{5}{3}} \def\@prob@getargs@eg@iii{{4}{5}{2}} \def\@prob@getargs@eg@iv{{5}{3}{10}{8}} \def\@prob@getargs@eg@v{{5}{3}{10}{8}{4}} \def\@prob@getargs@eg@vi{{5}{3}{10}{8}{4}{24}} \def\@prob@getargs@eg@vii{{5}{3}{10}{8}{4}{24}{32}} \def\@prob@getargs@eg@viii{{5}{3}{10}{8}{4}{24}{32}{9}} \def\@prob@getargs@eg@ix{{5}{3}{10}{8}{4}{24}{32}{9}{2}} \let\@prob@do@getargs\@prob@gobblethree \newcommand*{\setprobargs}[3][default]{% \expandafter\gdef\csname prob@args@#1@#2\endcsname{#3}% } \newcommand*{\@setdefaultprobargs}[1]{% \ifusedefaultprobargs \setprobargs[\thisprob@currentdb]{\thisprob@currentlabel}{#1}% \fi } \long\def\long@collect@body#1{% \@envbody{\@xp#1\@xp{\the\@envbody}}% \edef\process@envbody{\the\@envbody\@nx\end{\@currenvir}}% \@envbody\@emptytoks \def\begin@stack{b}% \begingroup \if@prob@fragile \obeylines\obeyspaces \@makeother\# \@makeother\% \fi \@xp\let\csname\@currenvir\endcsname\long@collect@@body \edef\process@envbody{\@xp\@nx\csname\@currenvir\endcsname}% \process@envbody } \long\def\long@addto@envbody#1{% \toks@{#1}% \edef\@psn@tmp{\the\@envbody\the\toks@}% \global\@envbody\@xp{\@psn@tmp}% } \long\def\long@collect@@body#1\end#2{% \protected@edef\begin@stack{% \long@push@begins#1\begin\end \@xp\@gobble\begin@stack }% \ifx\@empty\begin@stack \endgroup \@checkend{#2}% \long@addto@envbody{#1}% \else \long@addto@envbody{#1\end{#2}}% \fi \process@envbody } \long\def\long@push@begins#1\begin#2{% \ifx\end#2\else b\@xp\long@push@begins\fi } {\obeylines \gdef\@char@M{^^M}% } \@onelevel@sanitize\@char@M \def\@beg@env@string{\begin} \@onelevel@sanitize\@beg@env@string \def\@end@env@string{\end} \@onelevel@sanitize\@end@env@string \edef\def@replace@markers{% \noexpand\def\noexpand\do@replace@charM##1\@char@M##2\noexpand\end@replace@marker{% \noexpand\expandafter\noexpand\toks@\noexpand\expandafter{\noexpand\replace@text}% \noexpand\ifx\noexpand\relax##2\noexpand\relax \noexpand\edef\noexpand\replace@text{\noexpand\the\noexpand\toks@##1}% \noexpand\let\noexpand\do@replacenext\noexpand\replace@mark@noop \noexpand\else \noexpand\edef\noexpand\replace@text{\noexpand\the\noexpand\toks@##1^^J}% \noexpand\let\noexpand\do@replacenext\noexpand\do@replace@charM \noexpand\fi \noexpand\do@replacenext##2\noexpand\end@replace@marker }% \noexpand\def\noexpand\doreplace@begverb##1\@beg@env@string##2\noexpand\end@replace@marker{% \noexpand\expandafter\noexpand\toks@\noexpand\expandafter{\noexpand\replace@text}% \noexpand\ifx\noexpand\relax##2\noexpand\relax \noexpand\edef\noexpand\replace@text{\noexpand\the\noexpand\toks@##1}% \noexpand\let\noexpand\do@replacenext\noexpand\replace@mark@noop \noexpand\else \noexpand\edef\noexpand\replace@text{\noexpand\the\noexpand\toks@ ##1\expandafter\@gobble\string\\begin}% \noexpand\let\noexpand\do@replacenext\noexpand\doreplace@begverb \noexpand\fi \noexpand\do@replacenext##2\noexpand\end@replace@marker }% \noexpand\def\noexpand\doreplace@endverb##1\@end@env@string##2\noexpand\end@replace@marker{% \noexpand\expandafter\noexpand\toks@\noexpand\expandafter{\noexpand\replace@text}% \noexpand\ifx\noexpand\relax##2\noexpand\relax \noexpand\edef\noexpand\replace@text{\noexpand\the\noexpand\toks@##1}% \noexpand\let\noexpand\do@replacenext\noexpand\replace@mark@noop \noexpand\else \noexpand\edef\noexpand\replace@text{\noexpand\the\noexpand\toks@ ##1\expandafter\@gobble\string\\end}% \noexpand\let\noexpand\do@replacenext\noexpand\doreplace@endverb \noexpand\fi \noexpand\do@replacenext##2\noexpand\end@replace@marker }% \noexpand\def\noexpand\replace@markers##1{% \noexpand\def\noexpand\replace@text{}% \noexpand\expandafter\noexpand\do@replace@charM##1\@char@M\relax\noexpand\end@replace@marker \noexpand\let##1\noexpand\replace@text \noexpand\def\noexpand\replace@text{}% \noexpand\expandafter\noexpand\doreplace@begverb##1\@beg@env@string\relax\noexpand\end@replace@marker \noexpand\let##1\noexpand\replace@text \noexpand\def\noexpand\replace@text{}% \noexpand\expandafter\noexpand\doreplace@endverb##1\@end@env@string\relax\noexpand\end@replace@marker \noexpand\let##1\noexpand\replace@text } } \def\replace@mark@noop#1\end@replace@marker{} \def@replace@markers \newenvironment{defproblem}[1][0]{% \edef\@prob@currentargN{\number0#1}% \@defproblem@beginenv }{} \newcommand*{\@defproblem@beginenv}[2][]{% \def\@prob@currentdefaultargs{#1}% \def\@prob@currentlabel{#2}% \@defproblem@beginenv@ } \newcommand*{\@defproblem@beginenv@}[1][]{% \setkeys{probsoln}{#1}% \long@collect@body\prob@do@defproblem } \newcommand{\prob@do@newproblem}[1]{% \if@prob@fragile \probsoln@process@fragile{#1}% \protected@edef\do@def@new@problem{% \noexpand\prob@newproblem {\@prob@currentargN}% {\prob@currentdb}% {\@prob@currentlabel}% {% \noexpand\probsoln@write@tmp{\@prob@tmp@problem}% \noexpand\probsoln@read@tmp }% {\@prob@currentdefaultargs}% }% \else \toks@{#1}% \protected@edef\do@def@new@problem{% \noexpand\prob@newproblem {\@prob@currentargN}% {\prob@currentdb}% {\@prob@currentlabel}% {\the\toks@}% {\@prob@currentdefaultargs}% }% \fi \do@def@new@problem } \let\prob@do@defproblem=\prob@do@newproblem \newenvironment{onlysolution}[1][]{% \setkeys{probsoln}{#1}% \long@collect@body\do@onlysolution }{} \newcommand{\do@onlysolution}[1]{% \ifshowanswers \probsoln@do@body{#1}% \fi \@ifundefined{@prob@currentlabel} {}% {% \expandafter \psn@add@unique@label \csname prob@db@\prob@currentdb @solutions\endcsname{% \@prob@currentlabel }% }% } \newcommand*{\psn@add@unique@label}[2]{% \ifx#1\@empty \xdef#1{#2}% \else \edef\@tmp@label{#2}% \expandafter\DTLifinlist\expandafter{\@tmp@label}{#1}% {}% ignore {\xdef#1{#1,\@tmp@label}}% \fi } \providecommand{\DTLifinlist}[4]{% \def\@dtl@doifinlist##1,#1,##2\end@dtl@doifinlist{% \def\@before{##1}% \def\@after{##2}% }% \expandafter\@dtl@doifinlist\expandafter,#2,#1,\@nil \end@dtl@doifinlist \ifx\@after\@nnil #4% \else #3% \fi } \newenvironment{onlyproblem}[1][]{% \setkeys{probsoln}{#1}% \long@collect@body\do@onlyproblem }{} \newcommand{\do@onlyproblem}[1]{% \ifshowanswers \else \probsoln@do@body{#1}% \fi } \newcommand{\probsoln@do@body}[1]{% \if@prob@fragile \probsoln@process@fragile{#1}% \probsoln@write@tmp{\@prob@tmp@problem}% \probsoln@read@tmp \else #1% \fi } \newcommand{\probsoln@process@fragile}[1]{% \def\@prob@tmp@problem{#1}% \@onelevel@sanitize\@prob@tmp@problem \replace@markers\@prob@tmp@problem } \newcommand{\probsoln@write@tmp}[1]{% \immediate\openout\probsoln@write=\ProbSolnFragileFile.\ProbSolnFragileExt \immediate\write\probsoln@write{#1}% \immediate\closeout\probsoln@write } \newcommand{\probsoln@read@tmp}{% \input{\ProbSolnFragileFile.\ProbSolnFragileExt}% } \newcommand{\useproblem}[2][default]{% \def\@prob@currentlabel{#2}% \def\prob@currentdb{#1}% \prob@showdraftlabel{#1}{#2}% \@add@used@problem{#2}{#1}% \let\@useprob@next=\relax \@ifundefined{prob@data@#1@#2}% {% \PackageError{probsoln}% {Problem `#2' is not defined in data set `#1'}{}% }% {% \def\@useprob@next{\csname prob@data@#1@#2\endcsname}% }% \@useprob@next } \newcommand*{\loadallproblems}[2][default]{% \bgroup \let\par\relax \edef\prob@currentdb{#1}% \input{#2}% \egroup } \newcommand{\prob@do@selectedproblem}[1]{% \expandafter\DTLifinlist\expandafter{\@prob@currentlabel}{\prob@selectedlabels}% {% \prob@do@newproblem{#1}% }% {}% } \newcommand{\loadselectedproblems}[3][default]{% \bgroup \let\par\relax \edef\prob@currentdb{#1}% \edef\prob@selectedlabels{#2}% \let\prob@do@defproblem=\prob@do@selectedproblem \input{#3}% \egroup } \newcommand{\prob@do@exceptedproblem}[1]{% \expandafter\DTLifinlist\expandafter{\@prob@currentlabel}{\prob@selectedlabels}% {}% {% \prob@do@newproblem{#1}% }% } \newcommand{\loadexceptproblems}[3][default]{% \bgroup \let\par\relax \edef\prob@currentdb{#1}% \edef\prob@selectedlabels{#2}% \let\prob@do@defproblem=\prob@do@exceptedproblem \input{#3}% \egroup } \newcommand{\prob@add@currentlabel}[1]{% \ifx\prob@selectedlabels\@empty \xdef\prob@selectedlabels{\@prob@currentlabel}% \else \xdef\prob@selectedlabels{\prob@selectedlabels,\@prob@currentlabel}% \fi } \newif\iffirstpass \firstpasstrue \newcommand{\loadrandomproblems}[3][default]{% \@fetch@excluded@list{\@excl@list}{#1}% \@loadrandomproblems{#1}{#2}{#3}{\@excl@list}% } \newcommand{\loadrandomexcept}[4][default]{% \@loadrandomproblems{#1}{#2}{#3}{#4}% } \newcommand{\@loadrandomproblems}[4]{% \bgroup \let\par\relax \def\prob@db@reserved{}% \def\prob@currentdb{reserved}% \edef\prob@selectedlabels{}% \let\prob@do@defproblem=\prob@add@currentlabel \firstpasstrue \@for\@thisfile:=#3\do{\input{\@thisfile}}% \@probselN=0\relax \@for\@thislabel:=\prob@selectedlabels\do{% \edef\@if@in@list{\noexpand\DTLifinlist{\@thislabel}{#4}}% \@if@in@list {}% {% \advance\@probselN by 1\relax \expandafter \edef\csname @prob@tmp@\romannumeral\@probselN\endcsname{% \@thislabel}% }% }% \edef\@do@excludedlist{#4}% \ifdefempty{\@do@excludedlist}% {}% {\def\@do@excludedlist{(Excluded list: #4.) }}% \ifnum\@probselN=0\relax \PackageWarning{probsoln}{You have requested \number#2\space\space problem(s) but there are no available problems in `#3'. \@do@excludedlist No problems will be selected}% \else \shuffle{@prob@tmp@}{\@probselN}% \ifnum\@probselN<#2\relax \ifnum\@probselN=1\relax \PackageWarning{probsoln}{You have requested \number#2\space\space problem(s) but there is only 1 problem available in `#3'. \@do@excludedlist Only 1 problem will be selected}% \else \PackageWarning{probsoln}{You have requested \number#2\space\space problem(s) but there are only \number\@probselN\space problems available in `#3'. \@do@excludedlist Only \number\@probselN\space problems will be selected}% \fi \else \@probselN=#2\relax \fi \fi \@probN=0\relax \def\prob@selectedlabels{}% \whiledo{\@probN<\@probselN}{% \advance\@probN by 1\relax \ifx\prob@selectedlabels\@empty \edef\prob@selectedlabels{% \csname @prob@tmp@\romannumeral\@probN\endcsname}% \else \edef\prob@selectedlabels{% \prob@selectedlabels,% \csname @prob@tmp@\romannumeral\@probN\endcsname}% \fi }% \let\prob@do@defproblem=\prob@do@selectedproblem \firstpassfalse \@for\@thisfile:=#3\do{\input{\@thisfile}}% \@ifundefined{prob@db@#1}{\prob@newdb{#1}}{}% \@for\@thislabel:=\prob@selectedlabels\do{% \@moveproblem{\@thislabel}{reserved}{#1}% }% \let\prob@selectedlabels=\undefined \egroup } \newcommand{\foreachproblem}[2][default]{% \@ifundefined{prob@db@#1}{% \PackageError{probsoln}{Data base `#1' is not defined}{}% }{% \expandafter\let\expandafter\@tmp\csname prob@db@#1\endcsname \@for\thisproblemlabel:=\@tmp\do{% \expandafter\ifnum \csname prob@argN@#1@\thisproblemlabel\endcsname>0\relax \@ifundefined{prob@args@#1@\thisproblemlabel}{% \expandafter\@prob@getargs \csname prob@argN@#1@\thisproblemlabel\endcsname {#1}{\thisproblemlabel}}{}% \expandafter\let\expandafter\thisproblemargs \csname prob@args@#1@\thisproblemlabel\endcsname \else \let\thisproblemargs\@empty \fi \expandafter\toks@\expandafter{\thisproblemargs}% \edef\thisproblem{\noexpand\useproblem[#1]{\thisproblemlabel}% \the\toks@}% #2% }% }% } \newcommand{\foreachsolution}[2][default]{% \@ifundefined{prob@db@#1}{% \PackageError{probsoln}{Data base `#1' is not defined}{}% }{% \expandafter\let\expandafter\@tmp\csname prob@db@#1@solutions\endcsname \@for\thisproblemlabel:=\@tmp\do{% \ifx\thisproblemlabel\@empty \else \expandafter\ifnum \csname prob@argN@#1@\thisproblemlabel\endcsname>0\relax \@ifundefined{prob@args@#1@\thisproblemlabel}{% \expandafter\@prob@getargs \csname prob@argN@#1@\thisproblemlabel\endcsname {#1}{\thisproblemlabel}}{}% \expandafter\let\expandafter\thisproblemargs \csname prob@args@#1@\thisproblemlabel\endcsname \else \let\thisproblemargs\@empty \fi \expandafter\toks@\expandafter{\thisproblemargs}% \edef\thisproblem{\noexpand\useproblem[#1]{\thisproblemlabel}% \the\toks@}% #2% \fi }% }% } \newcommand{\foreachdataset}[2]{% \@for#1:=\prob@databases\do{#2}} \newcount\@probN \newcount\@probselN \newcount\@rndselctr \newcount\r@ndcur \newcount\@ps@randtmp \r@ndcur=1\relax \newcommand*{\PSNrandseed}[1]{% \ifnum#1=0\relax \PackageWarning{probsoln}{Can't have 0 as random seed, changing to 1}% \global\r@ndcur=1\relax \else \global\r@ndcur=#1\relax \fi \PackageInfo{probsoln}{Random Seed = \number\r@ndcur}% } \newcommand*{\PSNgetrandseed}[1]{#1=\r@ndcur\relax} \newcommand*{\PSNrand}{% \@ps@randtmp=\r@ndcur \multiply\@ps@randtmp by 16811\relax \r@ndcur=\@ps@randtmp \global\divide\r@ndcur by 39989\relax \global\multiply\r@ndcur by 39989\relax \advance\@ps@randtmp by -\r@ndcur \global\r@ndcur = \@ps@randtmp \ifnum\r@ndcur=0\relax \global\r@ndcur=1\relax \fi } \newcommand*{\PSN@old@rand}{% \@ps@randtmp=\r@ndcur \multiply\@ps@randtmp by 16807\relax \r@ndcur=\@ps@randtmp \global\divide\r@ndcur by 120001\relax \global\multiply\r@ndcur by 120001\relax \advance\@ps@randtmp by -\r@ndcur \global\r@ndcur = \@ps@randtmp \ifnum\r@ndcur=0\relax \global\r@ndcur=1\relax \fi } \newcommand*{\PSNuseoldrandom}{% \let\PSNrand\PSN@old@rand } \newcommand{\PSNrandom}[2]{% \PSNrand #1=\r@ndcur \@ps@randtmp=\r@ndcur \divide\@ps@randtmp by #2\relax \multiply\@ps@randtmp by #2\relax \advance#1 by -\@ps@randtmp \advance#1 by 1\relax } \newcommand{\random}[3]{% \ifnum#2=1\relax \PSNrandom{\value{#1}}{#3}% \else \@rndselctr=#3% \advance\@rndselctr by -#2\relax \advance\@rndselctr by 1\relax \PSNrandom{\value{#1}}{\@rndselctr}% \addtocounter{#1}{#2}% \addtocounter{#1}{-1}% \fi } \newcount\@shfctr \newcount\@shfA \newcount\@shfB \newcommand{\shuffle}[2]{% \@shfctr=1\relax \whiledo{\@shfctr < 101}% {% \PSNrandom{\@shfA}{#2}\PSNrandom{\@shfB}{#2}% \ifnum\@shfA=\@shfB \else \edef\@@tmpA{\csname#1\romannumeral\@shfA\endcsname}% \let\@tmpA=\@@tmpA \edef\@@tmpB{\csname#1\romannumeral\@shfB\endcsname}% \let\@tmpB=\@@tmpB \expandafter\xdef\csname#1\romannumeral\@shfA\endcsname{\@tmpB}% \expandafter\xdef\csname#1\romannumeral\@shfB\endcsname{\@tmpA}% \fi \advance\@shfctr by 1\relax }% } \newcount\@ps@forrand \newcount\@ps@forrand@level \newcommand{\doforrandN}[4]{% \global\advance\@ps@forrand@level by 1\relax {% \@ps@forrand=0\relax \@for#2:=#3\do{% \advance\@ps@forrand by 1\relax \expandafter \edef\csname @doforrandN@\number\@ps@forrand@level @\romannumeral\@ps@forrand\endcsname{#2}% }% \ifnum\@ps@forrand<#1\relax \PackageError{probsoln}{Can't randomly select \number#1\space item(s)}{You have requested \number#1\space item(s), but there are only \number\@ps@forrand\space item(s) in the list: #3}% \else \shuffle{@doforrandN@\number\@ps@forrand@level @}{\@ps@forrand}% \ifnum#1>0\relax \@ps@forrand=0\relax \loop \advance\@ps@forrand by 1\relax \edef#2{\csname @doforrandN@\number\@ps@forrand@level @\romannumeral\@ps@forrand\endcsname}% #4% \ifnum\@ps@forrand<#1\relax \repeat \fi \fi }% \global\advance\@ps@forrand@level by -1\relax } \newcommand*{\newproblem}{\@ifstar\@snewproblem\@newproblem} \newcommand{\@snewproblem}[1][0]{% \def\@newprob@argN{#1}% \@s@newproblem }% \newcommand{\@s@newproblem}[3][]{% \begin{defproblem}[\@newprob@argN][#1]{#2}% #3% \end{defproblem}% } \newcommand{\@newproblem}[1][0]{% \def\@newprob@argN{#1}% \@ns@newproblem } \newcommand{\@ns@newproblem}[4][]{% \begin{defproblem}[\@newprob@argN][#1]{#2}% #3% \begin{onlysolution}% \begin{solution}% #4% \end{solution}% \end{onlysolution}% \end{defproblem}% } \newcommand*{\selectallproblems}[1]{{\loadallproblems[#1]{#1}}% \foreachproblem[#1]{\PSNitem\thisproblem\endPSNitem}} \newcommand*{\selectrandomly}[2]{% {\loadrandomproblems[#1]{#2}{#1}}% \foreachproblem[#1]{\PSNitem\thisproblem\endPSNitem}% } \newenvironment{PSNitem}{\item}{} \@ifundefined{solution}{% \newenvironment{solution}{\par\noindent\textbf{\solutionname:}\space \ignorespaces}{}% }{} \newcommand*{\solutionname}{Solution} \newenvironment{textenum}{% \ifnum\@enumdepth>\thr@@ \@toodeep \else \advance\@enumdepth by 1\relax \edef\@enumctr{enum\romannumeral\the\@enumdepth}% \let\@item\@textitem \def\@itemlabel{% \refstepcounter{\@enumctr}% \csname label\@enumctr\endcsname }% \setcounter{\@enumctr}{0}% \fi \ignorespaces }% {% } \def\@textitem[#1]{#1\space\ignorespaces} \newcommand*{\correctitemformat}[1]{\fbox{#1}} \newcommand*{\incorrectitemformat}[1]{% \hspace{\fboxsep}\hspace{\fboxrule}#1} \newcommand*{\correctitem}{\@inmatherr\correctitem \@ifnextchar[\@correctitem{\@noitemargtrue\@correctitem[\@itemlabel]}} \def\@correctitem[#1]{% \ifshowanswers \@item[\correctitemformat{#1}]% \else \@item[#1]% \fi} \newcommand*{\incorrectitem}{\@inmatherr\incorrectitem \@ifnextchar[\@incorrectitem{\@noitemargtrue\@incorrectitem[\@itemlabel]}} \def\@incorrectitem[#1]{% \ifshowanswers \@item[\incorrectitemformat{#1}]% \else \@item[#1]% \fi} \endinput %% %% End of file `probsoln.sty'.