LaTeX biednego człowieka

37

Przenosisz się do równoległego wszechświata, w którym ludzie ręcznie piszą matematyczne równania na komputerach jako sztukę ASCII. Jako uzależniony od LaTeXa jest to całkowicie niedopuszczalne i należy nieco zautomatyzować ten proces.

Twoim celem jest napisanie programu, który wypisze wersję równania ASCII wprowadzoną jako polecenie matematyczne LaTeX.

Obowiązkowe polecenia LaTeX do obsługi

  • Suma: komenda LaTeX dla sumy to \sum_{lower bound}^{upper bound}

    Liczba ASCII, której musisz użyć do sum, to:

    upper bound
        ___ 
        \  `
        /__,
    lower bound
    
  • Produkt: komenda LaTeX dla produktu to \prod_{lower bound}^{upper bound}

    Liczba ASCII, którą musisz zastosować do produktów, to:

    upper bound
        ____
        |  |
        |  |
    lower bound
    
  • Frakcja: komenda LaTeX dla ułamków to \frac{numerator}{denominator}

    Liczba ASCII, której musisz użyć dla ułamków, to:

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

Wszystko, co nie jest jednym z tych trzech poleceń, jest wyświetlane w obecnej postaci. Na przykład \sum{i=3}^{e^10}\frac{3x+5}{2}powinien być wyświetlany jako

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

Wejścia

Dane wejściowe to polecenie LaTeX przekazane jako ciąg (lub odpowiednik napisów w Twoim języku). Polecenia LaTeX mogą być zagnieżdżone, na przykład \frac{\frac{1}{2}}{3}jest to poprawne wejście. Dane wejściowe powinny być zawsze poprawne (nie trzeba sprawdzać składni LaTeX-a w kodzie). Dane wejściowe będą składały się tylko z trzech poleceń LaTeX przedstawionych powyżej i „tekstu”, którego nie będzie trzeba formatować.

Polecenia LaTeX zawsze będą miały składnię przedstawioną powyżej, tzn. Sumy i produkty zawsze będą miały górne i dolne granice (chociaż mogą być puste) i zawsze będzie licznik i mianownik dla ułamków.

Zakładamy, że granice sum i produktów mają co najwyżej 4 znaki (= szerokość symboli sumy i produktów), więc nie musisz się martwić o możliwe problemy nakładania się. Z podobnych powodów zakładamy, że granice są po prostu „tekstem” i nigdy nie będą poleceniami LaTeX, np. \sum_{\sum_{1}^{2}}^{1}Nie są poprawnym wejściem.

Wyjścia

Wyjście twojego programu jest reprezentacją ASCII komendy LaTeX podanej jako dane wejściowe.

Twój program musi uwzględniać wyrównanie w poziomie: na przykład granice sumy lub produktu muszą być wyrównane w poziomie z sumą lub symbolem produktu (które mają szerokość 4 znaków). Jeśli granica ma nieparzystą liczbę znaków, nie ma znaczenia, czy jest to jeden znak z prawej, czy z lewej strony środka, w zależności od tego, co jest w porządku. Linia ułamka musi być tak długa jak licznik lub mianownik, w zależności od tego, który jest najdłuższy.

Twój program musi uwzględniać wyrównanie pionowe: na przykład \frac{\frac{1}{2}}{3} = \frac{1}{6}powinien być wyświetlany jako

1
-
2   1
- = -
3   6

W przypadku sum i produktów, ponieważ symbole mają 4 znaki wysokości, przyjmuje się, że pionowy środek jest drugą linią od góry.

Zakłada się, że odstępy poziome są prawidłowe na danym wejściu, tzn. Odstępy na wejściu powinny być wyświetlane na wyjściu.

Przypadki testowe

  • Wkład abc = 2

    Wydajność abc = 2

  • Wkład e = \sum_{n=0}^{+inf} \frac{1}{n!}

    Wydajność

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

    Wydajność

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

    Wydajność

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

    Wydajność

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

Punktacja

To jest , więc wygrywa najkrótszy kod.

Fatalizować
źródło
11
Ładne pierwsze wyzwanie. Wygląda to dość trudne; Jestem podekscytowany, aby zobaczyć niektóre rozwiązania.
Alex A.
1
@Alex A. Początkowo zamierzałem również mieć całki, pierwiastki kwadratowe i rozwijany nawias, ale wydawało się to trochę za dużo ...
Fatali
2
Wierzę, że zdarzają się przypadki nakładania się. Na przykład, jeśli masz sumę, w której termin staje się wyższy niż 4 (np. Wiele ułamków, ułamki sum), a suma ma długą górną / dolną granicę, łańcuch górnej / dolnej granicy może pokrywać się z tym terminem. Jak to można rozwiązać? Czy termin należy oddzielić od sumy, aby uniknąć nakładania się granic?
Reto Koradi
8
Naprawdę mam nadzieję, że ktoś
wymyśli

Odpowiedzi:

23

Python 2, 656 627 618 bajtów

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

Pobiera dane wejściowe w STDIN i zapisuje dane wyjściowe w STDOUT.

Program zakłada, że żadna inna kolejność kontroli niż \frac, \sumlub \prodpojawia się na wejściu (to znaczy, że nie pokaże jak normalny tekst) i że ~nie pojawia się jako dobrze (to ma szczególne znaczenie w trybie matematyki w każdym razie). Na drugiej strony, program ma wspierać dowolnych formuł jak limitów \sumi \prod.

Wyjaśnienie

Działa tak jak TeX! (cóż, coś w rodzaju ...) Każda podformularz (zaczynając od pojedynczych znaków i budując do bardziej skomplikowanych formuł) jest przekształcany w pudełko o powiązanej szerokości, wysokości i głębokości (linia bazowa). Pudełka o prostszych formułach są łączone w większe, tworząc złożone formuły i tak dalej. Zawartość każdego pola jest reprezentowana jako lista par pozycji / znaków względem lewego górnego rogu pola; gdy pola są połączone w większe pole, pozycje są przesunięte zgodnie z względnymi pozycjami mniejszych pól wewnątrz większego, a listy są konkatenowane.

Ostatecznie otrzymujemy pudełko najwyższego poziomu, które jest konwertowane na formularz do wydruku.


Aby nieco urozmaicić, następująca wersja obsługuje również pierwiastki kwadratowe:

Przykłady:

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

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

               _____________
              / ___
    |v| =    /  \  ` v[i]^2
            /   /__,
          \/     i
    
Łokieć
źródło
9
Muszę powiedzieć, że jestem pod wielkim wrażeniem! Próbowałem uruchomić \prod_{i=1}^{\sum_{azededzeda}^{k}} \frac{\sum_{j=0}^{m} 2j}{i + 1}i wszystko wypisało poprawnie bez nakładania się, nawet jeśli nie było to wymagane. Miły!
Fatalize
4
I wspierasz pierwiastki kwadratowe tylko o ~ 18% więcej bajtów. Niech ktoś powstrzyma tego człowieka!
Fatalize
1
@Ell To ma sens! Dobra robota :)
Kade
22

LaTeX, 540 532 znaków

Zastrzeżenie: To nie jest idealne i prawdopodobnie nie liczy się jako poprawna odpowiedź.

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

Część pomocy @Fatalize, zobacz komentarze, aby uzyskać szczegółowe informacje.

Test:

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

Wydajność:

wprowadź opis zdjęcia tutaj

Jak widać, wynik nie jest dokładnie zgodny ze specyfikacją. Może to zdyskwalifikować moją odpowiedź, ale nadal uważam, że warto ją opublikować.

Napisałem to na sharelatex.com. Możesz grać z tym tutaj .

sudo rm -rf slash
źródło
1
Miły! Grałem trochę z twoim kodem i myślę, że możesz wszystko naprawić, zmieniając ułamek na \newcommand{\frac}[2]{\mathop{\xleaders\hbox{-}\hfill\kern0pt}\limits^{#1}_{#2}}, dodając \DeclareMathSizes{10}{10}{10}{10}później (aby zapobiec zmniejszeniu liczników i mianowników przez LaTeX) oraz dodając \kern-1exwcześniej \displaystylew definicji sumy i produktu.
Fatalize