Implemente macros de acento LaTeX

11

Introducción

El sistema de composición tipográfica LaTeX utiliza macros para definir acentos. Por ejemplo, la letra ê es producida por \hat{e}. En este desafío, su tarea es implementar una versión ASCII de esta funcionalidad.

Entrada

Su entrada es una cadena no vacía de caracteres ASCII imprimibles. No contendrá nuevas líneas.

Salida

Su salida es una cadena que consta de dos líneas. La primera línea contiene acentos, y la segunda línea los caracteres a los que pertenecen. Se obtiene de la entrada de la siguiente manera ( Adenota un carácter arbitrario):

  • Cada \bar{A}se sustituye por Ala _encima de él.
  • Cada \dot{A}se sustituye por Ala .encima de él.
  • Cada \hat{A}se sustituye por Ala ^encima de él.
  • Para un bono -10%: todos \tilde{A}se sustituye por Ala ~encima de él.
  • Todos los demás personajes tienen un espacio por encima de ellos.

Por ejemplo, la entrada

Je suis pr\hat{e}t.

resultados en la salida

          ^
Je suis pret.

Reglas y puntaje

Se puede suponer que los personajes \{}sólo se producen en las macros \bar{}, \dot{}y \hat{}(y \tilde{}si vas para el bono). Todos los argumentos de la macro son exactamente un carácter de longitud, por lo que \dot{foo}y \dot{}no ocurrirán en la entrada. La salida puede ser una cadena separada por una nueva línea, o una lista / par de dos cadenas. Se permite cualquier cantidad de espacios en blanco finales y anteriores, siempre que los acentos estén en los lugares correctos. En particular, si no hay acentos, la salida puede ser una sola cadena.

Puede escribir un programa completo o una función. El conteo de bytes más bajo (después de los bonos) gana, y las lagunas estándar no se permiten.

Casos de prueba

Sin bonificación:

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

Con bonificación:

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
fuente
Empecé a prototipo esto en Go , pero luego me di cuenta de lo mucho más simple sería Python ...
gato
1
¿Podemos suponer que cada entrada de marcado contiene solo un carácter? O, en otras palabras, ¿es \bar{foo}una entrada válida?
Peter Taylor
@PeterTaylor Sí, cada argumento macro tiene exactamente un carácter. Lo aclararé.
Zgarb

Respuestas:

4

Pyth, 51 46 45 43 41 40 bytes

Quito las llaves y dividida en \, al igual que la respuesta de Cjam Reto Koradi hace. Los códigos bar, doty hatse reconocen simplemente por el último dígito decimal del código de caracteres del primer carácter, módulo 3. Solo agrego (RIP) a la primera parte y lo elimino al final para guardar el código para manejar la primera parte especialmente .barf """"

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

Pruébalo en línea. Banco de pruebas.

PurkkaKoodari
fuente
1
" Entonces solo agrego barf... " +1
Addison Crump
3

Julia, 204 184 bytes * 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))

Esta es una función anónima que acepta una cadena y devuelve una tupla de cadenas correspondientes a las líneas superior e inferior. La línea superior tendrá espacios en blanco al final. Para llamar a la función, asígnele un nombre, p. Ej.f=x->...

Sin golf:

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

CJam, 53 bytes

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

Pruébalo en línea

Explicació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.
Reto Koradi
fuente
1

Haskell, 156 * 0.9 = 140.4 bytes

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

Ejemplo de uso:

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

Cómo funciona: revise la cadena de entrada carácter por carácter y construya una lista de pares de caracteres, la izquierda para la cadena de salida superior, la derecha para la cadena de salida inferior. Si \se encuentra un, tome el acento apropiado, de lo contrario, un espacio para el elemento izquierdo. Finalmente, transforma la lista de pares en una sola cadena.

nimi
fuente
0

Python 3, 203 bytes

Sin bonificación:

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

Realmente espero que haya una versión más corta.

Alexander Nigl
fuente
1
Siempre es agradable ver la progresión del recuento de bytes. c: sugiero dejar el conteo de bytes anterior, luego rodearlo y <s></s>luego escribir el conteo de bytes nuevo para que podamos ver los pasos hacia la concisión.
Addison Crump