实现LaTeX口音宏


11

介绍

LaTeX排版系统使用宏来定义重音。例如,字母ê由产生\hat{e}。在这个挑战中,您的任务是实现此功能的ASCII版本。

输入值

您的输入是可打印的ASCII字符的非空字符串。它不会包含换行符。

输出量

您的输出是由两行组成的字符串。第一行包含重音符号,第二行包含重音符号。它是从输入中获得的,如下所示(A表示任意字符):

  • 每个\bar{A}被替换A_在它上面。
  • 每个\dot{A}被替换A.在它上面。
  • 每个\hat{A}被替换A^在它上面。
  • 对于10%的奖金:每一个\tilde{A}被替换A~在它上面。
  • 所有其他字符上方都有一个空格。

例如,输入

Je suis pr\hat{e}t.

结果输出

          ^
Je suis pret.

规则和计分

你可以假设字符\{}仅发生在宏\bar{}\dot{}\hat{}(和\tilde{}如果你去的奖金)。所有宏参数是准确的一个字符长,所以\dot{foo}\dot{}输入不会发生。输出可以是换行符分隔的字符串,也可以是两个字符串的列表/对。只要重音位于正确的位置,就可以允许任何数量的尾随和前导空格。特别是,如果没有重音,则输出可以是单个字符串。

您可以编写完整的程序或函数。最低字节数(奖金后)获胜,并且不允许出现标准漏洞。

测试用例

没有奖金:

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

有奖金:

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`

我开始在Go中对此进行原型设计,但是后来我意识到Python会简单得多……
2015年

1
我们可以假设每个标记条目仅包含一个字符吗?或者换句话说,是\bar{foo}有效输入吗?
彼得·泰勒

@PeterTaylor是的,每个宏参数都只有一个字符长。我会澄清这一点。
Zgarb 2015年

Answers:


4

Pyth,51 46 45 43 41 40字节

我删除花括号并在处拆分\,就像Reto Koradi的CJam答案一样。该代码bardothat通过第一个字符的字符代码的最后一个十进制数简单地认识到,模3.我只需要添加(RIP)的第一部分,并删除它到底保存代码,专门用于处理第一部分。barf """"

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

在线尝试。 测试套件。


1
那么我只是添加barf... ” +1
艾迪生·克伦普

3

利亚,204个 184字节×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))

这是一个匿名函数,它接受一个字符串并返回与顶行和底行相对应的字符串元组。第一行将包含尾随空格。要调用该函数,请为其命名,例如f=x->...

取消高尔夫:

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个字节

Sl+'\/(_,S*\@{(i2/49-"_. ^"=\3>'}-_,(S*@\+@@+@@+\}/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.

1

Haskell,156 * 0.9 = 140.4字节

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

用法示例:

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

工作原理:逐个字符地逐个输入字符串,并构建成对的字符列表,左侧为上方的输出字符串,右侧为下方的输出字符串。如果\找到a,则采用适当的重音符号,否则保留左侧元素的空格。最后,将对列表转换为单个字符串。


0

Python 3,203个字节

没有奖金:

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

我真的希望有一个较短的版本。


1
看到字节计数的进度总是很高兴。c:我建议保留旧字节数,然后将其包围起来<s></s>,然后键入新字节数,这样我们就可以看到简化的步骤。
Addison Crump 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.