Implementar macros de acentuação LaTeX

11

Introdução

O sistema tipográfico LaTeX usa macros para definir acentos. Por exemplo, a letra ê é produzida por \hat{e}. Nesse desafio, sua tarefa é implementar uma versão ASCII dessa funcionalidade.

Entrada

Sua entrada é uma sequência não vazia de caracteres ASCII imprimíveis. Não conterá novas linhas.

Resultado

Sua saída é uma sequência que consiste em duas linhas. A primeira linha contém acentos e a segunda linha os caracteres aos quais eles pertencem. É obtido da entrada da seguinte forma ( Adenota um caractere arbitrário):

  • Cada \bar{A}é substituído por Acom _em cima dela.
  • Cada \dot{A}é substituído por Acom .em cima dela.
  • Cada \hat{A}é substituído por Acom ^em cima dela.
  • Para um bônus -10%: todos \tilde{A}é substituído por Acom ~em cima dela.
  • Todos os outros caracteres têm um espaço acima deles.

Por exemplo, a entrada

Je suis pr\hat{e}t.

resulta na saída

          ^
Je suis pret.

Regras e pontuação

Você pode assumir que os personagens \{}só ocorrem nas macros \bar{}, \dot{}e \hat{}(e \tilde{}se você ir para o bônus). Todos os argumentos de macro têm exatamente um caractere, portanto, \dot{foo}e \dot{}não ocorrerão na entrada. A saída pode ser uma cadeia separada por nova linha ou uma lista / par de duas cadeias. Qualquer quantidade de espaço em branco à direita e anterior é permitida, desde que os acentos estejam nos lugares corretos. Em particular, se não houver acentos, a saída pode ser uma única sequência.

Você pode escrever um programa completo ou uma função. A menor contagem de bytes (após bônus) vence e as brechas padrão são proibidas.

Casos de teste

Sem bônus:

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

Com bônus:

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
fonte
Comecei a prototipar isso no Go, mas então percebi o quão mais simples seria o Python ... #
cat
1
Podemos supor que cada entrada de marcação contenha apenas um caractere? Ou, em outras palavras, é \bar{foo}uma entrada válida?
Peter Taylor
@ PeterTaylor Sim, todo argumento de macro tem exatamente um caractere. Eu vou esclarecer isso.
Zgarb

Respostas:

4

Pitão, 51 46 45 43 41 40 bytes

\Retiro o aparelho e paro, exatamente como a resposta CJam de Reto Koradi faz. Os códigos bar, dote hatsão reconhecidos apenas pelo último dígito decimal do código de caracteres do primeiro caractere, módulo 3. Eu só adicionar (RIP) para a primeira parte e removê-lo no final para salvar o código para lidar com a primeira parte, especialmente .barf """"

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

Experimente online. Suíte de teste.

PurkkaKoodari
fonte
1
" Então eu apenas adiciono 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))

Essa é uma função anônima que aceita uma sequência e retorna uma tupla de sequências correspondente às linhas superior e inferior. A linha superior terá espaços em branco à direita. Para chamar a função, dê um nome, por exemplof=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
Alex A.
fonte
2

CJam, 53 bytes

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

Experimente online

Explicação:

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

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

Como funciona: analise a sequência de caracteres de entrada por caractere e crie uma lista de pares de caracteres, o esquerdo para a sequência de saída superior e o direito para a sequência de saída inferior. Se a \for encontrado, use o sotaque apropriado, ou seja, um espaço para o elemento esquerdo. Por fim, transforme a lista de pares em uma única sequência.

nimi
fonte
0

Python 3, 203 bytes

Sem bônus:

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

Eu realmente espero que haja uma versão mais curta.

Alexander Nigl
fonte
1
É sempre bom ver a progressão da contagem de bytes. c: sugiro deixar a contagem de bytes antigos em cima, envolvê-la <s></s>e digitar a nova contagem de bytes, para que possamos ver os passos em direção à concisão.
Addison Crump