マクロツイーター

はてダから移行した記事の表示が崩れてますが、そのうちに直せればいいのに(えっ)

そもそも TeX 限定の競技プログラミング大会があるべきだ

という無茶な願望は放っておいて。

まずはそもそも解くことができるかについて.問題はAtCoder Regular Contest #005のA,B,C

あれぇ〜? Dは〜?

待っていても来なさそうなので、仕方が無いので、作ってみた。

(問題)

%% arc005_4.tex
\catcode`\@=11
%---------------------------------------
%(Constants)
\chardef\ET@ten=10
\mathchardef\ET@HUGE=10000
\newcount\ET@SLIMIT \ET@SLIMIT=100000000
%(Variables)
\newcount\ET@gm \ET@gm\z@
\newcount\ET@j         %(j)
\newcount\ET@k         %(k)
\newcount\ET@kk        % another k
\newcount\ET@m         %(m)
\newcount\ET@r         % ret-value
\newcount\ET@tl        % t lowerpart
\newcount\ET@tli       % tl saved
\newcount\ET@tu        % t upperpart
\newcount\ET@tui       % tu saved
\newcount\ET@u         % temp
%(Quasivariables)
\chardef\ET@ccost\z@   %(ccost)
\chardef\ET@clast\z@   %(clast)
\chardef\ET@d\z@       %(d)
\chardef\ET@dmax\z@    %(dmax)
\chardef\ET@lastk\z@   %(lastk)
\chardef\ET@lastm\z@   %(lastm)
\chardef\ET@xcost\z@   %(xcost)
%(Switches)
\newif\ifET@error
\newif\ifET@dserror
%(Token-lists)
\let\ET@za\empty       % temp
\let\ET@zb\empty       % temp
\let\ET@set\empty      %(set)
\let\ET@dsetl\empty    %(dset)
\let\ET@expr\empty     %(expr)
%%(Arrays)
\def\ET@cscst#1#2{\expandafter\mathchardef
  \csname E!#1\endcsname=#2\relax}
%\E!d/*                 (dvalid)
%\E!cc/*                (ccol)
\ET@cscst{cc/0}\z@
%\E!cl/*                (cslast)
%\E!mm/*                (mmax)
\ET@cscst{mm/0}\z@
%\E!an/*                (answer)
%\E!num/*               (num)
%---------------------------------------
\def\ET@cs#1{\csname E!#1\endcsname}
\def\ET@csdef#1{\expandafter\def\csname E!#1\endcsname}
\def\ET@csedef#1{\expandafter\edef\csname E!#1\endcsname}
\def\ET@cslet#1#2{\expandafter\let\csname E!#1\endcsname=#2}
\def\ET@letcs#1#2{\expandafter\let\expandafter#1\csname
  E!#2\endcsname}
\def\ET@iscsdef#1{\expandafter\ifx\csname E!#1\endcsname\relax
  \z@\else\@ne\fi}
\def\ET@end{\noexpand\ET@end@}
%\def\ET@debug#1{\immediate\write16{#1}}
%\def\ET@debugp#1{\message{#1}\read\m@ne to\ET@zz}
%\newlinechar=10
%---------------------------------------
%% \ET@do@residue:  t := residue(t, m)
\def\ET@do@residue{%
  \advance\ET@tl-\ET@m
  \divide\ET@tl\ET@ten
  \ifnum\ET@tu>\z@
    \ET@let@remainder\ET@r\ET@tu
    \divide\ET@tu\ET@ten
    \multiply\ET@r\ET@SLIMIT
    \advance\ET@tl\ET@r
  \fi
  \ifnum\ET@tl<\z@
    \advance\ET@tu\m@ne
    \advance\ET@tl\ET@SLIMIT
  \fi
}
%% \ET@do@tail: r := tail(t)
\def\ET@do@tail{%
  \ET@let@remainder\ET@r\ET@tl
}
%% \ET@do@to@value: r := to_value(t)
\def\ET@do@to@value{%
  \ifnum\ET@tu>\z@ \ET@r\ET@HUGE
  \else \ET@r\ET@tl
  \fi
}
%% \ET@let@remainder\X\Y: \Y := \X mod 10
\def\ET@let@remainder#1#2{%
  #1#2\divide#1\ET@ten
  \multiply#1-\ET@ten\advance#1#2%
}
%% \ET@do@to@internal{<num>}: t := to_internal(num)
\def\ET@do@to@internal#1{%
  \let\ET@za\empty
  \ET@do@to@internal@a#1\ET@end
}
\def\ET@do@to@internal@a#1{%
  \ifx#1\ET@end
    \ifx\ET@za\empty \let\ET@next\ET@errortrue
    \else \let\ET@next\ET@do@to@internal@c
    \fi
  \else\ifnum2<1\noexpand#1\relax
    \ifnum\ifx\ET@za\empty0\else1\fi#1>\z@
      \edef\ET@za{#1\ET@za}%
    \fi
    \let\ET@next\ET@do@to@internal@a
  \else
    \let\ET@next\ET@do@to@internal@b
  \fi\fi \ET@next
}
\def\ET@do@to@internal@b#1\ET@end{%
  \ET@errortrue
}
\def\ET@do@to@internal@c{%
  \expandafter\ET@do@to@internal@d\ET@za000000000000000000\ET@end
}
\def\ET@do@to@internal@d#1#2#3#4#5#6#7#8#9{%
  \ET@tl=#9#8#7#6#5#4#3#2#1\relax
  \ET@do@to@internal@e
}
\def\ET@do@to@internal@e#1#2#3#4#5#6#7#8#9{%
  \ET@tu=#9#8#7#6#5#4#3#2#1\relax
  \ET@do@to@internal@f
}
\def\ET@do@to@internal@f#1\ET@end{}
%% \ET@the@t: t stringified
\def\ET@the@t{\the\ET@tu:\the\ET@tl}
%% \ET@the@zero: zero stringified in same way as \ET@the@t
\def\ET@the@zero{0:0}
%---------------------------------------
%% \ET@get@cool@seq{<k>}: get_ccol_seq(k)
%* updates: \ET@gm, \E!cc/*, \E!cl/*, \E!mm/*
\def\ET@get@ccol@seq#1{%
  \ET@u#1\relax \advance\ET@u\m@ne
  \chardef\ET@cki\ET@u %== k-1
  \let\ET@next\ET@get@ccol@seq@a
  \ET@next\ET@get@ccol@seq@b
}
\def\ET@get@ccol@seq@a{%
  \global\advance\ET@gm\@ne
  \ET@get@ccol
  \global\ET@cscst{cc/\the\ET@gm}\ET@ccost
  \global\ET@cscst{cl/\the\ET@gm}\ET@clast
  \global\ET@cscst{mm/\the\ET@ccost}\ET@gm
  \ET@get@ccol@seq@b
}
\def\ET@get@ccol@seq@b{%
  \ET@letcs\ET@za{mm/\the\ET@cki}%
  \ifx\ET@za\relax\else
    \ET@u\ET@za \advance\ET@u\ET@dmax
    \ifnum\ET@gm<\ET@u\else
      \let\ET@next\relax
    \fi
  \fi \ET@next
}
%% \ET@get@ccol: get_ccol(m)
%r updates: \ET@ccost, \ET@clast
\def\ET@get@ccol{%
  \mathchardef\ET@ccost\ET@HUGE
  \chardef\ET@clast\z@
  \let\do\ET@get@ccol@a
  \ET@digits
}
\def\ET@get@ccol@a#1{%
  \chardef\ET@za#1\relax %==d
  \ifnum\ET@gm<\ET@za\else
    \ET@u\ET@gm \advance\ET@u-\ET@za
    \ET@u\ET@cs{cc/\the\ET@u}\advance\ET@u\@ne
    \ifnum\ET@u<\ET@ccost
      \mathchardef\ET@ccost\ET@u
      \chardef\ET@clast\ET@za
    \fi
  \fi
}
%---------------------------------------
%% \ET@prepare@answer{<k>}: prepare_answer(k)
% updates: \E!an/*/*
\def\ET@prepare@answer#1{%
  \ET@k=#1\relax
  \ET@j\m@ne \loop \ifnum\ET@j<\ET@k
    \advance\ET@j\@ne
    \ifnum\ET@iscsdef{an/\the\ET@j/\ET@the@zero}=\z@
      \global\ET@csdef{an/\the\ET@j/\ET@the@zero}{{0}{0}{0}}%
    \fi
  \repeat
}
%% \ET@solve@core: solve_core(t, k)
% updates: \ET@xcost, \ET@lastk, \ET@lastm, \E!an/*/*
\def\ET@solve@core{%
%\ET@debug{CALL:\the\ET@k/\ET@the@t}%
  \def\ET@zb{an/\the\ET@k/\ET@the@t}%
  \ET@letcs\ET@answer\ET@zb
  \ifx\ET@answer\relax
%\ET@debug{ENTER}%
    \begingroup
      \mathchardef\ET@xcost\ET@HUGE
      \chardef\ET@lastk\z@
      \chardef\ET@lastm\z@
      \ET@do@tail \chardef\ET@d\ET@r
      \chardef\ET@mmax\ET@cs{mm/\the\ET@k}%
      \ET@do@to@value
      \ifnum \ET@r<\ET@mmax \chardef\ET@mmax\ET@r \fi
      \chardef\ET@kmax\ET@k
      \ET@tui\ET@tu \ET@tli\ET@tl
      \ET@m\ET@d
      \ET@solve@core@a
      %\ET@k\ET@kmax
      \xdef\ET@g@next{%
        \edef\noexpand\ET@answer
         {{\the\ET@xcost}{\the\ET@lastk}{\the\ET@lastm}}%
      }%
    \endgroup
    \ET@g@next
    \global\ET@cslet\ET@zb\ET@answer
  \fi
%\ET@debug{RETURN:\ET@zb->\ET@answer}%
}
\def\ET@solve@core@a{%
  \ifnum\ET@m>\ET@mmax\else
    \ET@k\ET@cs{cc/\the\ET@m}%
    \ET@solve@core@b
    \advance\ET@m\ET@ten
    \expandafter\ET@solve@core@a
  \fi
}
\def\ET@solve@core@b{%
  \ifnum\ET@k>\ET@kmax\else
%\ET@debug{<\the\ET@m/\the\ET@k>}%
    \ET@do@residue
    \ET@solve@core
    \expandafter\ET@solve@core@c\ET@answer
    \ET@tu\ET@tui \ET@tl\ET@tli
    \ET@u\ET@xcosti \advance\ET@u\ET@k
    \ifnum\ET@u<\ET@xcost
      \mathchardef\ET@xcost\ET@u
      \chardef\ET@lastk\ET@k
      \chardef\ET@lastm\ET@m
    \fi
    \advance\ET@k\@ne
    \expandafter\ET@solve@core@b
  \fi
}
\def\ET@solve@core@c#1#2#3{%
  \mathchardef\ET@xcosti#1\relax
}
%---------------------------------------
%% \ET@solve@main{<t>}: solve_main(t)
% updates: \ET@xcost, \ET@lastk, \ET@lastm, (\ET@expr)
\def\ET@solve@main#1{%
  \def\ET@expr{ERROR!}%
  \ifET@dserror\else
    \ET@errorfalse
    \edef\ET@next{\noexpand\ET@do@to@internal{#1}}%
    \ET@next
    \ifET@error\else
      \ET@kk\z@
      \mathchardef\ET@xcost\ET@HUGE
      \chardef\ET@lastk\z@
      \mathchardef\ET@lastm\z@
      \ET@solve@main@a
      \ET@k\ET@lastk
      \ET@get@expr
    \fi
  \fi
}
\def\ET@solve@main@a{%
  \advance\ET@kk\@ne
  \ET@u\ET@kk \multiply\ET@u\tw@
  \ifnum\ET@u<\ET@xcost
    \ET@get@ccol@seq\ET@kk
    \ET@prepare@answer\ET@kk
    \ET@k\ET@kk
    \ET@solve@core
    \expandafter\ET@solve@main@c\ET@answer
    \ET@u\ET@xcosti
    \ifnum\ET@kk>\@ne \advance\ET@u\ET@kk \fi
%\ET@debug{[\the\ET@kk]->\the\ET@u/\the\ET@lastki/\the\ET@lastmi}%
    \ifnum\ET@u<\ET@xcost
      \mathchardef\ET@xcost\ET@u
      \chardef\ET@lastk\ET@lastki
      \mathchardef\ET@lastm\ET@lastmi
    \fi
    \expandafter\ET@solve@main@a
  \fi
}
\def\ET@solve@main@c#1#2#3{%
  \mathchardef\ET@xcosti#1\relax
  \chardef\ET@lastki#2\relax
  \mathchardef\ET@lastmi#3\relax
}
%---------------------------------------
%% \ET@get@dset{<m>}: get_dset(m)
% updates: \ET@set
\def\ET@get@dset#1{%
  \ET@u#1\relax
  \let\ET@set\empty
  \ET@get@dset@a
}
\def\ET@get@dset@a{%
  \ifnum\ET@u>\z@
    \chardef\ET@d\ET@cs{cl/\the\ET@u}%
    \advance\ET@u-\ET@d
    \edef\ET@set{\do{\the\ET@d}\ET@set}%
    \expandafter\ET@get@dset@a
  \fi
}
%% \ET@get@expr: get_expr(t, k)
% updates: \ET@expr
\def\ET@get@expr{%
  \let\do\relax \let\ET@cdo\relax
  \global\let\ET@dsetl\empty
  \begingroup
    \ET@get@expr@a
  \endgroup
  \begingroup
    \let\do\ET@get@expr@e
    \let\ET@cdo\ET@get@expr@c
    \ET@dsetl
    \ET@j\z@ \let\ET@expr\empty
    \ET@get@expr@f
    \xdef\ET@g@next{\def\noexpand\ET@expr{\ET@expr}}%
  \endgroup
  \global\let\ET@dsetl\empty
  \ET@g@next
}
\def\ET@get@expr@a{%
  \edef\ET@za{\ET@the@t}%
  \ifx\ET@za\ET@the@zero\else
    \ET@letcs\ET@answer{an/\the\ET@k/\ET@the@t}%
    \expandafter\ET@get@expr@b\ET@answer
    \ET@get@dset\ET@m
    \xdef\ET@dsetl{\ET@cdo{\ET@set}\ET@dsetl}%
    \ET@do@residue
    \expandafter\ET@get@expr@a
  \fi
}
\def\ET@get@expr@b#1#2#3{%
  \chardef\ET@k#2\relax
  \mathchardef\ET@m#3\relax
}
\def\ET@get@expr@c#1{%
  \ET@j\z@
  #1%
  \ET@get@expr@d
}
\def\ET@get@expr@d{%
  \ifnum\ET@j<\ET@k
    \advance\ET@j\@ne
    \ET@letcs\ET@za{num/\the\ET@j}%
    \ifx\ET@za\relax\else
      \ET@csedef{num/\the\ET@j}{\ET@za0}%
    \fi
    \expandafter\ET@get@expr@d
  \fi
}
\def\ET@get@expr@e#1{%
  \advance\ET@j\@ne
  \ET@letcs\ET@za{num/\the\ET@j}%
  \ifx\ET@za\relax \let\ET@za\empty \fi
  \ET@csedef{num/\the\ET@j}{\ET@za#1}%
}
\def\ET@get@expr@f{%
  \ifnum\ET@j<\ET@k
    \advance\ET@j\@ne
    \edef\ET@za{\ifnum\ET@j<\ET@k +\else\ifnum\ET@k>\@ne =\fi\fi}%
    \edef\ET@expr{\ET@expr\ET@cs{num/\the\ET@j}\ET@za}%
    \expandafter\ET@get@expr@f
  \fi
}
%---------------------------------------
%% \ET@read@set{<digit-seq>}: read_set(s)
% updates: \E!d/*, \ET@digits, \ET@dmax
\def\ET@read@set#1{%
  \global\ET@dserrorfalse
  \edef\ET@za{#1}%
  \expandafter\ET@read@set@a\ET@za\ET@end
  \global\let\ET@read@set\ET@read@set@inv
}
\def\ET@read@set@a#1{%
  \ifx#1\ET@end
    \let\ET@next\ET@read@set@c
  \else\ifnum2<1\noexpand#1\relax
    \global\ET@cslet{d/#1}t%
    \let\ET@next\ET@read@set@a
  \else
    \let\ET@next\ET@read@set@b
  \fi\fi \ET@next
}
\def\ET@read@set@b#1\ET@end{%
  \global\ET@dserrortrue
}
\def\ET@read@set@c{%
  \global\ET@cslet{d/1}t%
  \let\do\relax
  \global\let\ET@digits\empty
  \ET@j\@ne \loop
    \ifnum\ET@iscsdef{d/\the\ET@j}=\@ne
      \xdef\ET@digits{\ET@digits\do\the\ET@j}%
      \global\chardef\ET@dmax\ET@j
    \fi
    \advance\ET@j\@ne
  \ifnum\ET@j<\ET@ten \repeat
}
\def\ET@read@set@inv#1{%
  \errmessage{Digit set cannot be altered}%
}
%---------------------------------------
\def\Main{%
  \begingroup
    \endlinechar\m@ne
    \read\m@ne to\ET@za
    \expandafter\ET@read@set\expandafter{\ET@za}%
    \read\m@ne to\ET@tnum
    \ET@solve@main\ET@tnum
    \immediate\write16{\ET@expr}%
  \endgroup
}
%---------------------------------------
\catcode`\@=12
\immediate\write16{--------}%===========
\Main
\immediate\write16{--------}%===========
\bye

入力例 4。(input4.txt)

019
2727

これを標準入力から読み込んでソースを実行すると以下の出力を得る。(見易くするために区切り線を出力させている。*1

C>tex arc005_4.tex < input4.txt
This is TeX, Version 3.1415926 (TeX Live 2012/W32TeX)
 encTeX v. Jun. 2004, reencoding enabled.
(./arc005_4.tex
--------
909+909+909=
--------
 )
No pages of output.
Transcript written on arc005_4.log.

入力例 5。(input5.txt)

01457
245723852196245230

実行すると次のようになる。

C>tex arc005_4.tex < input5.txt
This is TeX, Version 3.1415926 (TeX Live 2012/W32TeX)
 encTeX v. Jun. 2004, reencoding enabled.
(./arc005_4.tex
--------
175711751155145110+70011701041100110+400000000010=
--------
 )
No pages of output.
Transcript written on arc005_4.log.

*1:標準出力を「答え」だけにするのは原理的に無理なので、TeX の使用を前提としたジャッジでは何らかの規定を敷く必要がある。