Skip to content

Instantly share code, notes, and snippets.

@doraTeX
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save doraTeX/8968650 to your computer and use it in GitHub Desktop.
Save doraTeX/8968650 to your computer and use it in GitHub Desktop.
結城浩さんの CodeIQ の アルゴリズム問題「ジェムストリング問題」( https://codeiq.jp/ace/yuki_hiroshi/q684 )をTeX言語(TeX on LaTeX)で解きました。TeX Liveなどで pdflatex gemstring とすればコンパイルできます。
%! pdflatex gemstring
\documentclass{article}
\usepackage[nomessages]{fp}
\usepackage{pgffor}
\usepackage{xstring}
\usepackage{ifthen}
\makeatletter
\newif\ifdebugmode
\def\shiftarray#1{%
\@shiftarray#1,\relax
}
\def\@shiftarray#1,#2\relax{%
\def\@shiftarray@temp{#2}%
\ifx\@shiftarray@temp\@empty
\def\result{}%
\else
\removelastcomma{#2}%
\fi
}
\def\removelastcomma#1{%
\@removelastcomma#1\relax
}
\def\@removelastcomma#1,\relax{%
\def\result{#1}%
}
\def\firstcount#1{%
\expandafter\@firstcount#1\relax
}
\def\@firstcount#1/#2#3\relax{%
\def\result{#2}%
}
\def\decarray#1#2{%
\foreach \char/\num in {#1}{%
\expandafter\xdef\csname gem\char\endcsname{\num}%
}%
\@decarray#2\relax
\def\result{}%
\foreach \char/\num in {#1}{%
\xdef\result{\result,\char/\csname gem\char\endcsname}%
}%
\expandafter\shiftarray\expandafter{\result}%
\edef\result{\result}%
}
\def\@decarray#1{%
\ifx#1\relax
\let\@decarraynext\relax
\else
\let\@decarraynext\@decarray
\FPeval\@result{trunc(\csname gem#1\endcsname - 1:0)}%
\expandafter\xdef\csname gem#1\endcsname{\@result}%
\fi
\@decarraynext
}
\def\factorial#1{%
\def\result{1}%
\@gobble\if\FPifeq{#1}{0}%
\def\result{1}%
\else
\@gobble\if\FPifeq{#1}{1}%
\def\result{1}%
\else
\foreach \i in {1,2,...,#1}{%
\FPeval\@result{trunc(\result*\i:0)}%
\xdef\result{\@result}%
}%
\fi
\fi
}
\def\countstring#1{%
\def\sumresult{0}%
\@countstring{#1}{}%
}
\def\@countstring#1#2{%
\def\@temp{#1}%
\ifx\@temp\@empty
\shiftarray{#2}%
\def\@sumresult{0}%
\edef\ary{\result}%
\foreach \i in \ary{%
\FPeval\@sumresult{trunc(\@sumresult + \i:0)}%
\xdef\@sumresult{\@sumresult}%
}%
\factorial{\@sumresult}%
\edef\@factresult{\result}%
\def\@prodresult{1}%
\foreach \i in \ary{%
\factorial{\i}%
\FPeval\@prodresult{trunc(\@prodresult*\result:0)}%
\xdef\@prodresult{\@prodresult}%
}%
\FPeval\sumresult{trunc(\sumresult + \@factresult / \@prodresult:0)}%
\xdef\sumresult{\sumresult}%
\else
\firstcount{#1}%
\edef\@@temp{\result}%
\shiftarray{#1}%
\edef\@nextary{\result}%
\foreach \i in {0,...,\@@temp}{%
\edef\@@@temp{#2,\i}%
\expandafter\expandafter\expandafter\@countstring
\expandafter\expandafter\expandafter{%
\expandafter\@nextary\expandafter}\expandafter{\@@@temp}%
}%
\fi
}
\newcount\position
\newcount\charnum
\def\search#1#2{%
\def\searchresult{0}%
\StrLen{#2}[\strlen]%
\position=0\relax
\whiledo{\position<\strlen}{%
\advance\position by 1\relax
\StrChar{#2}{\position}[\charAt]%
\if\charAt a\def\charNum{1}\fi
\if\charAt b\def\charNum{2}\fi
\if\charAt c\def\charNum{3}\fi
\if\charAt d\def\charNum{4}\fi
\if\charAt e\def\charNum{5}\fi
\if\charAt f\def\charNum{6}\fi
\if\charAt g\def\charNum{7}\fi
\charnum=1\relax
\whiledo{\charnum<\charNum}{%
\@tempcntb=\the\position\relax
\advance\@tempcntb by -1\relax
\StrLeft{#2}{\the\@tempcntb}[\strleft]%
\def\@temp{#1}%
\expandafter\expandafter\expandafter\decarray
\expandafter\expandafter\expandafter{%
\expandafter\@temp\expandafter}\expandafter{\strleft}%
\edef\@counttarget{\result}%
\gdef\sumflag{T}%
\def\next@ary{}%
\foreach \char/\num in \@counttarget{%
\ifnum\charnum=1\relax\gdef\thechar{a}\fi
\ifnum\charnum=2\relax\gdef\thechar{b}\fi
\ifnum\charnum=3\relax\gdef\thechar{c}\fi
\ifnum\charnum=4\relax\gdef\thechar{d}\fi
\ifnum\charnum=5\relax\gdef\thechar{e}\fi
\ifnum\charnum=6\relax\gdef\thechar{f}\fi
\ifnum\charnum=7\relax\gdef\thechar{g}\fi
\if\thechar\char
\@tempcnta=\num\relax
\ifnum\@tempcnta=0\relax
\gdef\sumflag{F}%
\else
\advance\@tempcnta by -1\relax
\edef\num{\the\@tempcnta}%
\fi
\fi
\xdef\next@ary{\next@ary,\char/\num}%
}%
\expandafter\shiftarray\expandafter{\next@ary}%
\edef\next@ary{\result}%
\if\sumflag T%
\expandafter\countstring\expandafter{\next@ary}%
\FPeval\searchresult{trunc(\sumresult+\searchresult:0)}%
\ifdebugmode
\typeout{\strleft\thechar\space + [\next@ary] => \sumresult}%
\fi
\fi
\advance\charnum by 1\relax
}%
\ifdebugmode
\StrLeft{#2}{\position}[\@strleft]%
\typeout{\@strleft\space => 1}%
\fi
\FPeval\searchresult{trunc(\searchresult+1:0)}%
}%
\typeout{Index of "#2" in [#1] => \searchresult}%
\searchresult
}
\makeatother
\begin{document}
\debugmodetrue
\search{a/1,b/4,c/1,d/4,e/2,f/1,g/3}{eagcdfbe} % => 5578864439
\end{document}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment