불쌍한 사람의 라텍스


37

사람들은 컴퓨터에서 수학적 방정식을 ASCII 예술로 직접 쓰는 평행 우주에서 운송됩니다. LaTeX 중독자로서 이것은 완전히 받아 들일 수 없으며이 과정을 다소 자동화해야합니다.

LaTeX math 명령으로 입력 된 방정식의 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

2
나는 당신이 겹치는 경우가있을 것이라고 믿습니다. 예를 들어, 항이 4보다 커지는 합 (예 : 여러 분수, 합의 분수)이 있고 합의 상한 / 하한이 길면 상한 / 하한 문자열이 항과 겹칠 수 있습니다. 어떻게 해결 될까요? 경계와 겹치지 않도록 용어를 합계에서 분리해야합니까?
Reto Koradi


8
나는 누군가 누군가 LaTeX에서 해결책을 제시하기를 바랍니다
shadowtalker

답변:


23

파이썬 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
@ Elll 그 의미가 있습니다! 좋은 일 :)
Kade

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귀하의 합과 제품 정의한다.
치명적인
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.