Twinkle, Twinkle, little star...
Having enjoyed @Humn's recent MathJax puzzles (MathJax exposed and MathJax re-flex), I decided to contribute some of my own.
This one is a classic $\rm\TeX$ exercise, but since MathJax doesn't implement counter registers, numeric operations, or looping and if-then control structures, it takes a bit more ingenuity than in actual $\rm\TeX$.
Goal: find the minimal replacement for (replace this line)
in the following MathJax code
$$\require{begingroup}\begingroup
(replace this line)
\stars{57}
\endgroup$$
so that the output is 57 asterisks in the \texttt{}
font (and nothing else):
$$\texttt{*********************************************************}$$
The Catch? Your code should produce the proper number of stars no matter what non-negative integer is given in place of 57
(including 0).
When counting the length of your solution, control sequences count as 1 character, as do macro parameters #1
(and ##
if needed, and even ##1
if used in a nested macro definition), and pairs of braces ({
with a paired }
count as one). So \stars
and \s
each count as 1. All other non-space characters count as 1, but please do use spaces and line breaks for clarity.
Example: \def \x #1:#2\x {#1#1\stop}
has a character count of 10.
To make this easier, I've made a code snippet that counts the tokens for you. (Unfortunately, there are no code snippets on this site, so I had to use the SE sandbox for it.) Run the snippet, then past your MathJax code into the resulting text area and press "Count tokens".
Do not use any additional \require{...}
macros, or defeat the final call to \endgroup
. Admittedly, the audience for this puzzle is small. Please share any answer that even almost works. A solution is known, and will be posted after a suitable period, if no other solution is offered.
In displaying formatted code in a spoiler, feel free to omit $$
, which doesn’t play well in that combination (or copy-and-paste the pair above, which have an invisible character between them, allowing the spoiler to display properly).
NOTE ☆ Before posting an answer, be sure to test it on a freshly loaded browser page ☆ Might also need to reload the page while editing, as inadvertent indiscretions in one edit can pervert MathJax results during later edits ☆
Answer
Overhauled solution — just $\, \texttt{\stars{}} \:$ and $\, \texttt{\N} \:$ while borrowing $\, \texttt{\endgroup} \:$ as a delimiter
$\small \texttt{\stars{57}}$ — solution with 47 code tokens, as $\small\texttt{\stars{}}$ and one dynamic macro — base 10: $$\require{begingroup}\begingroup \def \stars #1#2 #3\endgroup{ \def \N ##1#1 ##2 ##3 ##4 ##5 ##6 ##7 { ##3 \stars ##4#2 #3##6\endgroup} \N 9 8 7 6 5 4 3 2 1 0 #2 % \texttt * #3 #3#3#3#3 #1 #1 } \stars{57} \endgroup$$
$\small \texttt{\starsTwo{111001}}$ — 34 code tokens — base 2: $$\require{begingroup}\begingroup \def \starsTwo #1#2 #3\endgroup{ \def \N ##1#1##2 ##3 ##4 ##5 ##6 { ##3 \starsTwo ##5#2 #3##4\endgroup } \N 1 \texttt* 0 #2 % #3 #1 #1 } \starsTwo{111001} \endgroup$$
$\small \texttt{\starsEight{71}}$ — 40 ½ code tokens — base 8: $$\require{begingroup}\begingroup \def \starsEight #1#2 #3\endgroup{ \def \N ##1#1 ##2 ##3 ##4 ##5 ##6 { ##4 \starsEight ##2#2 #3##5\endgroup} \N 7 6 5 4 3 2 1 0 \texttt * {} #2 % #3 #1 #1 } \starsEight{71} \endgroup$$
Base 8’s ½ token is a nonfunctional $\small\texttt{{}}$ that allows an otherwise blank line to reach MathJax’s interpreter. Along this approach, base 8 is might be optimally efficient in that every larger base seems to require adding non-digit tokens to base 2's minimum.
Once again, squeezing out code tokens has burdened execution, and added scads of spaces as well, as a mere $\small\texttt{\stars{87}}$ exceeds MathJax’s default safety limits and the call to $\small\texttt{\N}$ uses 113 spaces. (Notice the scroll bar below the code.)
. - - - WRUNG OUT \stars{} - - - -
$$\require{begingroup}\begingroup
\def\stars#1#2
#3\endgroup{
\def\N##1#1 ##2 ##3 ##4 ##5 ##6 ##7 {
##3\stars##4#2
#3##6\endgroup}
\N9 8 7 6 5 4 3 2 1 0 #2 % \texttt * #3 #3#3#3#3 #1 #1 }
\stars{57}
\endgroup$$
.
. - - - AIRED OUT \stars{} - - -
$$\require{begingroup}\begingroup
%
\def \stars #1#2
#3\endgroup{
\def \N ##1#1 ##2 ##3 ##4 ##5 ##6 ##7 {
##3 \stars ##4#2
#3##6\endgroup}
\N 9 8 7 6 5 4 3 2 1 0 #2 % \texttt * #3 #3#3#3#3 #1 #1 }
%
\stars{57}
\endgroup$$
.
. leading digit's current value #1
. subsequent digits #2
. accumulated ***...* stars #3
. ##1 (skip to current leading digit)
. ##2 (skip to ##3)
. % if done ##3 (usually empty)
. leading digit's next value(s) ##4 decrement or (two values:) \texttt * or empty
. ##5 (skip to ##6)
. add stars to #3 ##6 \texttt * or #3 (double) or #3#3#3#3 (quintuple)
. ##7 (leftovers)
The code for base 2, $\small\texttt{\starsTwo{}}$, is relatively tidy while the code for base 8, $\small\texttt{\starsEight{}}$, is compact in its own vertical way. (Notice the scroll bar along the right side.)
. - - - \starsTwo{} - - -
$$\require{begingroup}\begingroup
%
\def \starsTwo #1#2
#3\endgroup{
\def \N ##1#1##2 ##3 ##4 ##5 ##6 {
##3 \starsTwo ##5#2
#3##4\endgroup }
\N 1 \texttt* 0 #2 % #3 #1 #1 }
\starsTwo{111001}
\endgroup$$
.
.
. leading digit's current value #1
. subsequent digits #2
. accumulated ***...* stars #3
. ##1 (skip to current leading digit)
. ##2 (skip to ##3)
. \S for next call ##3 (empty when done)
. leading digit's next value ##4 decrement or \texttt or * or empty
. add stars to #3 ##5 \texttt* or \texttt * or #3 (double)
. ##6 (leftovers)
.
.
. - - - \starsEight{} - - -
$$\require{begingroup}\begingroup
%
\def \starsEight #1#2
#3\endgroup{
\def \N ##1#1
##2
##3 ##4 ##5 ##6 {
##4 \starsEight ##2#2
#3##5\endgroup}
\N 7
6
5
4
3
2
1
0
\texttt
*
{}
#2 % #3 #1
#1
}
\starsEight{71}
\endgroup$$
Yes, that’s $\small\texttt{\endgroup}$ being borrowed as a terminal delimiter so that $\small\texttt{\stars{}}$ can accumulate $\small\texttt{***...*}$ stars into an initially-empty parameter after the line break. This does not defeat $\small\texttt{\endgroup}$ because it is rewritten each time, on the line that remains active when $\small\texttt{%}$ comments out the recursive call to $\small\texttt{\stars{}}$. In the following trace, $\small\texttt{\t}$ represents $\small\texttt{\texttt}$ while $\large \raise-.3ex{\unicode{8629}}$ represents the line break.
$\require{begingroup}\begingroup \def \Eol {{ \large \kern2mu \raise-.3ex{\unicode{8629}} \kern1mu }} \def \t #1{{ \normalsize \texttt{#1} \large \strut }} % \def \stars #1#2 #3\end{ \def \N ##1#1 ##2 ##3 ##4 ##5 ##6 ##7 { \texttt {##3 \stars ##4#2} \Eol \tiny \texttt {#3##6} \, \scriptsize\texttt{\endgroup} \\[-1ex] ##3 \stars ##4#2 #3##6\end} \N 9 8 7 6 5 4 3 2 1 0 #2 % \t * #3 #3#3#3#3 #1 #1 } % \small \begin{array}{l} \texttt{ \stars {23}} \Eol \scriptsize\texttt{\endgroup} \\[-1ex] \stars{23} \end{array} \endgroup$
The present approach is built on Davide Cervone’s algorithm that accumulates stars by appending each leading digit’s number of stars and, if more digits follow, multiplying that total by $\small 10$ and recursively calling $\small\texttt{\stars{}}$. Leading digits are treated like states of a state machine with branch points at the digits$\scriptsize \raise.2ex/$states $\small\texttt{0}$ and $\small\texttt{*}$. Here are the steps in rendering $\small\texttt{\stars{2301}}$.
$$\require{begingroup}\begingroup \small \def \S #1{ \textsf {#1} } \def \T #1{{ \small \texttt {#1} }} \def \U #1{{ \scriptsize \K\!\texttt{#1}\K }} \def \P #1{{ \scriptsize ( \kern1mu\raise-.1ex{\texttt{#1}}\kern1mu ) }} \def \K { \kern-.5em } \def \Zip {{ \tiny \raise.6ex - }} \def \L { \\[ .4ex] } \def \M { \\[-.7ex] } \def \Timess {{ \small \raise .1ex \times \kern 1mu }} \def \Times {{ \small \raise .1ex \times }} \def \Pluss {{ \scriptsize\raise .1ex + \kern 2mu }} \def \Plus {{ \scriptsize\raise.1ex + \kern1mu }} \kern-.5em \begin{array}{rcccc} &\rlap {\kern .85em \S {Original algorithm}} \\ & \rlap{ \kern .7em \S{Direct and efficient}} \\[.5ex] & & & & \\[-.7ex] &\K\S{Leading}\K&\S{Further}&\K\S{Previous}\K& \\[-.7ex] \S{Step}& \S{digit} & \S{digits}& \S{total} & \S{Operation} \\[-.5ex] & \P{#1} & \P{#2} & \P{#3} & \P{\N...} \\[1ex] & & & & \L \sf a.~ &\tt 2 &\tt 3 0 1 & \Zip & \Pluss 2 \M\L \sf b.~ &\tt 2 &\tt 3 0 1 &\tt 2 & \Times 10 \M\M\L \sf c.~ &\tt 3 &\tt 0 1 &\tt 20 & \Pluss 3 \M\M\L \sf d.~ &\tt 3 &\tt 0 1 &\tt 23 & \Times 10 \M\M\L \sf e.~ &\tt 0 &\tt 1 &\tt 230 & \Times 10 \M\M\L \sf f.~ &\tt 1 &\tt \Zip &\tt 2300 & \Pluss 1 \L \sf g.~ &\tt 1 &\tt \Zip &\tt 2301 & \S{done} \end {array} \kern4em \begin{array}{rcccc} &\rlap {\kern .9em \S {Solution's algorithm}} \\ & \rlap{ \kern-1.5em \S{Small steps, inefficient, less code}} \\[.5ex] &\K\S{State /}\K& & & \\[-.7ex] &\K\S{leading}\K&\S{Further}&\K\S{Previous}\K& \\[-.7ex] \S{Step}& \S{digit} & \S{digits}& \S{total} & \S{Operation} \\[-.5ex] & \P{#1} & \P{#2} & \P{#3} & \P{\N...} \\[1ex] 1.~~ &\K \T{{2301}}\K& \Zip & \Zip & \raise.6ex*\S{unwrap}\,\L 2.~~ &\tt 2 &\tt 3 0 1 & \Zip & \Plus 1 \M 3.~~ &\tt 1 &\tt 3 0 1 &\tt 1 & \Plus 1 \L 4.~~ &\tt 0 &\tt 3 0 1 &\tt 2 & \Zip \M 5.~~ & \!\U{\texttt} &\tt 3 0 1 &\tt 2 & \Timess 2 \M 6.~~ &\tt * &\tt 3 0 1 &\tt 4 & \Timess 5 \L 7.~~ &\tt 3 &\tt 0 1 &\tt 20 & \Plus 1 \M 9.~~ &\tt 2 &\tt 0 1 &\tt 21 & \Plus 1 \M 10.~~ &\tt 1 &\tt 0 1 &\tt 22 & \Plus 1 \L 11.~~ &\tt 0 &\tt 0 1 &\tt 23 & \Zip \M 12.~~ & \!\U{\texttt} &\tt 0 1 &\tt 23 & \Timess 2 \M 13.~~ &\tt * &\tt 0 1 &\tt 46 & \Timess 5 \L 14.~~ &\tt 0 &\tt 1 &\tt 230 & \Zip \M 15.~~ & \!\U{\texttt} &\tt 1 &\tt 230 & \Timess 2 \M 16.~~ &\tt * &\tt 1 &\tt 460 & \Timess 5 \L 17.~~ &\tt 1 & \Zip &\tt 2300 & \Plus 1 \L 18.~~ &\tt 0 & \Zip &\tt 2301 & \S{done} \end{array}\endgroup$$
$\small\raise.6ex* \sf unwrap$ in step $\small 1$ means that $\small\texttt{{2301}}$, delivered as a lone “digit” from the initial call $\small\texttt{\stars{2301}}$, becomes an ad hoc state that refeeds $\small\texttt{2301}$ to $\small\texttt{\stars}$ as an unwrapped sequence of digits.
$\small\texttt{\texttt}$ and $\small\texttt{*}$ in steps $\small 5, 6, 12, 13, 15$ and $\small 16$ represent the use of those tokens as states — pseudo-digits below $\small\tt 0$ — when they are not needed as text for incremental stars.
The bottom line’s call to $\small\texttt{\N}$ is effectively a state-transition case$\scriptsize \raise.2ex/$switch regime that determines what to do with each current leading digit, what to use as the next leading digit, and whether to reiterate or halt.
. space after possible % = c nnn = 3 spaces after next digit
. 3 spaces after skip = fff | | ssssss = 6 spaces after skip
. space after digit = d | | | | aa = 2 spaces after added stars
. | | | | | |
. _dfffc_nnn ssssss_________aa zzzzzzzzzzzzzzzzzzzz
. \N 9 8 . . . 2 1 0 #2 % \texttt * #3 #3#3#3#3 #1 #1 }
. : : : :
. : : : :
. Any positive digit ...:.....:...... : :
. gets replaced by : : : :
. 1 less and adds _dfffc_nnn ssssss_________aa zzzzzzzzzzzzzzzzzzzz
. \text * to the 1 0 #2 % \texttt * #3 #3#3#3#3 #1 #1 }
. cumulative stars : :
. in #3...........................................:.......:
.
. When no further digits _dfff_cnnn ssssssaa zzzzzzzzzzzzzzzzzzzz
. remain, % is prepended, 0 % \texttt * #3 #3#3#3#3 #1 #1 }
. halting \stars iteration ................: :
. and adding nothing to #3.......................................:
. ............
. When further digits remain, : ::
. they split the space before %, _d ---> fffc___________nnnssssssaa zzzzzzzzzzzzzzzzzzzz
. causing fff to bypass %. 0 #2 % \texttt * #3 #3#3#3#3 #1 #1 }
. : :
. 0 is replaced as the leading .................:.........:
. digit by both \texttt and *
. at the same time, saving _______d_fffcnnnssssss__aa zzzzzzzzzzzzzzzzzzzz
. space even if not code. \texttt * #3 #3#3#3#3 #1 #1 }
. ::
. \texttt and * add 1 or 4 .............................................::..............
. copies of #3 to itself, : :
. multiplying its cumulative _dfffcnnn ssssss________aa zzzzzzzzzzzzzzzzzzzz
. stars by 2 or 5. * #3 #3#3#3#3 #1 #1 }
.
. Initially, all digits are .......................................................................
. encapsulated in #1 as a : :
. single leading digit, so this __dfffc__nnnssssssaazzzzzzzzzzzzzzzzzzzz
. refeeds them unwrapped to \stars. #1 #1 }
A more sophisticated matrix-oriented solution with only one more code token
Without using $\small\texttt{\endgroup}$ as a delimiter, a 48 code-token alternate solution uses a macro with an auxiliary parameter for multiplying more efficiently than the 47 token solution.
$$\require{begingroup}\begingroup \def \stars #1{ \S #1 } \def \S #1#2 #3 #4 { \def \N ##1#1 ##2 ##3 ##4 ##5 ##6 ##7 { ##3 \S ##4#2 #3##6 } \N 9 8 7 6 5 4 3 2 1 0 #2 % \texttt * #3#4 #3 } \stars{57} \endgroup$$
Here the call to $\small\texttt{\N}$ uses 4 fewer tokens, because $~ \small\texttt{#1 #1} ~$ is not needed to unwrap the initial number and because multiplication uses $~ \small\texttt{#3#4 #3} ~$ instead of $~ \small\texttt{#3 #3#3#3#3} \,$. (Again, scroll right.)
$$\require{begingroup}\begingroup
%
\def \stars #1{
\S #1
}
\def \S #1#2
#3 #4 {
\def \N ##1#1 ##2 ##3 ##4 ##5 ##6 ##7 {
##3 \S ##4#2
#3##6 }
\N 9 8 7 6 5 4 3 2 1 0 #2 % \texttt * #3#4 #3 }
%
\stars{57}
\endgroup$$
.
. leading digit's current value #1
. subsequent digits #2
. accumulated ***...* stars #3
. temporary copy of ***...* stars #4 (usually empty)
. ##1 (skip to current leading digit)
. ##2 (skip to ##3)
. % if done ##3 (usually empty)
. leading digit's next value(s) ##4 decrement or (two values:) \texttt* or empty
. ##5 (skip to ##6)
. add stars to #3 (and #4) ##6 \texttt* or #3#4 #3 (sqrt 5) or #3 (double)
. ##7 (leftovers)
In the following trace, $\small\texttt{\t}$ represents $\small\texttt{\texttt}$ while $\large \raise-.4ex{\unicode{8629}}$ represents a line break and $ \small \, \Rule{ .5pt}{.6ex}{0ex} \kern -.3pt \Rule{2.3em}{.5pt}{0ex} \kern-.3pt \Rule{.5pt}{.6ex}{0ex} \, $ represents the 6 spaces between $\small\texttt{#3}$ and $\small\texttt{#4}$.
$\require{begingroup}\begingroup \def \Eol {{ \large \kern1mu \raise-.4ex{\unicode{8629}} \kern2mu }} \def \t #1{{ \normalsize \texttt{#1} \strut }} % \def \stars #1{ \S #1 } % \def \S #1#2 #3 #4 { \rlap { \small \texttt {\S #1#2} \, \Eol {\tiny \texttt{#3}} \, \Rule{ .5pt}{.6ex}{0ex} \kern -.3pt \Rule{2.3em}{.5pt}{0ex} \kern-.3pt \Rule{.5pt}{.6ex}{0ex} \, {\tiny \texttt{#4}} } \\[-1ex] \def \N ##1#1 ##2 ##3 ##4 ##5 ##6 ##7 { ##3 \S ##4#2 #3##6 } \N 9 8 7 6 5 4 3 2 1 0 #2 % \t * #3#4 #3 } % \small \begin{array}{l} \texttt{\stars {23}} \\[-.5ex] \stars{23} \end{array} \endgroup$
This alternate approach performs $\small 10$-fold multiplication by approximating $\small \surd 5$ with a matrix and by treating cumulative stars as a vector $\small [ \, \texttt{#3 #4} \, ] \,$ that is almost always just $\small [ \, \texttt{#3 -} ~ ] \,$. The $\small ~ \texttt{#3#4 #3} ~$ in $\small \texttt{\N}$ economically serves as two different matrices when appended, as a whole or in part, to $\small \, \texttt{#3} \,$.
$$\small \begin{array}{lll} \texttt{#3} ~~~{\sf \&}~~~ \texttt{#3#4 #3} & \to ~~~ [ \, \texttt{#3#3#4 #3} \, ] & = ~~~ [ \, \texttt{#3 -} ~ ] ~ \displaystyle \bigg[ \, { 2 ~~ 1 \atop 1 ~~ 0 } \, \bigg] ~~~\sim ~~~ [ \, \texttt{#3 -} ~ ] \kern1mu \cdot \kern2mu \surd 5 \\[.5ex] \texttt{#3} ~~~{\sf \&}~~~ \texttt{#3} & \to ~~~ [ \, \texttt{#3#3 -} ~ ] & = ~~~ [ \, \texttt{#3 -} ~ ] ~ \displaystyle \bigg[ \, { 2 ~~ 0 \atop 0 ~~ 0 } \, \bigg] ~~~ = ~~~ [ \, \texttt{#3 -} ~ ] \kern1mu \cdot \kern2mu 2 \end{array}$$
The first matrix, derived from $\small ~ \texttt{#3#4 #3} \kern1mu$, is multiplied twice. Then the second, derived from $\small \, \texttt{#3} \,$.
$$ \small [ \, \texttt{#3 -} ~ ] \kern 1mu \cdot \kern 2mu ( \kern-2mu \surd 5 )^2 \kern-1mu \cdot \kern1mu 2 ~~~\sim ~~~ [ \, \texttt{#3 -} ~ ] ~ \bigg[ \, { 2 ~~ 1 \atop 1 ~~ 0 } \, \bigg] \raise2.5ex{\scriptsize 2} ~ \bigg[ \, { 2 ~~ 0 \atop 0 ~~ 0 } \, \bigg] ~~~ = ~~~ [ \, 10 \cdot \texttt{#3 -} ~ ] $$
Layout of this matrix-oriented alternative’s progression through $\small\texttt{\N}$:
. space after possible % = c nnn = 3 spaces after next digit
. 3 spaces after skip = fff | | ssssss = 6 spaces after skip
. space after digit = d | | | | aaaaaaa = 7 spaces after added stars
. | | | | | |
. | | | | | |
. _dfffc_nnn ssssss_________aaaaaaa zzzzzzz
. \N 9 8 . . . 2 1 0 #2 % \texttt * #3#4 #3 }
.
. Positive leading digit
. appends \texttt * to _dfffc_nnn ssssss_________aaaaaaa zzzzzzz
. cumulative stars in #3 1 0 #2 % \texttt * #3#4 #3 }
.
. Leading digit 0 causes
. halt when #2 contains _dfff_cnnn ssssssaaaaaaa zzzzzzz
. no further digits 0 % \texttt * #3#4 #3 }
.
. Leading digit 0 normally
. triggers multiplication _d ---> fffc___________nnnssssss________________aaaaaaazzzzzzz
. of #3 #4 by ~sqrt(5) 0 #2 % \texttt * #3#4 #3 }
.
.
. Leading digit \texttt triggers _______d fffcnnnssssss____________aaaaaaazzzzzzz
. multiplication by ~sqrt(5) \texttt * #3#4 #3 }
.
.
. Leading digit * triggers _dfffcnnn ssssss__aaaaaaazzzzzzz
. multiplication by 2 * #3#4 #3 }
Previous Solution, progress along the way
While this solution weighs in at 124 108 75 replacement tokens that include 8 7 6 $\small\texttt{\def} \,$ macros, one of which is dynamic, a heavy toll is exacted during execution, with macro overrun at 1000 decimal, 854 hexadecimal (2132 decimal) and 10000000000 binary (1024 decimal) stars.
. $$\require{begingroup}\begingroup
. %
. \def \stars #1{ \Throw #1 \Throw \Skip
. } % ^spaces^ (space at line break needed too)
. \def \Throw #1#2#3 #4#5
. { #4 #2#3 #4#5
. \StarDigit#1}
. % ^no^spaces (line break needed)
. %
. \def \Skip #1
. { }
. \def \StarDigit #1#2 { % e.g, \StarDigit 7*****[space] --> 57 stars
. \DoN #1 {\texttt* \Skip }
. \DoN A { #2 \Skip}
. } % ^space (also A = 10)
. \def \DoN #1#2{ % e.g, \DoN 3 {\text{Do me.}\Skip}
. \def \N ##1#1{}
. \N A #2 9
. #2 8
. #2 7
. #2 6
. #2 5
. #2 4
. #2 3
. #2 2
. #2 1
. #2 0 }
. \stars{57}
. \endgroup$$
Three features of this solution remain original, though not necessarily novel.
Use of a general-purpose repeater macro, $\small\texttt{\DoN}$, that can produce a variable number of stars and can multiply by 10 a recursive section of star-producing code.
The calls $~\small\texttt{\DoN}\,\small\texttt{#1}\,\small\texttt{{\texttt* \Skip}}~$ and $~\small\texttt{\DoN}\,\small\texttt{A}\,\small\texttt{{#2 \Skip}}~$ include incomplete calls to $\small\texttt{\Skip}$, declared as having a parameter, so that the line in $\small\texttt{\DoN}$: $$\small\texttt{ \N A #2 9 #2 8 ... 3 #2 2 #2 1 #2 0 }$$ effectively becomes, but with 8 fewer source-code tokens: $$\small \texttt{ \N A #2 \Skip 9 #2 \Skip 8 ... 3 #2 \Skip 2 #2 \Skip 1 #2 \Skip 0 }$$ (Do not attempt to breach code levels like this outside of a controlled puzzling zone.)
Reversal of digit order allows Horner’s Method, conjured and explained well in Davide Cervone’s answer, to be applied without storing intermediate results. Multiplication here means repetition. $$\small \begin{align} 257 ~ \to ~ & \texttt {\StarDigit7} \, \texttt {\StarDigit5} \, \texttt{\StarDigit2} \\[9mu] = ~ & \texttt {\StarDigit7} + 10 \, ( \kern2mu \texttt {\StarDigit5} \, \texttt{\StarDigit2} \, ) \\[9mu] = ~ & \texttt {\StarDigit7} + 10 \, ( \kern2mu \texttt {\StarDigit5} + 10 \cdot \texttt{\StarDigit2} \, ) \\[9mu] = ~ & \texttt {*******} + 10 \, ( \texttt {*****} + 10 \cdot \texttt{**} ) \\[9mu] = ~ & 100 \cdot \texttt {**} + 10 \cdot \texttt {*****} + \texttt{*******} \end{align} $$
Initial solution, binary stars with overlapping templates
$$\require{begingroup}\begingroup % \def \0 #1\starrise#2\eternity{ #1\starrise\0#2\eternity } \def \Zer #10#2#3\Zer#4#5#6#7\eternity{ #1#6#4#2#3\Zer#4#5#6#7\eternity } \def \1 #1\starrise#2\eternity{ #1\starrise\1#2\eternity } \def \One #11#2#3\One#4#5#6#7\eternity{ #1#6#4#2#3\One#4#5#6#7\eternity } \def \stars #1{ \Zer \One #1 \. 0\Zer\Zer\ZerX \0\_ 1\One\One\OneX \1\_ \starrise \_ \eternity } \def \ZerX { \def\Zer{} \def\0{} } \def \OneX { \def\One{} \def\1{} } \def \ZerStars #1\_{#1\_#1\_} \def \OneStars #1\_{\texttt*#1\_#1\_} % \def \starrise { \let\0=\ZerStars \let\1=\OneStars } \def \eternity {} \def \_ {} \def \. {} \stars{111001} \endgroup$$
These stars are produced by $\small\texttt{\stars{111001}}$. An equivalent decimal version was presented too, but it was just plain unwieldy and is best forgotten. This binary version weighed in at around 180 replacement tokens.
$$\require{begingroup}\begingroup
%
\def \0 #1\starrise#2\eternity{
#1\starrise\0#2\eternity
}
\def \Zer #10#2#3\Zer#4#5#6#7\eternity{
#1#6#4#2#3\Zer#4#5#6#7\eternity
}
\def \1 #1\starrise#2\eternity{
#1\starrise\1#2\eternity
}
\def \One #11#2#3\One#4#5#6#7\eternity{
#1#6#4#2#3\One#4#5#6#7\eternity
}
\def \stars #1{ \Zer
\One
#1 \.
0\Zer\Zer\ZerX \0\_
1\One\One\OneX \1\_
\starrise
\_
\eternity
}
\def \ZerX { \def\Zer{} \def\0{} }
\def \OneX { \def\One{} \def\1{} }
\def \ZerStars #1\_{#1\_#1\_}
\def \OneStars #1\_{\texttt*#1\_#1\_}
%
\def \starrise { \let\0=\ZerStars
\let\1=\OneStars
}
\def \eternity {}
\def \_ {}
\def \. {}
\stars{111001}
\endgroup$$
The underlying mechanism takes advantage of how MathJax easily parses overlapping templates.
LINE \Zer \One ... 0 1 ... \. 0 \Zer \Zer \ZerX .. 1 \One \One \OneX
early
0 template \Zer #1 0 #2 #3 \Zer #4
early
1 template \One #1 1 #2 #3 \One #4
last
1 template \One #1 1 #2 #3 \One #4
But the overlapped parsing had to be worked around in order to get the resultant digits to be evaluated in their correct order. In what amounts to an additional two passes, each parsed digit moves itself to the end before actually being evaluated.
LINE after parsing \1 \1 \0 \1 ...
1st
order of parsing 2nd 3rd 4th
desired order of evaluation 4th 3rd 2nd 1st
..........................
: :
"second" pass V
\1 \1 \0 \1 ... \starrise
\1 \0 \1 ... \starrise \1
\0 \1 ... \starrise \1 \1
\1 ... \starrise \0 \1 \1
... \starrise \1 \0 \1 \1
No comments:
Post a Comment