Implémenter des macros d'accent LaTeX

11

introduction

Le système de composition LaTeX utilise des macros pour définir les accents. Par exemple, la lettre ê est produite par \hat{e}. Dans ce défi, votre tâche consiste à implémenter une version ASCII de cette fonctionnalité.

Contribution

Votre entrée est une chaîne non vide de caractères ASCII imprimables. Il ne contiendra pas de nouvelles lignes.

Production

Votre sortie est une chaîne composée de deux lignes. La première ligne contient des accents et la deuxième ligne les caractères auxquels ils appartiennent. Il est obtenu à partir de l'entrée comme suit ( Adénote un caractère arbitraire):

  • Tout \bar{A}est remplacé par Apar _dessus.
  • Tout \dot{A}est remplacé par Apar .dessus.
  • Tout \hat{A}est remplacé par Apar ^dessus.
  • Pour un bonus de -10%: tout \tilde{A}est remplacé par Aavec ~en haut.
  • Tous les autres personnages ont un espace au-dessus d'eux.

Par exemple, l'entrée

Je suis pr\hat{e}t.

entraîne la sortie

          ^
Je suis pret.

Règles et notation

Vous pouvez supposer que les personnages \{}n'apparaissent que dans les macros \bar{}, \dot{}et \hat{}(et \tilde{}si vous optez pour le bonus). Tous les arguments de macro ont exactement un caractère \dot{foo}et \dot{}ne se produiront donc pas en entrée. La sortie peut être une chaîne séparée par des sauts de ligne ou une liste / paire de deux chaînes. N'importe quelle quantité d'espace blanc arrière et précédent est autorisée, tant que les accents sont aux bons endroits. En particulier, s'il n'y a pas d'accents, la sortie peut être une seule chaîne.

Vous pouvez écrire un programme complet ou une fonction. Le nombre d'octets le plus bas (après les bonus) gagne et les failles standard sont interdites.

Cas de test

Sans 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

Avec 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`
Zgarb
la source
J'ai commencé à créer un prototype dans Go, mais j'ai réalisé à quel point Python serait plus simple ...
cat
1
Pouvons-nous supposer que chaque entrée de balisage ne contient qu'un seul caractère? Ou, en d'autres termes, est-ce \bar{foo}une entrée valide?
Peter Taylor
@PeterTaylor Oui, chaque argument de macro contient exactement un caractère. Je vais clarifier cela.
Zgarb

Réponses:

4

Pyth, 51 46 45 43 41 40 octets

\J'enlève les accolades et je m'écarte, tout comme la réponse CJam de Reto Koradi. Les codes bar, dotet hatsont reconnus simplement par le dernier chiffre décimal du code de caractère du premier caractère, modulo 3. Je viens d'ajouter (RIP) à la première partie et de le supprimer à la fin pour enregistrer le code pour gérer la première partie spécialement .barf """"

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

Essayez-le en ligne. Suite de tests.

PurkkaKoodari
la source
1
" Alors j'ajoute juste barf... " +1
Addison Crump
3

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

Il s'agit d'une fonction anonyme qui accepte une chaîne et renvoie un tuple de chaînes correspondant aux lignes supérieure et inférieure. La ligne supérieure aura un espace de fin. Pour appeler la fonction, donnez-lui un nom, par exemplef=x->...

Non 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.
la source
2

CJam, 53 octets

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

Essayez-le en ligne

Explication:

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
la source
1

Haskell, 156 * 0,9 = 140,4 octets

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

Exemple d'utilisation:

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

Comment cela fonctionne: parcourez la chaîne d'entrée caractère par caractère et créez une liste de paires de caractères, la gauche pour la chaîne de sortie supérieure, la droite pour la chaîne de sortie inférieure. Si un \est trouvé, prenez l'accent approprié, sinon un espace pour l'élément gauche. Enfin, transformez la liste des paires en une seule chaîne.

nimi
la source
0

Python 3, 203 octets

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

J'espère vraiment qu'il existe une version plus courte.

Alexander Nigl
la source
1
C'est toujours agréable de voir la progression du nombre d'octets. c: Je suggère de laisser l'ancien décompte d'octets vers le haut, puis de l'entourer <s></s>, puis de taper le nouveau décompte d'octets afin que nous puissions voir les étapes vers la concision.
Addison Crump