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


11

Вступ

Система набору тексту LaTeX використовує макроси для визначення акцентів. Наприклад, букву ê виробляє \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`

Я почав прототипувати це в Go, але потім зрозумів, наскільки простішим буде Python ...
кіт

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

Спробуйте в Інтернеті. Тестовий набір.


1
" Тоді я просто додаю barf... " +1
Addison Crump

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

Безголівки:

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

Пітон 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>, а потім ввести нове число байтів, щоб ми могли побачити кроки до стиснення.
Аддісон Кримп
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.