貧乏人のラテックス


37

あなたは人々がASCIIアートとしてコンピューター上で数学の方程式を手で書く平行宇宙に運ばれます。LaTeXの常習者として、これはまったく受け入れられません。このプロセスを多少自動化する必要があります。

あなたの目標は、LaTeX数学コマンドとして入力された方程式のASCIIバージョンを出力するプログラムを書くことです。

サポートする必須のLaTeXコマンド

  • 合計:合計のLaTeXコマンドは \sum_{lower bound}^{upper bound}

    合計に使用する必要があるASCII数字は次のとおりです。

    upper bound
        ___ 
        \  `
        /__,
    lower bound
    
  • 製品:製品のLaTeXコマンドは \prod_{lower bound}^{upper bound}

    製品に使用しなければならないASCII図は次のとおりです。

    upper bound
        ____
        |  |
        |  |
    lower bound
    
  • 分数:分数のLaTeXコマンドは \frac{numerator}{denominator}

    分数に使用しなければならないASCII図は次のとおりです。

     numerator
    -----------
    denominator
    

これらの3つのコマンドのいずれでもないものはすべてそのまま表示されます。例えば、\sum{i=3}^{e^10}\frac{3x+5}{2}のように表示されなければなりません

e^10
___  3x+5
\  ` ----
/__,  2
i=3

入力

入力は、文字列として渡されるLaTeXコマンドです(または言語の文字列に相当するもの)。LaTeXコマンドはネストでき\frac{\frac{1}{2}}{3}ます。たとえば、有効な入力です。入力は常に正しいはずです(コード内でLaTeXの構文をチェックする必要はありません)。入力は、上記の3つのLaTeXコマンドと、フォーマットする必要のない「テキスト」のみで構成されます。

LaTeXコマンドは常に上記の構文を使用します。つまり、合計と積には常に上限と下限がありますが(空でもかまいません)、分数には分子と分母が常にあります。

合計と製品の境界は最大で4文字(=合計と製品シンボルの幅)であると想定しているため、重複の問題を心配する必要はありません。同様の理由で、境界は単なる「テキスト」であり、LaTeXコマンドになること\sum_{\sum_{1}^{2}}^{1}はない、たとえば有効な入力ではないと仮定します。

出力

プログラムの出力は、入力として与えられたLaTeXコマンドのASCII表現です。

プログラムでは、水平方向の配置を考慮する必要があります。たとえば、合計または製品の境界は、合計または製品シンボル(両方とも4文字幅)と水平方向に配置する必要があります。境界の文字数が奇数である場合、中央から1文字右または左のどちらの文字でも問題ありません。分数の行は、分子または分母のどちらか長い方と同じ長さでなければなりません。

プログラムでは、垂直方向の配置を考慮する\frac{\frac{1}{2}}{3} = \frac{1}{6}必要があります。たとえば、次のように表示する必要があります

1
-
2   1
- = -
3   6

合計と積の場合、シンボルの高さは4文字であるため、垂直方向の中心は上から2番目の行であると想定されます。

水平方向の間隔は、指定された入力で正しいと想定されます。つまり、入力のスペースが出力に表示される必要があります。

テストケース

  • 入力 abc = 2

    出力 abc = 2

  • 入力 e = \sum_{n=0}^{+inf} \frac{1}{n!}

    出力

        +inf
        ___  1
    e = \  ` --
        /__, n!
        n=0
    
  • 入力 e^x = 1 + \frac{x}{1 - \frac{x}{2 + x - ...}}

    出力

                     x
    e^x = 1 + ---------------
                       x
              1 - -----------
                  2 + x - ...
    
  • 入力 \prod_{i=1}^{n} \frac{\sum_{j=0}^{m} 2j}{i + 1}

    出力

           m
          ___
          \  ` 2j
     n    /__,
    ____  j=0
    |  |  -------
    |  |   i + 1
    i=1
    
  • 入力 \frac{sum}{prod} = \sum_{frac}^{prod} sum

    出力

           prod
    sum    ___
    ---- = \  ` sum
    prod   /__,
           frac
    

得点

これはなので、最短のコードが優先されます。


11
素敵な最初の挑戦。かなり難しいようです。私はいくつかの解決策を見ることに興奮しています。
アレックスA.

1
@Alex A.私はもともと積分、平方根、展開可能な括弧も持つことを意図していましたが、それは少し多すぎるように見えました
...-Fatalize

2
重複する場合があると思います。たとえば、用語が4を超える合計(複数の分数、合計の小数など)があり、合計の上限/下限が長い場合、上限/下限文字列が用語と重複する可能性があります。それはどのように解決されますか?境界との重複を避けるために、用語は合計から間隔を空ける必要がありますか?
レトコラディ


8
誰かがLaTeXで解決策を思いつくことを本当に願っています
-shadowtalker

回答:


23

Python 2、 656 627 618バイト

M=max
O=lambda l,o=2:[(p+o,c)for p,c in l]
def C(s,m=0):
 if''<s<'}'[m:]:f,w,h,d,s=C(s,1);F,W,H,D,s=C(s);e=M(d,D);return[O(f,e-d)+O(F,w*1j+e-D),w+W,M(h-d,H-D)+e,e,s]
 if'\\'!=s[:1]:return[[(0,s[:1])]*m,m,m,0,s[1:]]
 t=s[1]<'s';e=s[1]>'f';f,w,h,d,s=C(s[5+t+e:]);F,W,H,D,s=C(s[1+e:]);g=M(w,W);G=C('-'*g)[0]
 if e:f,w,h,F,W,H=F,W,H,f,w,h;g=4;p=C('|  |')[0];G=C('_'*(3+t))[0]+[O(C('/__,')[0])+[(1,'\\'),(1+3j,'`')],O(p,1)+O(p)][t]
 x=M(w,W,g);return[O(f,(x-w)/2*1j)+O(F,(x-W)/2*1j+h+3**e)+O(G,(x-g)/2*1j+h),x,h+3**e+H,h+e,s]
f,w,h,d,s=C(raw_input())
for y in range(h):print"".join(dict(f).get(y+x*1j,' ')for x in range(w))

STDINで入力を受け取り、出力をSTDOUTに書き込みます。

プログラムは、よりその他の制御シーケンスを負いません\frac\sumまたは\prod(すなわち、それは、通常のテキストとして表示されません)、その入力に現れる~(それは同様に表示されない数式モードで特別な意味を持っているではとにかく。)一方、プログラムがないの制限などの任意の式をサポート\sumしてを\prod

説明

TeXと同じように機能します!(まあ、並べ替え...)各サブ数式(単一の文字から始まり、より複雑な数式を作成する)は、幅、高さ、深さ(ベースライン)が関連付けられたボックスに変わります。より単純な数式のボックスは、より大きなボックスに結合されて複雑な数式を形成します。各ボックスの内容は、ボックスの左上隅を基準とした位置/文字のペアのリストとして表されます。ボックスを大きなボックスに結合すると、大きなボックス内の小さなボックスの相対位置に応じて位置がオフセットされ、リストが連結されます。

最終的には、印刷可能なフォームに変換される最上位のボックスになります。


少しスパイスを加えるために、次のバージョンでは平方根もサポートしています。

例:

  • \frac{-b +- \sqrt{b^2 - 4ac}}{2a}

            _________
    -b +- \/b^2 - 4ac
    -----------------
           2a
    
  • |v| = \sqrt{ \sum_{i}^{} v[i]^2 }

               _____________
              / ___
    |v| =    /  \  ` v[i]^2
            /   /__,
          \/     i
    

9
私は完全に感銘を受けたと言わざるを得ません!実行しようとしましたが\prod_{i=1}^{\sum_{azededzeda}^{k}} \frac{\sum_{j=0}^{m} 2j}{i + 1}、必要ではありませんでしたが、重複することなくすべてを正しく出力しました。いいね!
致命的

4
そして、あなたは〜18%以上のバイトで平方根をサポートします。誰かがこの男を止める!
致命的な

1
@Ellそれは理にかなっています!良い仕事:)
ケード

22

ラテックス、 540 532文字

免責事項:これは完全ではなく、間違いなく有効な回答としてはカウントされません。

\ usepackage [LGRgreek] {mathastext}
\ renewcommand {\ sum} {\ kern-1ex \ displaystyle \ mathop {\ vphantom {\ int} \ begin {array} {l} \ mbox {\ underline {\ hspace {12pt}}} \\ \ mbox {\ textbackslash } \ hspace {8pt} `\\\ mbox {/ \ underline {\ hspace {8pt}}、} \ end {array}} \ displaylimits}
\ renewcommand {\ prod} {\ kern-1ex \ displaystyle \ mathop {\ vphantom {\ int} \ begin {array} {c} \ mbox {\ underline {\ hspace {16pt}}} \\ | \ \ \ \ | \\ | \ \ \ \ | \ end {array}} \ displaylimits}
\ renewcommand {\ frac} [2] {\ mathop {\ xleaders \ hbox {-} \ hfill \ kern0pt} \ limits ^ {#1} _ {#2}}
\ DeclareMathSizes {10} {10} {10} {10}

@Fatalizeのヘルプがあります。詳細についてはコメントをご覧ください。

テスト:

入力: \prod_{i=1}^{n} \frac{\sum_{j=0}^{m} 2j}{i + 1}

出力:

ここに画像の説明を入力してください

ご覧のとおり、出力は仕様に正確に準拠していません。これは私の答えを失格にするかもしれませんが、私はまだ投稿する価値があると思います。

これはsharelatex.comで書きました。ここで遊ぶことができます


1
いいね!コードを少し試してみましたが、分数を\newcommand{\frac}[2]{\mathop{\xleaders\hbox{-}\hfill\kern0pt}\limits^{#1}_{#2}}に変更して\DeclareMathSizes{10}{10}{10}{10}から(LaTeXが分子と分母を縮めないように)、合計と製品定義の\kern-1ex\displaystyleに追加することで、すべてを修正できると思います。
15年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.