Implementa le macro di accento LaTeX


11

introduzione

Il sistema di composizione tipografica LaTeX utilizza le macro per definire gli accenti. Ad esempio, la lettera ê è prodotta da \hat{e}. In questa sfida, il tuo compito è implementare una versione ASCII di questa funzionalità.

Ingresso

L'input è una stringa non vuota di caratteri ASCII stampabili. Non conterrà newline.

Produzione

L'output è una stringa composta da due righe. La prima riga contiene accenti e la seconda riga a cui appartengono i personaggi. Si ottiene dall'input come segue ( Aindica un carattere arbitrario):

  • Ogni \bar{A}è sostituito da Acon _sopra di esso.
  • Ogni \dot{A}è sostituito da Acon .sopra di esso.
  • Ogni \hat{A}è sostituito da Acon ^sopra di esso.
  • Per un bonus del -10%: ogni \tilde{A}è sostituito da Acon ~sopra di esso.
  • Tutti gli altri personaggi hanno uno spazio sopra di loro.

Ad esempio, l'input

Je suis pr\hat{e}t.

risulta nell'output

          ^
Je suis pret.

Regole e punteggio

Si può ipotizzare che i caratteri \{}si verificano solo nelle macro \bar{}, \dot{}e \hat{}(e \tilde{}se si va per il bonus). Tutti gli argomenti di macro sono esattamente lungo un carattere, in modo \dot{foo}e \dot{}non si verificano in ingresso. L'output può essere una stringa separata da una nuova riga o un elenco / coppia di due stringhe. È consentita qualsiasi quantità di spazio bianco finale e precedente, purché gli accenti si trovino nei punti corretti. In particolare, se non ci sono accenti, l'output può essere una singola stringa.

È possibile scrivere un programma completo o una funzione. Il conteggio dei byte più basso (dopo i bonus) vince e le scappatoie standard non sono ammesse.

Casi test

Senza bonus:

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 bonus:

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`

Ho iniziato a prototipare questo in Go, ma poi ho capito quanto sarebbe stato più semplice Python ...
cat

1
Possiamo supporre che ogni voce di markup contenga solo un carattere? O, in altre parole, è \bar{foo}un input valido?
Peter Taylor,

@PeterTaylor Sì, ogni argomento macro ha esattamente una lunghezza di un carattere. Lo chiarirò.
Zgarb,

Risposte:


4

Pyth, 51 46 45 43 41 40 byte

\Rimuovo le parentesi graffe e mi divido, proprio come fa la risposta CJam di Reto Koradi. I codici bar, dote hatsono riconosciuti semplicemente dall'ultima cifra decimale del codice carattere del primo carattere, modulo 3. Aggiungo semplicemente (RIP) alla prima parte e lo rimuovo alla fine per salvare il codice per la gestione della prima parte appositamente .barf """"

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

Provalo online. Suite di test.


1
" Quindi aggiungo solo barf... " +1
Addison Crump

3

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

Questa è una funzione anonima che accetta una stringa e restituisce una tupla di stringhe corrispondente alla riga superiore e inferiore. La riga superiore avrà spazi vuoti finali. Per chiamare la funzione, assegnagli un nome, ad esf=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 byte

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

Provalo online

Spiegazione:

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 byte

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

Esempio di utilizzo:

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

Come funziona: passa attraverso la stringa di input carattere per carattere e crea un elenco di coppie di caratteri, a sinistra per la stringa di output superiore, a destra per la stringa di output inferiore. Se \viene trovato un, prendi l'accento appropriato, altrimenti uno spazio per l'elemento sinistro. Trasforma infine l'elenco di coppie in una singola stringa.


0

Python 3, 203 byte

Senza bonus:

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

Spero davvero che ci sia una versione più breve.


1
È sempre bello vedere la progressione del conteggio dei byte. c: suggerisco di lasciare il vecchio conteggio dei byte in alto, quindi circondarlo <s></s>, quindi digitare il nuovo conteggio dei byte in modo da poter vedere i passi verso la concisione.
Addison Crump,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.