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 에서 이것을 프로토 타입하기 시작 했지만 파이썬이 얼마나 간단한 지 깨달았습니다 ...
cat

1
각 마크 업 항목에 문자가 하나만 있다고 가정 할 수 있습니까? 즉, \bar{foo}유효한 입력입니까?
피터 테일러

@PeterTaylor 예, 모든 매크로 인수는 정확히 한 문자 길이입니다. 나는 그것을 명확히 할 것이다.
Zgarb

답변:


4

Pyth, 51 46 45 43 41 40 바이트

\Reto Koradi의 CJam 답변과 마찬가지로 중괄호를 제거하고에서 분할 합니다. 코드가 bar, dot그리고 hat첫 번째 문자의 문자 코드의 마지막 소수점 숫자로 간단하게 인식, 난 그냥 추가 3. 모듈로 (RIP) 첫 번째 부분에 특별히 첫 번째 부분을 처리하기위한 코드를 저장하기 위해 결국 제거 .barf """"

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

온라인으로 사용해보십시오. 테스트 스위트.


1
" 그리고 난 그냥 추가 barf... "+1
Addison Crump

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

하스켈, 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

파이썬 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>묶은 다음 새 바이트 수를 입력하여 결정 단계를 볼 수 있습니다.
애디슨 크럼프
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.