可怜的人的乳胶


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
    

不属于这三个命令之一的所有内容均按原样显示。例如,\sum{i=3}^{e^10}\frac{3x+5}{2}应显示为

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

输入项

输入是作为字符串(或您的语言等效于字符串)传递的LaTeX命令。LaTeX命令可以嵌套,例如\frac{\frac{1}{2}}{3}是有效输入。输入应该总是正确的(无需在代码中检查LaTeX的语法)。输入仅包含上面显示的三个LaTeX命令和不需要格式化的“文本”。

LaTeX命令将始终具有上述语法,即,总和和乘积始终具有上限和下限(尽管它们可以为空),并且始终存在分数的分子和分母。

我们假定求和与乘积的边界最多为4个字符长(=和与乘积符号的宽度),因此您不必担心可能出现的重叠问题。出于类似的原因,我们假设边界只是“文本”,绝不会是LaTeX命令,例如\sum_{\sum_{1}^{2}}^{1}不是有效输入。

产出

程序的输出是作为输入提供的LaTeX命令的ASCII表示形式。

您的程序必须考虑水平对齐:例如,总和或乘积的边界必须与总和或乘积符号(均为4个字符宽)水平对齐。如果边界中的字符数为奇数,则该字符距中心的右侧或左侧是否相距一个字符都没有关系,以较合适的为准。分数线必须与分子或分母一样长,以最长者为准。

您的程序必须考虑垂直对齐:例如,\frac{\frac{1}{2}}{3} = \frac{1}{6}应显示为

1
-
2   1
- = -
3   6

对于总和和乘积,由于符号的高度为4个字符,因此假定垂直中心为从顶部起第二行。

假定在给定输入中水平间距是正确的,即输入中的空格应显示在输出中。

测试用例

  • 输入值 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
不错的第一个挑战。看起来很难。我很高兴看到一些解决方案。
Alex A.

1
@Alex A.我本来打算也有积分,平方根和可扩展的括号,但这似乎有点过分……
Fatalize 2015年

2
我相信在某些情况下您会重叠。例如,如果您有一项总和,其中项变得高于4(例如,多个分数,总和的分数),并且总和具有较长的上限/下限,则上限/下限字符串可能与该项重叠。那将如何解决?该术语是否必须与总和隔开以避免与边界重叠?
Reto Koradi


8
我真的希望有人提出LaTeX的解决方案
shadowtalker 2015年

Answers:


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讲得通!做得好:)
Kade 2015年

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在您的总和和产品的定义。
致命
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.