Zaimplementuj makra akcentujące LaTeX

11

Wprowadzenie

System składu LaTeX używa makr do definiowania akcentów. Na przykład litera ê jest produkowana przez \hat{e}. W tym wyzwaniu Twoim zadaniem jest zaimplementowanie wersji ASCII tej funkcji.

Wejście

Wprowadzony tekst jest niepustym ciągiem drukowalnych znaków ASCII. Nie będzie zawierać nowych linii.

Wynik

Twój wynik to ciąg składający się z dwóch linii. Pierwszy wiersz zawiera akcenty, a drugi wiersz znaki, do których należą. Jest uzyskiwany z danych wejściowych w następujący sposób ( Aoznacza dowolny znak):

  • Każdy \bar{A}otrzymuje Asię _na wierzchu.
  • Każdy \dot{A}otrzymuje Asię .na wierzchu.
  • Każdy \hat{A}otrzymuje Asię ^na wierzchu.
  • Do premii -10%: każdy \tilde{A}otrzymuje Asię ~na wierzchu.
  • Wszystkie pozostałe postacie mają spację nad nimi.

Na przykład dane wejściowe

Je suis pr\hat{e}t.

daje wynik

          ^
Je suis pret.

Zasady i punktacja

Można założyć, że postacie \{}występują tylko w makr \bar{}, \dot{}oraz \hat{}(a \tilde{}jeśli pójdziesz do premii). Wszystkie argumenty są dokładne makro długo jeden znak, więc \dot{foo}i \dot{}nie pojawią się w wejściu. Wynik może być ciągiem oddzielonym znakiem nowej linii lub listą / parą dwóch ciągów znaków. Dopuszczalna jest dowolna ilość końcowych i poprzedzających białych znaków, o ile akcenty znajdują się w odpowiednich miejscach. W szczególności, jeśli nie ma akcentów, wyjściem może być pojedynczy ciąg.

Możesz napisać pełny program lub funkcję. Wygrywa najniższa liczba bajtów (po bonusach), a standardowe luki są niedozwolone.

Przypadki testowe

Bez premii:

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

Z premią:

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
źródło
Zacząłem prototypować to w Go, ale potem zdałem sobie sprawę, o ile prostszy byłby Python ...
cat
1
Czy możemy założyć, że każdy wpis znaczników zawiera tylko jeden znak? Lub innymi słowy, czy jest \bar{foo}to poprawny wkład?
Peter Taylor
@PeterTaylor Tak, każdy argument makra ma dokładnie jeden znak. Wyjaśnię to.
Zgarb

Odpowiedzi:

4

Pyth, 51 46 45 43 41 40 bajtów

\Usuwam nawiasy klamrowe i dzielę na , podobnie jak odpowiedź CJam Reto Koradi. Kody bar, doti hatsą rozpoznawane po prostu przez ostatnią cyfrę dziesiętną kodu znaków pierwszego znaku, modulo 3. Po prostu dodać (RIP) do pierwszej części i usunąć go w końcu, aby zapisać kod do obsługi pierwszą część specjalnie .barf """"

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

Wypróbuj online. Zestaw testowy.

PurkkaKoodari
źródło
1
Więc po prostu dodaję barf... ” +1
Addison Crump
3

Julia, 204 184 bajtów * 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))

Jest to anonimowa funkcja, która akceptuje ciąg znaków i zwraca krotkę ciągów odpowiadającą górnej i dolnej linii. Górna linia będzie miała końcowe białe znaki. Aby wywołać funkcję, nadaj jej nazwę, npf=x->...

Nie golfowany:

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
Alex A.
źródło
2

CJam, 53 bajty

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

Wypróbuj online

Wyjaśnienie:

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.
Reto Koradi
źródło
1

Haskell, 156 * 0,9 = 140,4 bajtów

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

Przykład użycia:

*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`

Jak to działa: przejdź przez ciąg znaków wejściowych znak po znaku i zbuduj listę par znaków, lewy dla górnego ciągu wyjściowego, prawy dla dolnego ciągu wyjściowego. Jeśli \znaleziono a, weź odpowiedni akcent, w przeciwnym razie miejsce na lewy element. Na koniec przekształć listę par w pojedynczy ciąg.

nimi
źródło
0

Python 3, 203 bajty

Bez premii:

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

Naprawdę mam nadzieję, że jest krótsza wersja.

Alexander Nigl
źródło
1
Zawsze miło jest obserwować postęp liczenia bajtów. c: Sugeruję pozostawienie starego bajtu w górę, następnie otoczenie go <s></s>, a następnie wpisanie nowej liczby bajtów, abyśmy mogli zobaczyć kroki w kierunku zakończenia.
Addison Crump