Реализация макросов LaTeX с акцентом

11

Вступление

Система набора текста LaTeX использует макросы для определения ударений. Например, буква is производится \hat{e}. В этой задаче ваша задача заключается в реализации ASCII-версии этой функциональности.

вход

Ваш ввод - непустая строка печатных символов ASCII. Он не будет содержать переводы строк.

Выход

Ваш вывод представляет собой строку, состоящую из двух строк. Первая строка содержит акценты, а вторая - символы, которым они принадлежат. Он получается из ввода следующим образом ( Aобозначает произвольный символ):

  • Каждый \bar{A}заменяется Aс _поверх него.
  • Каждый \dot{A}заменяется Aс .поверх него.
  • Каждый \hat{A}заменяется Aс ^поверх него.
  • Для -10% бонуса: каждый \tilde{A}заменяются Aс ~поверх него.
  • Все остальные символы имеют пробел над ними.

Например, вход

Je suis pr\hat{e}t.

результаты в выводе

          ^
Je suis pret.

Правила и оценки

Можно предположить, что символы \{}встречаются только в макросах \bar{}, \dot{}и \hat{}\tilde{}если вы идете за бонусом). Все макро аргументы точный длинный один символ, так \dot{foo}и \dot{}не будет происходить на входе. Выходными данными может быть строка, разделенная новой строкой, или список / пара из двух строк. Допускается любое количество пробелов и предшествующих пробелов, если акценты находятся в правильных местах. В частности, если нет акцентов, вывод может быть одной строкой.

Вы можете написать полную программу или функцию. Наименьшее количество байтов (после бонусов) выигрывает, и стандартные лазейки запрещены.

Контрольные примеры

Без бонуса:

Input:
No accents.
Output:

No accents.
Input:
Ch\hat{a}teau
Output:
  ^
Chateau
Input:
Som\bar{e} \dot{a}cc\hat{e}nts.
Output:
   _ .  ^
Some accents.
Input:
dot hat\dot{h}a\hat{t}\hat{ }x\bar{x}dot
Output:
       . ^^ _
dot hathat xxdot
Input:
\hat{g}Hmi\hat{|}Su5Y(\dot{G}"\bar{$}id4\hat{j}gB\dot{n}#6AX'c\dot{[}\hat{)} 6\hat{[}T~_sR\hat{&}CEB
Output:
^   ^     . _   ^  .      .^  ^     ^
gHmi|Su5Y(G"$id4jgBn#6AX'c[) 6[T~_sR&CEB

С бонусом:

Input:
Ma\tilde{n}ana
Output:
  ~
Manana
Input:
\dot{L}Vz\dot{[}|M.\bar{#}0\hat{u}U^y!"\tilde{I} K.\bar{"}\hat{m}dT\tilde{$}F\bar{;}59$,/5\bar{'}K\tilde{v}R \tilde{E}X`
Output:
.  .   _ ^     ~   _^  ~ _      _ ~  ~
LVz[|M.#0uU^y!"I K."mdT$F;59$,/5'KvR EX`
Zgarb
источник
Я начал создавать прототип в Go, но потом понял, насколько проще будет Python ...
cat
1
Можем ли мы предположить, что каждая запись разметки содержит только один символ? Или, другими словами, \bar{foo}это правильный вход?
Питер Тейлор
@PeterTaylor Да, каждый аргумент макроса имеет длину ровно один символ. Я уточню это.
Згарб

Ответы:

4

Pyth, 51 46 45 43 41 40 байт

Я \удаляю фигурные скобки и делю на , как и ответ Рето Коради на CJam. Коды bar, dotи hatраспознаются только последним десятичного знака символа кода первого символа, по модулю 3. Я просто добавить (RIP) в первой части и удалить его , в конце концов , чтобы сохранить код для обработки первой части специально ,barf """"

jtMsMCm,+@".^_"eChd*\ -ld4>d3c-+*4Nz`H\\

Попробуйте онлайн. Тестирование.

PurkkaKoodari
источник
1
« Тогда я просто добавлю barf... » +1
Аддисон Крамп
3

Юлия, 204 184 байта * 0,9 = 165,6

x->(r=r"\\(\w)\w+{(\w)}";t=[" "^endof(x)...];while ismatch(r,x) m=match(r,x);(a,b)=m.captures;t[m.offsets[1]-1]=a=="b"?'_':a=="d"?'.':a=="h"?'^':'~';x=replace(x,r,b,1)end;(join(t),x))

Это анонимная функция, которая принимает строку и возвращает кортеж строк, соответствующих верхней и нижней строкам. Верхняя строка будет содержать пробел. Чтобы вызвать функцию, дайте ей имя, напримерf=x->...

Ungolfed:

function f(x::AbstractString)
    # Store a regular expression that will match the LaTeX macro call
    # with capture groups for the first letter of the control sequence
    # and the character being accented
    r = r"\\(\w)\w+{(\w)}"

    # Create a vector of spaces by splatting a string constructed with
    # repetition
    # Note that if there is anything to replace, this will be longer
    # than needed, resulting in trailing whitespace
    t = [" "^endof(x)...]

    while ismatch(r, x)
        # Store the RegexMatch object
        m = match(r, x)

        # Extract the captures
        a, b = m.captures

        # Extract the offset of the first capture
        o = m.captures[1]

        # Replace the corresponding element of t with the accent
        t[o-1] = a == "b" ? '_' : a == "d" ? '.' : a == "h" ? '^' : '~'

        # Replace this match in the original string
        x = replace(x, r, b, 1)
    end

    # Return the top and bottom lines as a tuple
    return (join(t), x)
end
Алекс А.
источник
2

CJam, 53 байта

Sl+'\/(_,S*\@{(i2/49-"_. ^"=\3>'}-_,(S*@\+@@+@@+\}/N\

Попробуйте онлайн

Объяснение:

S       Leading space, to avoid special case for accent at start.
l+      Get input, and append it to leading space.
'\/     Split at '\.
(       Split off first sub-string, which does not start with an accent.
_,      Get length of first sub-string.
S*      String of spaces with the same length.
\       Swap the two. First parts of both output lines are now on stack.
@       Rotate list of remaining sub-strings to top.
{       Loop over sub-strings.
  (       Pop first character. This is 'b, 'd, or 'h, and determines accent.
  i       Convert to integer.
  2/      Divide by two.
  49-     Subtract 49. This will result in 0, 1, or 4 for the different accents.
  "_. ^"  Lookup string for the accents.
  =       Get the correct accent.
  \       Swap string to top.
  3>      Remove the first 3 characters, which is the rest of the accent string
          and the '{.
  '}-     Remove the '}. All the macro stuff is removed now.
  _,(     Get the length, and subtract 1. This is the number of spaces for the first line.
  S*      Produce the spaces needed for the first line.
  @\+     Bring accent and spaces to top, and concatenate them.
  @@+     Get previous second line and new sub-string without formatting to top,
          and concatenate them.
  @@+     Get previous first line and new accent and spacing to top,
          and concatenate them.
  \       Swap the two lines to get them back in first/second order.
}/      End loop over sub-strings.
N\      Put newline between first and second line.
Рето Коради
источник
1

Haskell, 156 * 0,9 = 140,4 байта

g('\\':a:r)=(q,l):g s where q|a=='b'='_'|a=='d'='.'|a=='h'='^'|a=='t'='~';(_,_:l:_:s)=span(<'{')r
g(a:b)=(' ',a):g b
g""=[('\n','\n')]
f=uncurry(++).unzip.g

Пример использования:

*Main> putStr $ f "\\dot{L}Vz\\dot{[}|M.\\bar{#}0\\hat{u}U^y!\"\\tilde{I} K.\\bar{\"}\\hat{m}dT\\tilde{$}F\\bar{;}59$,/5\\bar{'}K\\tilde{v}R \\tilde{E}X`"
.  .   _ ^     ~   _^  ~ _      _ ~  ~  
LVz[|M.#0uU^y!"I K."mdT$F;59$,/5'KvR EX`

Как это работает: просматривайте входную строку символ за символом и формируйте список пар символов, слева для верхней строки вывода, справа для нижней строки вывода. Если \найден a , возьмите соответствующий акцент, в противном случае оставьте пробел для левого элемента. Наконец, преобразовать список пар в одну строку.

Ними
источник
0

Python 3, 203 байта

Без бонуса:

l=list(input())
b=list(" "*len(l))
try:
 while 1:s=l.index("\\");t=l[s+1];del l[s+6];del l[s:s+5];b[s] = "b"==t and "_" or "d"==t and "." or "h"==t and "^" or "*";
except:print("".join(b)+"\n"+"".join(l));

Я действительно надеюсь, что есть более короткая версия.

Александр Нигл
источник
1
Всегда приятно видеть прогрессирование количества байтов. c: Я предлагаю оставить старый счетчик байтов, затем окружить его <s></s>, затем ввести новый счетчик байтов, чтобы мы могли видеть шаги к сжатию.
Аддисон Крамп