Бідний чоловічий LaTeX


37

Вас транспортують у паралельний Всесвіт, де люди вручну пишуть математичні рівняння на комп’ютерах як мистецтво ASCII. Як наркоман LaTeX, це абсолютно неприпустимо, і вам слід дещо автоматизувати цей процес.

Ваша мета - написати програму, яка виводить ASCII версію рівняння, введеного як математична команда LaTeX.

Обов’язкові команди 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}, не є коректним вводом.

Виходи

Результатом вашої програми є представлення ASCII команди LaTeX, яку ви дали для введення.

Ваша програма повинна враховувати горизонтальне вирівнювання: наприклад, межі суми або продукту повинні бути горизонтально вирівняні з сумою або символом продукту (які обидва мають 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
Гарний перший виклик. Це виглядає досить складно; Я раді бачити деякі рішення.
Олексій А.

1
@ Алекс А. Спочатку я мав намір також мати інтеграли, квадратні корені та розширювані круглі дужки, але це здалося трохи занадто ...
Fatalize

2
Я вірю, що будуть випадки, коли ви перетинаєтесь. Наприклад, якщо у вас є сума, де термін стає більшим за 4 (наприклад, кілька дробів, дроби суми), і сума має довгу верхню / нижню межу, верхній / нижній обмежений рядок може перетинатися з терміном. Як би це було вирішено? Чи слід відкладати термін від суми, щоб уникнути перекриття меж?
Рето Кораді


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
@Ell Це має сенс! Приємна робота :)
Каде

22

LaTeX, 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 {/ \ підкреслити {\ hspace {8pt}},} \ end {масив}} \ displaylimits}
\ renewcommand {\ prod} {\ kern-1ex \ displaystyle \ mathop {\ vphantom {\ int} \ begin {масив} {c} \ mbox {\ підкреслити {\ hspace {16pt}}} \\ | \ \ \ \ | \\ | \ \ \ \ | | end {масив}} \ відображення обмежень}
\ renewcommand {\ frac} [2] {\ mathop {\ xleaders \ hbox {-} \ hfill \ kern0pt} \ межі ^ {# 1} _ {# 2}}
\ DeclareMathS Size {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до вашої суми та визначення продукту.
Фаталізувати
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.