Texto bifurcado

26

Dada uma sequência de letras ASCII (maiúsculas e / ou minúsculas), imprima o MathJax bruto necessário para exibir essa sequência bifurcada em cada caractere, em sobrescritos e subscritos. Por exemplo, as entradas cate horseresultariam em saídas que o MathJax renderiza da seguinte forma, respectivamente:

imagem de gato bifurcando imagem de cavalo bifurcando

Observe que apenas uma entrada é necessária para ser obtida - essas duas são listadas lado a lado simplesmente para economizar espaço vertical.

Significado de marcação

  • _ indica um subscrito.
  • ^ indica um sobrescrito.
  • As chaves são necessárias em torno de substrings sobrescritos ou sobrescritos que contêm mais sobrescritos ou sobrescritos, a fim de impedir que todos eles estejam no mesmo nível.

Casos de teste

Os casos de teste estão no formato input : output. O primeiro caso de teste mostra a cadeia vazia, pois a entrada deve resultar na cadeia vazia como saída.

"" : ""
"a" : "a"
"me" : "m_e^e"
"cat" : "c_{a_t^t}^{a_t^t}"
"frog" : "f_{r_{o_g^g}^{o_g^g}}^{r_{o_g^g}^{o_g^g}}"
"horse" : "h_{o_{r_{s_e^e}^{s_e^e}}^{r_{s_e^e}^{s_e^e}}}^{o_{r_{s_e^e}^{s_e^e}}^{r_{s_e^e}^{s_e^e}}}"
"bifurcate" : "b_{i_{f_{u_{r_{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}^{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}}^{r_{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}^{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}}}^{u_{r_{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}^{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}}^{r_{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}^{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}}}}^{f_{u_{r_{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}^{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}}^{r_{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}^{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}}}^{u_{r_{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}^{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}}^{r_{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}^{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}}}}}^{i_{f_{u_{r_{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}^{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}}^{r_{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}^{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}}}^{u_{r_{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}^{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}}^{r_{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}^{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}}}}^{f_{u_{r_{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}^{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}}^{r_{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}^{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}}}^{u_{r_{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}^{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}}^{r_{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}^{c_{a_{t_e^e}^{t_e^e}}^{a_{t_e^e}^{t_e^e}}}}}}}"

Você pode ver como eles são renderizados colando a saída em mathurl.com .

Sem chaves redundantes

Felizmente, o MathJax renderiza marcações com chaves redundantes. Por exemplo, o seguinte será todos parecem idênticos quando renderizado: a, {a}, {}{a}, {{{{a}}}}.

No entanto, a saída válida para esse desafio não possui chaves redundantes. Observe em particular que caracteres únicos na saída não são cercados por chaves.

Ordem

A ordem do subscrito e do sobrescrito não é importante. A seguir, são equivalentes e serão indistinguíveis quando renderizados (e são todos igualmente válidos):

c_{a_t^t}^{a_t^t}
c_{a^t_t}^{a_t^t}
c_{a_t^t}^{a^t_t}
c_{a^t_t}^{a^t_t}
c^{a_t^t}_{a_t^t}
c^{a^t_t}_{a_t^t}
c^{a_t^t}_{a^t_t}
c^{a^t_t}_{a^t_t}

Pontuação

Para cada idioma, o vencedor é o código mais curto em bytes.

Muitas notificações? Digite </sub>para cancelar a inscrição

Trichoplax
fonte
Muitas notificações? Digite </sub>para cancelar a inscrição hein, quem disse que eu quero cancelar a inscrição ou algo assim? Foi um teste para ver se eu li o post inteiro certo?
Erik the Outgolfer
12
@EriktheOutgolfer não, era apenas uma piada muito ruim.
Trichoplax
Podemos apenas exibir o resultado do pdf compilado? Eu gostaria de escrever uma resposta pura do látex.
Assistente de trigo
@ WheatWizard que soa como um desafio diferente. Não seria válido como resposta aqui.
Trichoplax

Respostas:

10

Python, 95 90 86 92 82 bytes

10 bytes salvos graças a @ConnerJohnston

f=lambda s:s and s[0]+(s[1:]and'_{0}^{0}'.format(s[2:]and'{'+f(s[1:])+'}'or s[1]))

Experimente online!

Uriel
fonte
4
Uau, isso é uma recursão louca.
Mr. Xcoder
1
Alguma formatação de string para 81 bytes (ainda não sabe como vincular o TIO nos comentários): f = lambda s: se [0] + '_ {0} ^ {0}'. Format (s [2:] e ' {'+ f (s [1:]) +'} 'ou s [1:] e s [1])
Conner Johnston
1
@ConnerJohnston thanks! você pode colocar tio ligações com [text](link), mas isso é realmente estragar;)
Uriel
1
79 bytes ; e suponho que você não deseja usar o truque da função anônima, mas economizaria 2 bytes.
Jonathan Frech
7

Mathematica, 72 84 77 76 bytes

a_±b__:={"{",a,"_",±b,"^",±b,"}"};±(a_:""):={"",a,""};""<>Most@Rest@±##&@@#&

Usa a codificação CP-1252 (Windows). Leva uma lista de caracteres como entrada.

Explicação

a_±b__:=

Defina a função ±, com 2 ou mais argumentos. Rotule o primeiro argumento a, e o segundo e depois b.

{"{",a,"_",±b,"^",±b,"}"}

Crie um Listequivalente a "{a_±b^±b}"( ±bé avaliado novamente, recursivamente).

±(a_:""):= ...

Defina a função ±, com 1 ou 0 argumentos. Rotule o primeiro argumento a, se existir, e atribua-o ""ao acontrário.

{"",a,""}

Crie um Listequivalente a "a", preenchido com Strings vazios .

""<>Most@Rest@±##&@@#&

Uma função pura que se aplica ±à entrada, descarta o primeiro e o último elemento e converte Listem String.

JungHwan Min
fonte
7

CJam (35 bytes)

MqW%{"^{ }_{ }"{AW$,)3e<#<},S/@*+}/

Este é um programa completo. Demonstração online .

3 bytes solucionam um erro no intérprete (veja abaixo).

Dissecação

M            e# Start building from the empty string
qW%{         e# For each character in the reversed input
  "^{ }_{ }" e#   Take a template
  {          e#   If the accumulator is of length n, remove all characters whose
    A        e#   codepoints are greater than pow(10,
    W$,)3e<  e#                                   min(n+1, 3))
    #<       e#   When the accumulator is the empty string, that's all of them.
  },         e#   When the accumulator is one character, that's {}
             e#   When the accumulator is any longer, it's none of them.
  S/@*       e#   Substitute the accumulator for the spaces.
  +          e#   Append to the new character.
}/

Observe que o min(n+1, 3)objetivo é solucionar um erro no intérprete: deve haver algum padrão nos poderes de 10 que '}seja menor que, mas não é óbvio .

Peter Taylor
fonte
Não parece funcionar para a sequência vazia (primeiro caso de teste).
Trichoplax
1
@trichoplax, isso foi devido a uma diferença sutil entre GolfScript e CJam, que ocasionalmente me chama a atenção. Agora corrigido ao custo de apenas um byte, tornando o código muito mais inteligente do que era anteriormente.
22416 Peter
Funciona perfeitamente agora. Ótima explicação.
Trichoplax
@PeterTaylor (Pelo menos na demonstração online) Ele não funciona para palavras com mais de quatro letras.
dessert
2
@dessert, isso é muito estranho e definitivamente merece um relatório de erro contra o intérprete. Eu adicionei uma solução alternativa a um custo de 3 bytes.
Peter Taylor
7

JavaScript (ES6), 57 55 bytes

f=([c,...s])=>s+s?c+`_${p=s[1]?`{${f(s)}}`:s}^`+p:c||''

Complexity (len) complexidade! De acordo com @PeterTaylor, este é realmente Θ (2 ^ len (s)), que ainda é o melhor possível ...

ETHproductions
fonte
Não parece funcionar para a sequência vazia (primeiro caso de teste).
Trichoplax
@trichoplax Deve ser corrigido agora.
ETHproductions
Funciona perfeitamente agora.
Trichoplax
1
O que é n no seu O (n)? Presumo que seja o comprimento da saída, mas a menos que você indique que é interpretado por padrão como sendo o comprimento da entrada, e como o comprimento da saída é exponencial no comprimento da entrada, é impossível implementar em tempo polinomial.
Peter Taylor
@PeterTaylor Eu tinha imaginado que, como o algoritmo apenas executa etapas len (entrada), que a complexidade é len (entrada) ... se isso não estiver correto, eu o removerei do post, pois não sei como calculá-lo, a menos que você saiba qual é a complexidade correta.
ETHproductions
6

Haskell , 71 bytes

f[x,y]=x:'_':y:'^':y:[]
f(x:y@(_:_))=x:"_{"++f y++"}^{"++f y++"}"
f x=x

Experimente online!

Se tivéssemos que gerar um código válido, o seguinte funcionaria para 44 bytes:

f[a]=[a]
f(a:b)=a:"_{"++f b++"}^{"++f b++"}"

Experimente online!

Assistente de Trigo
fonte
2
-5 bytes, com base na versão de 44 bytes: Experimente online!
jferard
@jferard Nice! Vou adicionar isso ao post.
Assistente de trigo
66 bytes: Experimente online!
Laikoni
63 bytes: Experimente online!
Laikoni
59 bytes: Experimente online!
Laikoni
5

SOGL V0.12 , 21 bytes

±K;{╔+;lH?"{ŗ}”}1 ^Ο+

Experimente aqui!

Explicação:

±                      reverse the string
 K                     take off the first letter - will slowly convert to the output
  ;                    get the rest of the string ontop
   {                   iterate over the rest of the characters
    ╔+                   append "_" to it
      ;                  get the output string ontop
       lH?     }         if it's length - 1 [isn't 0]
          "{ŗ}”            push the string "{ŗ}" where ŗ is replaced by the output string
                1 ^Ο     wrap "^" around with the output string
                    +    prepend to it the current character + "_"
dzaima
fonte
5

Perl 5 , 54 + 1 (-p) = 55 bytes

s/\{(.)\}/$1/g while s/([a-z])([a-z]+)/$1_{$2}^{$2}/ig

Experimente online!

Quão?

A substituição na condição while quebra ocorrências de várias letras na primeira letra, seguidas pelo restante entre chaves assim:

abc -> a_{bc}^{bc}

O loop while executa a substituição até que não haja mais seqüências de várias letras. A substituição dentro do loop remove chaves de cerca de uma letra.

Xcali
fonte
Bom, eu estava me perguntando quanto tempo levaria para uma resposta regex para aparecer
Nnnes
4

Ruby , 76 73 72 68 67 57 bytes

Uso de lambda economizando 4 bytes graças a Tutleman

f=->s{(r=s[1..-1])[0]?s[0]+?_+[r[1]??{+f[r]+?}:r]*2*?^:s}

Experimente online!

Ungolfed:

def f(s)
  r = s[1..-1]
  if r.size > 0
    if r.size > 1
      x = "{" + f(r) + "}"
    else
      x = r
    end
    return s[0] + "_" + [x, x].join("^")
  else
    return s
  end
end
Nnnes
fonte
Em vez de uma função, use uma lambda anônima (por exemplo ->s{...}), que economiza 7 bytes. Em seguida, você pode salvar mais 2 bytes substituindo "#{s[0]}_por s[0]+"_. Você pode salvar mais um byte, atribuindo inline '{}'a uma variável na primeira vez que o usar.
Tutleman
@Tutleman É recursivo ( t=f s[1..-1]), então não acho que uma função anônima funcione e já reorganizei o início da string, mas posso usar a atribuição em linha.
Nnnes
1
D'oh! Opa - não acredito que perdi isso. De qualquer forma, ainda é mais curto usar um lambda (nomeado): f=->s{...}economiza 4 bytes, mesmo considerando o extra []necessário ao fazer a chamada recursiva.
Tutleman
@ Tutleman Ah, sim, mudou. Agora, se eu posso vir acima algo melhor do que .trbagunça ...
Nnnes
1

Pitão , 47 bytes

Ljk[hb|&ttbs[\_\{ytb"}^{"ytb\})&tbs[\_htb\^htb;

Experimente online!

Esta é praticamente uma porta direta da resposta Python do @ Uriel. Indo para o golfe daqui a pouco.

Arnold Palmer
fonte
1

PHP, 121 bytes

function b($s){return $s[0].($s[1]?'_'.($s[2]?'{'.($b=b(substr($s,1))).'}^{'.$b.'}':"$s[1]^$s[1]"):'');}echo b($argv[1]);

A função em si é de 104 bytes e mostra um aviso do PHP.

jstnthms
fonte
1

Retina , 43 bytes

(.)(.)$
$1¶$2
+`(.)¶(.*)
¶{$1_$2^$2}
¶{|}$

Experimente online! O link inclui casos de teste. Explicação:

(.)(.)$
$1¶$2

Faça a bola rolar cortando o último personagem. (Mas se for o único personagem, eles o deixam em paz.)

+`(.)¶(.*)
¶{$1_$2^$2}

Mova o caractere back um passo de cada vez, obtendo o resultado anterior e tornando-o um subscrito e sobrescrito do próximo caractere.

¶{|}$

Remova o red agora redundante e o exterior {} s.

Neil
fonte
0

Javascript, 73 bytes

s=>[...s].reduceRight((m,c)=>`${c}_{${m}}^{${m}}`).replace(/{(.)}/g,'$1')

Explicação

s=>                                  // take the input string
    [...s]                           // split the string into an array
    .reduceRight(                    // reduce the array in reverse order
        (m,c)=>`${c}_{${m}}^{${m}}`  // storing the result of each iteration in the memo m
    )                                // and returning m at the end
    .replace(/{(.)}/g,'$1')          // replace redundant {}

Como não há um valor inicial especificado de m, reduceRightassume o último elemento scomo o valor inicial e começa a iterar no índice s.length-2.

asgallant
fonte
s=>[...s].reduceRight((m,c)=>`{${c}_${m}^${m}}`).slice(1,-1)tem apenas 60 bytes.
Neil
Não parece funcionar para a sequência vazia (primeiro caso de teste).
Trichoplax