Il povero LaTeX


37

Sei trasportato in un universo parallelo in cui le persone scrivono a mano equazioni matematiche sui computer come arte ASCII. Come dipendente da LaTeX, questo è totalmente inaccettabile e dovresti automatizzare un po 'questo processo.

Il tuo obiettivo è quello di scrivere un programma che genera una versione ASCII di un'equazione inserita come comando matematico LaTeX.

Comandi LaTeX obbligatori da supportare

  • Somma: il comando LaTeX per una somma è \sum_{lower bound}^{upper bound}

    La cifra ASCII che devi usare per le somme è:

    upper bound
        ___ 
        \  `
        /__,
    lower bound
    
  • Prodotto: il comando LaTeX per un prodotto è \prod_{lower bound}^{upper bound}

    La cifra ASCII che devi usare per i prodotti è:

    upper bound
        ____
        |  |
        |  |
    lower bound
    
  • Frazione: il comando LaTeX per le frazioni è \frac{numerator}{denominator}

    La cifra ASCII che devi usare per le frazioni è:

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

Tutto ciò che non è uno di quei tre comandi viene visualizzato così com'è. Ad esempio, \sum{i=3}^{e^10}\frac{3x+5}{2}dovrebbe essere visualizzato come

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

ingressi

L'input è un comando LaTeX passato come stringa (o equivalente della tua lingua alle stringhe). I comandi LaTeX possono essere nidificati, ad esempio \frac{\frac{1}{2}}{3}è un input valido. Gli input dovrebbero essere sempre corretti (non è necessario controllare la sintassi di LaTeX nel codice). Gli input saranno composti solo dai tre comandi LaTeX presentati sopra e da "testo" che non è necessario formattare.

I comandi LaTeX verranno sempre con la sintassi presentata sopra, ovvero somme e prodotti avranno sempre limiti superiore e inferiore (anche se possono essere vuoti) e ci saranno sempre un numeratore e un denominatore per le frazioni.

Partiamo dal presupposto che i limiti di somme e prodotti sono lunghi al massimo 4 caratteri (= la larghezza della somma e dei simboli del prodotto), quindi non devi preoccuparti di possibili problemi di sovrapposizione. Per ragioni simili, supponiamo che i limiti siano solo "testo" e non saranno mai comandi LaTeX, ad esempio \sum_{\sum_{1}^{2}}^{1}non è un input valido.

Uscite

L'output del tuo programma è la rappresentazione ASCII del comando LaTeX che ti è stato dato come input.

Il programma deve tenere conto dell'allineamento orizzontale: ad esempio, i limiti della somma o del prodotto devono essere allineati orizzontalmente con il simbolo della somma o del prodotto (che sono entrambi di 4 caratteri). Se il limite ha un numero dispari di caratteri, non importa se si tratta di un carattere a destra oa sinistra del centro, a seconda di quale va bene. La linea della frazione deve essere lunga quanto il numeratore o il denominatore, a seconda di quale sia il più lungo.

Il programma deve tenere conto dell'allineamento verticale: ad esempio, \frac{\frac{1}{2}}{3} = \frac{1}{6}deve essere visualizzato come

1
-
2   1
- = -
3   6

Per somme e prodotti, poiché i simboli sono alti 4 caratteri, si presume che il centro verticale sia la seconda riga dall'alto.

Si presume che la spaziatura orizzontale sia corretta nell'input dato, cioè gli spazi nell'input dovrebbero essere visualizzati nell'output.

Casi test

  • Ingresso abc = 2

    Produzione abc = 2

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

    Produzione

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

    Produzione

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

    Produzione

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

    Produzione

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

punteggio

Questo è , quindi vince il codice più corto.


11
Bella prima sfida. Sembra piuttosto difficile; Sono entusiasta di vedere alcune soluzioni.
Alex A.

1
@Alex A. Inizialmente avevo intenzione di avere anche integrali, radici quadrate e parentesi espandibile, ma sembrava un po 'troppo ...
Fatalizza il

2
Credo che ci saranno casi in cui ti sovrapponi. Ad esempio, se si dispone di una somma in cui il termine diventa superiore a 4 (ad esempio frazioni multiple, frazioni di somme) e la somma ha un limite superiore / inferiore lungo, la stringa del limite superiore / inferiore potrebbe sovrapporsi al termine. Come sarebbe risolto? Il termine deve essere distanziato dalla somma per evitare sovrapposizioni con i limiti?
Reto Koradi,


8
Spero davvero che qualcuno trovi una soluzione in LaTeX
shadowtalker il

Risposte:


23

Python 2, 656 627 618 byte

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

Accetta input su STDIN e scrive output su STDOUT.

Il programma presume che nessun'altra sequenza di controllo sia \frac, \sumo \prodappare nell'input (cioè, non mostrerà come testo normale) e che ~non appaia altrettanto ( ha comunque un significato speciale in modalità matematica ). D'altra parte, il programma fa sostenere formule arbitrarie come limiti per \sume \prod.

Spiegazione

Funziona proprio come TeX! (beh, sorta di ...) Ogni sottformula (a partire da singoli caratteri e costruendo formule più complesse) viene trasformata in una scatola, con larghezza, altezza e profondità associate (linea di base). Le scatole di formule più semplici vengono combinate in scatole più grandi per formare formule complesse e così via. I contenuti di ogni riquadro sono rappresentati come un elenco di coppie posizione / carattere, relative all'angolo in alto a sinistra del riquadro; quando le caselle vengono combinate in una casella più grande, le posizioni vengono sfalsate in base alle posizioni relative delle caselle più piccole all'interno di quella più grande e gli elenchi vengono concatenati.

Alla fine, finiamo con un riquadro di livello superiore, che viene convertito in un modulo stampabile.


Per rendere un po 'più piccante, la seguente versione supporta anche le radici quadrate:

Esempi:

  • \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
Devo dire che sono rimasto molto colpito! \prod_{i=1}^{\sum_{azededzeda}^{k}} \frac{\sum_{j=0}^{m} 2j}{i + 1}Ho provato a correre e ha prodotto tutto correttamente senza sovrapposizioni, anche se non era necessario. Bello!
Fatalizza il

4
E supporti le radici quadrate con solo ~ il 18% in più di byte. Qualcuno fermi quest'uomo!
Fatalizza il

1
@Ell That ha senso! Bel lavoro :)
Kade,

22

LaTeX, 540 532 caratteri

Disclaimer: questo non è perfetto e probabilmente non conta come una risposta valida.

\ 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} \ limiti ^ {# 1} _ {2 #}}
\ DeclareMathSizes {10} {10} {10} {10}

Qualche aiuto da @Fatalize, vedere i commenti per i dettagli.

Test:

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

Produzione:

inserisci qui la descrizione dell'immagine

Come puoi vedere, l'output non segue esattamente le specifiche. Questo potrebbe squalificare la mia risposta, ma penso ancora che valga la pena pubblicare.

L'ho scritto su sharelatex.com. Puoi giocarci qui .


1
Bello! Ho giocato un po 'con il tuo codice e penso che puoi sistemare tutto cambiando la tua frazione in \newcommand{\frac}[2]{\mathop{\xleaders\hbox{-}\hfill\kern0pt}\limits^{#1}_{#2}}, aggiungendo \DeclareMathSizes{10}{10}{10}{10}successivamente (per impedire a LaTeX di ridurre i numeratori e denominatori) e aggiungendo \kern-1exprima \displaystylenella tua somma e nella definizione del prodotto.
Fatalizza il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.