Бедный мужской латекс


37

Вы переноситесь в параллельную вселенную, где люди пишут математические уравнения на компьютерах как искусство ASCII вручную. Как наркоман LaTeX, это абсолютно неприемлемо, и вам следует несколько автоматизировать этот процесс.

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

Обязательные команды LaTeX для поддержки

  • Сумма: команда LaTeX для суммы \sum_{lower bound}^{upper bound}

    Число ASCII, которое вы должны использовать для сумм:

    upper bound
        ___ 
        \  `
        /__,
    lower bound
    
  • Product: команда 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
@Alex A. Я изначально намеревался иметь также интегралы, квадратные корни и расширяемые скобки, но это казалось слишком много ...
Fatalize

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


8
Я действительно надеюсь, что кто-то
придумает

Ответы:


23

Python 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}и все правильно вычислялось без наложения, хотя это и не требовалось. Ницца!
Fatalize

4
И вы поддерживаете квадратные корни только на ~ 18% больше байтов. Кто-нибудь остановить этого человека!
Fatalize

1
@ Все это имеет смысл! Хорошая работа :)
Kade

22

Латекс, 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}}} \ {конец массива}}} \ displaylimits
\ renewcommand {\ prod} {\ kern-1ex \ displaystyle \ mathop {\ vphantom {\ int} \ begin {array} {c} \ mbox {\ underline {\ hspace {16pt}}} \\ | \ \ \ \ | \\ | \ \ \ \ | \ end {array}} \ displaylimits}
\ Renewcommand {\ гидроразрыва} [2] {\ mathop {\ xleaders \ HBox {-} \ hfill \ kern0pt} \ пределы ^ {# 1} _ {# 2}}
\ DeclareMathSizes {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в вашем определении суммы и продукта.
Fatalize
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.