LaTeX do pobre homem


37

Você é transportado em um universo paralelo em que as pessoas escrevem equações matemáticas em computadores como arte ASCII à mão. Como um viciado em LaTeX, isso é totalmente inaceitável, e você deve automatizar um pouco esse processo.

Seu objetivo é escrever um programa que produza uma versão ASCII de uma equação inserida como um comando matemático LaTeX.

Comandos obrigatórios do LaTeX para suportar

  • Soma: o comando LaTeX para uma soma é \sum_{lower bound}^{upper bound}

    A figura ASCII que você deve usar para somas é:

    upper bound
        ___ 
        \  `
        /__,
    lower bound
    
  • Produto: o comando LaTeX para um produto é \prod_{lower bound}^{upper bound}

    A figura ASCII que você deve usar para produtos é:

    upper bound
        ____
        |  |
        |  |
    lower bound
    
  • Fração: o comando LaTeX para frações é \frac{numerator}{denominator}

    A figura ASCII que você deve usar para frações é:

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

Qualquer coisa que não seja um desses três comandos é exibida como está. Por exemplo, \sum{i=3}^{e^10}\frac{3x+5}{2}deve ser exibido como

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

Entradas

A entrada é um comando do LaTeX passado como uma string (ou o seu idioma é equivalente a strings). Os comandos do LaTeX podem ser aninhados, por exemplo, \frac{\frac{1}{2}}{3}é uma entrada válida. As entradas devem estar sempre corretas (não é necessário verificar a sintaxe do LaTeX no seu código). As entradas consistirão apenas dos três comandos do LaTeX apresentados acima e do 'texto' que você não precisará formatar.

Os comandos do LaTeX sempre vêm com a sintaxe apresentada acima, ou seja, somas e produtos sempre terão limites superior e inferior (embora possam estar vazios) e sempre haverá um numerador e denominador para frações.

Assumimos que os limites de somas e produtos tenham no máximo 4 caracteres (= a largura da soma e dos símbolos do produto), para que você não precise se preocupar com possíveis problemas de sobreposição. Por razões semelhantes, assumimos que os limites são apenas 'texto' e nunca serão comandos do LaTeX; por exemplo, \sum_{\sum_{1}^{2}}^{1}não é uma entrada válida.

Saídas

A saída do seu programa é a representação ASCII do comando LaTeX que você recebeu como entrada.

Seu programa deve levar em consideração o alinhamento horizontal: por exemplo, os limites da soma ou do produto devem ser alinhados horizontalmente com o símbolo da soma ou do produto (com 4 caracteres de largura). Se o limite tiver um número ímpar de caracteres, não importa se é um caractere à direita ou à esquerda do centro, o que for adequado. A linha da fração deve ter o tamanho do numerador ou do denominador, o que for maior.

Seu programa deve levar em consideração o alinhamento vertical: por exemplo, \frac{\frac{1}{2}}{3} = \frac{1}{6}deve ser exibido como

1
-
2   1
- = -
3   6

Para somas e produtos, como os símbolos têm 4 caracteres, o centro vertical é considerado a segunda linha do topo.

O espaçamento horizontal é considerado correto na entrada fornecida, ou seja, os espaços na entrada devem ser exibidos na saída.

Casos de teste

  • Entrada abc = 2

    Saída abc = 2

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

    Saída

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

    Saída

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

    Saída

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

    Saída

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

Pontuação

Isso é , então o código mais curto vence.


11
Bom primeiro desafio. Parece bem difícil; Estou animado para ver algumas soluções.
Alex A.

11
@Alex A. I originalmente destinados a têm também integrais, raízes quadradas e parênteses expansível, mas que parecia um pouco demais ...
Fatalize

2
Acredito que haverá casos em que você se sobrepõe. Por exemplo, se você tiver uma soma em que o termo se torne maior que 4 (por exemplo, frações múltiplas, frações de somas) e a soma tiver um limite superior / inferior longo, a cadeia do limite superior / inferior poderá se sobrepor ao termo. Como isso seria resolvido? O termo precisa ser espaçado da soma para evitar sobreposição com os limites?
Reto Koradi


8
Eu realmente espero que alguém surge com uma solução em LaTeX
shadowtalker

Respostas:


23

Python 2, 656 627 618 bytes

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))

Recebe entrada em STDIN e grava a saída em STDOUT.

O programa assume que nenhuma outra sequência de controle que não seja \frac, \sumou \prodapareça na entrada (ou seja, não aparecerá como texto normal) e que ~não apareça tão bem ( tem um significado especial no modo matemático) . por outro lado, o programa faz apoiar fórmulas arbitrárias como limites para \sume \prod.

Explicação

Funciona exatamente como o TeX! (bem, mais ou menos ...) Cada sub-fórmula (iniciando com caracteres únicos e construindo com fórmulas mais complexas) é transformada em uma caixa, com uma largura, altura e profundidade associadas (linha de base). Caixas de fórmulas mais simples são combinadas em caixas maiores para formar fórmulas complexas e assim por diante. O conteúdo de cada caixa é representado como uma lista de pares de posição / caractere, em relação ao canto superior esquerdo da caixa; quando as caixas são combinadas em uma caixa maior, as posições são deslocadas de acordo com as posições relativas das caixas menores dentro da maior e as listas são concatenadas.

Eventualmente, acabamos com uma caixa de nível superior, que é convertida em um formulário imprimível.


Para apimentar um pouco, a versão a seguir também suporta raízes quadradas:

Exemplos:

  • \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
Eu tenho que dizer que estou completamente impressionado! Tentou executar \prod_{i=1}^{\sum_{azededzeda}^{k}} \frac{\sum_{j=0}^{m} 2j}{i + 1}e produziu tudo corretamente, sem sobreposição, mesmo que não fosse necessário. Agradável!
Fatalize

4
E você suporta raízes quadradas com apenas ~ 18% mais bytes. Alguém pare esse homem!
Fatalize

11
@ Tudo isso faz sentido! Bom trabalho :)
Kade

22

LaTeX, 540 532 caracteres

Isenção de responsabilidade: isso não é perfeito e, sem dúvida, não conta como uma resposta válida.

\ 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}

Alguma ajuda do @Fatalize, consulte os comentários para obter detalhes.

Teste:

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

Saída:

insira a descrição da imagem aqui

Como você pode ver, a saída não segue exatamente a especificação. Isso pode desqualificar minha resposta, mas ainda acho que vale a pena postar.

Eu escrevi isso no sharelatex.com. Você pode brincar aqui .


11
Agradável! Eu brinquei um pouco com seu código e acho que você pode consertar tudo alterando sua fração para \newcommand{\frac}[2]{\mathop{\xleaders\hbox{-}\hfill\kern0pt}\limits^{#1}_{#2}}, adicionando \DeclareMathSizes{10}{10}{10}{10}depois disso (para impedir que o LaTeX diminua numeradores e denominadores) e adicionando \kern-1exantes \displaystylena sua soma e definição de produto.
Fatalize
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.