LaTeX du pauvre

37

Vous êtes transporté dans un univers parallèle où les gens écrivent manuellement des équations mathématiques sur des ordinateurs en tant qu'art ASCII. En tant que dépendant de LaTeX, cela est totalement inacceptable et vous devriez automatiser un peu ce processus.

Votre objectif est d'écrire un programme qui génère une version ASCII d'une équation saisie en tant que commande mathématique LaTeX.

Commandes LaTeX obligatoires à prendre en charge

  • Sum: la commande LaTeX pour une somme est \sum_{lower bound}^{upper bound}

    Le chiffre ASCII que vous devez utiliser pour les sommes est:

    upper bound
        ___ 
        \  `
        /__,
    lower bound
    
  • Produit: la commande LaTeX pour un produit est \prod_{lower bound}^{upper bound}

    La figure ASCII que vous devez utiliser pour les produits est la suivante:

    upper bound
        ____
        |  |
        |  |
    lower bound
    
  • Fraction: la commande LaTeX pour les fractions est \frac{numerator}{denominator}

    La figure ASCII que vous devez utiliser pour les fractions est la suivante:

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

Tout ce qui ne fait pas partie de ces trois commandes est affiché tel quel. Par exemple, \sum{i=3}^{e^10}\frac{3x+5}{2}devrait être affiché comme

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

Contributions

L'entrée est une commande LaTeX transmise sous forme de chaîne (ou l'équivalent de votre langue en chaînes). Les commandes LaTeX peuvent être imbriquées, par exemple \frac{\frac{1}{2}}{3}une entrée valide. Les entrées sont supposées être toujours correctes (inutile de vérifier la syntaxe de LaTeX dans votre code). Les entrées ne seront composées que des trois commandes LaTeX présentées ci-dessus et d'un 'texte' que vous n'aurez pas besoin de formater.

Les commandes LaTeX viendront toujours avec la syntaxe présentée ci-dessus, c'est-à-dire que les sommes et les produits auront toujours des limites supérieure et inférieure (bien qu'ils puissent être vides) et qu'il y aura toujours un numérateur et un dénominateur pour les fractions.

Nous supposons que les limites des sommes et des produits comportent au plus 4 caractères (= la largeur de la somme et les symboles du produit), de sorte que vous n’ayez pas à vous soucier des éventuels problèmes de chevauchement. Pour des raisons similaires, nous supposons que les bornes ne sont que du texte et ne seront jamais des commandes LaTeX. Par exemple, ce \sum_{\sum_{1}^{2}}^{1}n'est pas une entrée valide.

Les sorties

La sortie de votre programme est la représentation ASCII de la commande LaTeX qui vous a été donnée en entrée.

Votre programme doit prendre en compte l'alignement horizontal: par exemple, les limites de la somme ou du produit doivent être alignées horizontalement avec la somme ou le symbole du produit (tous deux d'une largeur de 4 caractères). Si la limite comporte un nombre impair de caractères, peu importe qu'il s'agisse d'un caractère à gauche ou à droite du centre, celle qui convient le mieux. La ligne de la fraction doit être aussi longue que le numérateur ou le dénominateur, le plus long des deux.

Votre programme doit prendre en compte l’alignement vertical: par exemple, \frac{\frac{1}{2}}{3} = \frac{1}{6}doit être affiché comme

1
-
2   1
- = -
3   6

Pour les sommes et les produits, puisque les symboles ont 4 caractères de haut, le centre vertical est supposé être la deuxième ligne en partant du haut.

L'espacement horizontal est supposé être correct dans l'entrée donnée, c'est-à-dire que les espaces de l'entrée doivent être affichés dans la sortie.

Cas de test

  • Contribution abc = 2

    Sortie abc = 2

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

    Sortie

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

    Sortie

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

    Sortie

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

    Sortie

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

Notation

C'est du , donc le code le plus court gagne.

Fataliser
la source
11
Beau premier défi. Cela semble assez difficile; Je suis excité de voir des solutions.
Alex A.
1
@Alex A. À l'origine, j'avais l'intention d'intégrer également les intégrales, les racines carrées et les parenthèses extensibles, mais cela
me
2
Je crois qu'il y aura des cas de chevauchement. Par exemple, si vous avez une somme dont le terme devient supérieur à 4 (par exemple, plusieurs fractions, fractions de sommes) et que la somme a une longue limite supérieure / inférieure, la chaîne de limite supérieure / inférieure pourrait chevaucher le terme. Comment cela serait-il résolu? Le terme doit-il être espacé de la somme pour éviter un chevauchement avec les limites?
Reto Koradi
8
J'espère vraiment que quelqu'un
trouvera

Réponses:

23

Python 2, 656 627 618 octets

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

Prend une entrée sur STDIN et écrit la sortie sur STDOUT.

Le programme suppose qu'aucune autre séquence de contrôle que \frac, \sumou \prodn'apparaît dans l'entrée (c'est-à-dire, il ne s'affichera pas sous forme de texte normal) et cela ~n'apparaît pas aussi bien (il a de toute façon une signification spéciale en mode mathématique .) D'autre part, le programme prend en charge des formules arbitraires comme limites pour \sumet \prod.

Explication

Cela fonctionne comme TeX! (enfin, en quelque sorte ...) Chaque sous-formule (en commençant par des caractères uniques et en passant par des formules plus complexes) est transformée en une boîte, avec une largeur, une hauteur et une profondeur associées (ligne de base). Des boîtes de formules plus simples sont combinées dans des boîtes plus grandes pour former des formules complexes, etc. Le contenu de chaque case est représenté par une liste de paires de positions / caractères, par rapport au coin supérieur gauche de la case. Lorsque les cases sont combinées dans une case plus grande, les positions sont décalées en fonction des positions relatives des cases les plus petites à l'intérieur de la plus grande, et les listes sont concaténées.

Finalement, nous nous retrouvons avec une boîte de niveau supérieur, qui est convertie en un formulaire imprimable.


Pour pimenter un peu, la version suivante supporte également les racines carrées:

Exemples:

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

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

               _____________
              / ___
    |v| =    /  \  ` v[i]^2
            /   /__,
          \/     i
    
Aune
la source
9
Je dois dire que je suis complètement impressionné! \prod_{i=1}^{\sum_{azededzeda}^{k}} \frac{\sum_{j=0}^{m} 2j}{i + 1}J'ai essayé de courir et tout est sorti correctement, sans chevauchement, même si ce n'était pas nécessaire. Agréable!
Fataliser
4
Et vous supportez les racines carrées avec seulement ~ 18% d'octets en plus. Quelqu'un arrête cet homme!
Fatalise le
1
@Ell Cela fait sens! Beau travail :)
Kade
22

LaTeX, 540 532 caractères

Avertissement: Ce n'est pas parfait et ne constitue sans doute pas une réponse valable.

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

Un peu d'aide de @Fatalize, voir les commentaires pour plus de détails.

Tester:

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

Sortie:

entrez la description de l'image ici

Comme vous pouvez le constater, la sortie ne suit pas exactement les spécifications. Cela peut disqualifier ma réponse, mais je pense toujours que ça vaut la peine de la poster.

J'ai écrit ceci sur sharelatex.com. Vous pouvez jouer avec ça ici .

sudo rm -rf slash
la source
1
Agréable! J'ai un peu joué avec votre code et je pense que vous pouvez tout régler en changeant votre fraction en \newcommand{\frac}[2]{\mathop{\xleaders\hbox{-}\hfill\kern0pt}\limits^{#1}_{#2}}ajoutant \DeclareMathSizes{10}{10}{10}{10}ensuite (pour éviter que LaTeX ne réduise les numérateurs et les dénominateurs), et en ajoutant \kern-1exavant \displaystyledans votre définition de somme et de produit.
Fataliser