Parênteses em notas de rodapé

29

fundo

Programadores LISP conquistaram o mundo! Os parênteses foram declarados como caracteres sagrados e, a partir de agora, só podem ser usados ​​em programas LISP. Foi decidido que os parênteses nas obras literárias serão substituídos por notas de rodapé, e é seu trabalho automatizar isso para o texto Markdown simplificado.

Entrada

Sua entrada é uma única sequência que contém caracteres ASCII alfabéticos, espaços e caracteres especiais ,.!?(). Não conterá novas linhas ou dígitos. Os parênteses serão correspondidos corretamente.

Saída

Você deve converter cada par de parênteses correspondente na sequência de entrada em uma nota de rodapé. Isso acontece da seguinte maneira:

  1. Substitua o primeiro par correspondente de parênteses e a substring entre eles por um número em execução que começa em 1, entre as tags Markdown <sup>e </sup>.
  2. Anexar ao final da string
    • duas novas linhas,
    • a tag Markdown <sub>,
    • o número da etapa 1,
    • um espaço,
    • a substring entre parênteses e
    • a tag de fechamento </sub>, nesta ordem.
  3. Se ainda houver parênteses na sequência, vá para a etapa 1.

Sua saída é a sequência resultante, possivelmente com uma nova linha à direita. Você não precisa implementar esse algoritmo exato, desde que sua saída esteja correta. Observe que pode haver parênteses aninhados; nesse caso, teremos notas de rodapé que contêm referências a outras notas de rodapé. A substring entre parênteses também pode estar vazia. Veja os casos de teste abaixo para exemplos.

Regras e Pontuação

Você pode escrever um programa completo ou uma função. A menor contagem de bytes vence e as brechas padrão não são permitidas.

Se o seu idioma não suporta nativamente números decimais ( tosse Retina tosse ), você pode dar os números nota de rodapé na outra base, incluindo binários ou unário; no entanto, o uso de números unários impõe uma penalidade de + 20% .

Casos de teste

Entrada:

This input contains no parentheses.

Saída:

This input contains no parentheses.

Entrada:

This has (some) parentheses (but not so many).

Saída:

This has <sup>1</sup> parentheses <sup>2</sup>.

<sub>1 some</sub>

<sub>2 but not so many</sub>

Entrada:

This has (nested (deeply (or highly?) nested)) parentheses (and several groups).

Saída:

This has <sup>1</sup> parentheses <sup>2</sup>.

<sub>1 nested <sup>3</sup></sub>

<sub>2 and several groups</sub>

<sub>3 deeply <sup>4</sup> nested</sub>

<sub>4 or highly?</sub>

Entrada:

Hmm()(()(,))  a()((trt)(v( (((((wut)))))(X)(Y)(Z) )!?!?!?!))oooooooo(oooo)oooo

Saída:

Hmm<sup>1</sup><sup>2</sup>  a<sup>3</sup><sup>4</sup>oooooooo<sup>5</sup>oooo

<sub>1 </sub>

<sub>2 <sup>6</sup><sup>7</sup></sub>

<sub>3 </sub>

<sub>4 <sup>8</sup><sup>9</sup></sub>

<sub>5 oooo</sub>

<sub>6 </sub>

<sub>7 ,</sub>

<sub>8 trt</sub>

<sub>9 v<sup>10</sup>!?!?!?!</sub>

<sub>10  <sup>11</sup><sup>12</sup><sup>13</sup><sup>14</sup> </sub>

<sub>11 <sup>15</sup></sub>

<sub>12 X</sub>

<sub>13 Y</sub>

<sub>14 Z</sub>

<sub>15 <sup>16</sup></sub>

<sub>16 <sup>17</sup></sub>

<sub>17 <sup>18</sup></sub>

<sub>18 wut</sub>

Observe as linhas vazias entre as notas de rodapé.

Zgarb
fonte
23
Meu programa pode conter parênteses, mesmo que não esteja escrito em Lisp ou isso seja uma ofensa punível agora?
Martin Ender
16
@ MartinBüttner Parênteses em programas não-LISP são relutantemente permitidos, desde que sejam usados ​​para um bem maior, como converter outros parênteses em notas de rodapé.
Zgarb 15/09/2015
A entrada pode ter várias linhas? Nesse caso, as notas de rodapé devem ser colocadas após cada linha ou no final? Por exemplo, para que serve a saída foo (bar)\nfoot (note)?
Xebtl # 16/15
@xebtl A entrada é sempre uma única linha. Consulte a seção Entrada : "Não conterá novas linhas ou dígitos".
Zgarb 16/09/2015
2
:( @ esta especificação numerando notas de rodapé em primeiro lugar em vez de profundidade primeiro
Sparr

Respostas:

10

Perl, 81 75 72 bytes

Código de 71 bytes + argumento de linha de comando de 1 byte.

Requer Perl 5.10 ou mais recente (para suporte regex recursivo)

$i++;s#(\((((?1)|.)*?)\))(.*)#<sup>$i</sup>$4

<sub>$i $2</sub>#s&&redo

Uso:

perl -p entry.pl input.txt

Explicação

-p O parâmetro imprimirá o resultado da aplicação dos comandos fornecidos à entrada, evitando a necessidade de uma impressão explícita.

O regex (\(((?1)|.)*?)\))está procurando o conjunto mais externo de colchetes desde o início da string. Quando isso é encontrado, realizamos a substituição, garantindo que apenas adicionemos o valor no final da entrada (capturando tudo até o final da entrada usando (.*)).

Em seguida, repetimos a substituição de regex na cadeia agora substituída usando redo, que aplicará continuamente a substituição de regex até que não corresponda mais. O smodificador garante que o .no regex corresponda a novas linhas, o que é necessário porque reaplicamos o correspondente no resultado da substituição anterior do regex.

Jarmex
fonte
11
Você pode se safar com [^)] ou até em .vez de [^()]garantir que a entrada será equilibrada corretamente.
Martin Ender
+1 por me apresentar regexes recursivas :-). Mas, em uma leitura estrita do desafio, isso está incorreto: se a sequência contiver novas linhas, as notas de rodapé serão colocadas após cada linha, e não no final. (Veja o meu pedido de esclarecimento acima.)
xebtl
Bom ponto @ MartinBüttner - podemos nos safar .tornando a partida preguiçosa. @xebtl, o desafio declara "Ele não conterá novas linhas ou dígitos"
Jarmex 16/09/2015
12

Emacs Lisp, 335 bytes

Prefácio. Esta resposta e as do esquema são atualmente as únicas respostas oficialmente sancionadas pela República Popular do Poder da LISP e pela Igreja de Emacs. Outras respostas, mais curtas ou não, são consideradas uma ameaça à paz. Em particular, e com um profundo desdém a qualquer alegação difamatória de McCarthyism que é esporadicamente ouvida por oponentes hostis do estado, pedimos a qualquer pessoa que tenha informações sobre a verdadeira identidade dos autores anônimos que escrevem respostas do Nonlisp para entrar em contato com o Escritório local. Lembramos que todos devem dedicar tempo para refletir e votar de acordo com o que ele ou ela acredita profundamente que não ameaçará suas futuras interações com representantes oficiais do poder em vigor. Código é dados. Dados são código.

(defun p()(let(b(cpt 0)n)(goto-char 0)(while(search-forward"("()t)(setf b(point)n(number-to-string(incf cpt)))(backward-char)(forward-sexp)(backward-char)(kill-region b(point))(delete-backward-char 1)(delete-forward-char 1)(insert "<sup>"n"</sup>")(save-excursion(end-of-buffer)(newline 2)(insert "<sub>"n" ")(yank)(insert"</sub>")))))

Mais elegantemente:

(defun parens ()
  (let (b(cpt 0)n)
    (goto-char 0)
    (while(search-forward"("()t)
      (setf b(point)n(number-to-string(incf cpt)))
      (backward-char)
      (forward-sexp)
      (backward-char)
      (kill-region b(point))
      (delete-backward-char 1)
      (delete-forward-char 1)
      (insert "<sup>"n"</sup>")
      (save-excursion
       (end-of-buffer)
       (newline 2)
       (insert "<sub>"n" ")
       (yank)
       (insert "</sub>")))))
coredump
fonte
9

Retina , 96 86 83 bytes * 120% = 99,6

O código fonte desta solução consiste em dois arquivos:

+s`\((((\()|(?<-3>\))|[^)])*).(.*)(?<=(1+).*?)?
<sup>1$5</sup>$4

<sub>1$5 $1</sub>

Explicação

Esta é uma implementação muito direta do algoritmo, conforme descrito no desafio. O código consiste em uma única substituição de regex que transforma o primeiro conjunto de parênteses em uma nota de rodapé. Essa substituição é repetida +até que a string pare de mudar, o que aqui significa que o regex não corresponde mais (porque não consegue encontrar mais parênteses).

As notas de rodapé são enumeradas em unário, para que eu possa simplesmente procurar o número da última nota de rodapé e anexar a 1para criar o próximo.

O regex para encontrar o primeiro conjunto de parênteses é baseado na técnica padrão de correspondência entre parênteses e grupos de balanceamento (hrhr, "parênteses correspondentes"). Foi reduzido um pouco usando um grupo sem nome e assumindo que os parênteses estão corretamente balanceados (o que significa que podemos omitir o (da classe de caractere negado e combinar a final )com um simples .e também não precisamos garantir que o parâmetro pilha de captura está vazia).

Depois de combinar os parênteses e capturar seu conteúdo em grupo 1, capturamos o restante da sequência com (.*)em grupo 4e, em seguida, pesquisamos novamente na sequência o primeiro conjunto de 1s com um olhar negativo para trás. Se encontrarmos uma substring, armazenamos em grupo 5. Se não o fizermos, observamos falhas, mas tudo bem porque é opcional - significa apenas que $5fornecerá uma string vazia, que é a representação unária 0e que também está correta.

A sequência de substituição simplesmente reúne tudo com base nos grupos de captura. O número da nota de rodapé é incrementado acrescentando 1a ao último número com 1$5.

Martin Ender
fonte
3
Retina está em uma série de vitórias!
orlp 15/09/2015
@orlp Ou é? ;) Grupos de equilíbrio não são compatíveis com regex recursiva. Isso e não ser capaz de lidar com números decimais ...
Martin Ender
Hora de roubar o invólucro do PHP e implementar o Retina em torno do PCRE:
ǹ̷̰ĥ̷̳h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Normalmente, eu prefiro ter grupos de equilíbrio do que recursão, mas há alguns casos em que o último é mais conciso. Talvez um dia eu reimplementarei o sabor do regex .NET para Retina e aplique alguns recursos adicionais. ;)
Martin Ender
9

JavaScript sagrado , 1510 bytes

Colegas rebeldes, não cedam à demolição tirânica dos parênteses! Você deve perseverar! Desde o início, a programação tem sido uma empresa livre. Agora, tornou-se uma demonstração permeada de piedade. Não devemos mostrar nada menos que medo absoluto. Portanto, eu lutei de volta!

    ( )( (((  ((  )( )  (( ))( )) (( ( ((  ) ( ()( ) (( ) )(( ((( ()((( ) ( ) )((  ) (((((( )( (())((  ) ) )( ()(( ((()((()   ( (  (  ( )) ((  )( ) (( ) )((((  ( () ) )( ( ()(( )( () ((( )(( ) )( ()((( ) ( )  ( )() (((( () ) (((( () ) ((() ) ()  ( (  (  ( )) ( )(  ((((( )) ((  )( ) (( ) )((((  ) )  ()(  ((() ( ()(( ) ( ) )(( ))(((  (( ) ((  ) ( ()(( )( ) ()  ( (  (  ( ()( ) )( ()(  ) ()  ( (  (  ( )( (( ( (( )  ((((( ))  ) )(( )) ((  )( ) (( ) )((((  ) ()( ))  ) ) (( )( () (((   ( ) )((  )( )(((( ))( )() ) ()( ))  (()( (()( ((()((()   ( (  (    (  ( )) ( )(  (((((( )(( ( (( )) ( ((  ) )( ) )( ( )( ((() ( )( ((() ( ()( ()( ()   ) )( ()(( ) ()  ( (  (    (  ( )) ( )(  (((((( )(( ( (( )) ( ((  ) )( ) )( ( )( (((( ( )( ((() ( ()( ()( (()( ) )( ()(( ) ()  ( (  (    (  ( )) ( )(  (((( ( ) ( ()( ((() ( ()( ())(( ) ( ) )( ()(( ))) ) ()  ( (  (  ((())  ( (  (  ((( ( ) )((( )( () ((( )(((   ( )) ( )  ( ) ) ((((( )) ((  )( ) (( ) )((((  (())( ))  (()( ()(( ((()  ( (  (  ( )(  ) )(((( ( () ((( ) ( ) )(( ((((   ( ()(( )  ( ) ) (((( () )( ((( ((((((()( ((() ((   () )( )(( (()) ( )( ( )( ((() ) ()  ( (  (  (( ) ( ) )(( ))(((  (( ) ((  ) ( ()( ) (( ) )(( ((( ()((( ) ( ) )((  ) (((((( )( () ((( ) ( ) )(( ((((   ( ()(( )  ( ) ) ((((((( ( (()) ( )( ) ) (( )((((  ( ()) ) )) ( )( (()(((  ) (()( ( )( ) )  () )(( )((((  ( ()) ) )) ( )( ((() (()( ( )(  ( (  ( ( ) ) (( )((((  ( ()) ) )) ( )( (()(((  ) (()( ( )( ( () ( )( (()(( )(  (()( ( )( ) )  () )(( )((((  ( ()) ) )) ( )( (())((  ) (()( ()(( ((() ) ()  ( (((())

Não há regras contra o uso de caracteres sagrados em uma linguagem não Lisp. Não, de jeito nenhum. (De uma forma um pouco menos compacta :)

( )( (((  ((  )( )  (( ))( )) (( ( ((  ) ( ()( ) (( ) )(( ((( ()((( ) 
( ) )((  ) (((((( )( (())((  ) ) )( ()(( ((()((()   ( (  (  ( )) ((  )
( ) (( ) )((((  ( () ) )( ( ()(( )( () ((( )(( ) )( ()((( ) ( )  ( )()
 (((( () ) (((( () ) ((() ) ()  ( (  (  ( )) ( )(  ((((( )) ((  )( ) (
( ) )((((  ) )  ()(  ((() ( ()(( ) ( ) )(( ))(((  (( ) ((  ) ( ()(( )(
 ) ()  ( (  (  ( ()( ) )( ()(  ) ()  ( (  (  ( )( (( ( (( )  ((((( )) 
 ) )(( )) ((  )( ) (( ) )((((  ) ()( ))  ) ) (( )( () (((   ( ) )((  )
( )(((( ))( )() ) ()( ))  (()( (()( ((()((()   ( (  (    (  ( )) ( )( 
 (((((( )(( ( (( )) ( ((  ) )( ) )( ( )( ((() ( )( ((() ( ()( ()( ()  
 ) )( ()(( ) ()  ( (  (    (  ( )) ( )(  (((((( )(( ( (( )) ( ((  ) )(
 ) )( ( )( (((( ( )( ((() ( ()( ()( (()( ) )( ()(( ) ()  ( (  (    (  
( )) ( )(  (((( ( ) ( ()( ((() ( ()( ())(( ) ( ) )( ()(( ))) ) ()  ( (
  (  ((())  ( (  (  ((( ( ) )((( )( () ((( )(((   ( )) ( )  ( ) ) ((((
( )) ((  )( ) (( ) )((((  (())( ))  (()( ()(( ((()  ( (  (  ( )(  ) )(
((( ( () ((( ) ( ) )(( ((((   ( ()(( )  ( ) ) (((( () )( ((( ((((((()(
 ((() ((   () )( )(( (()) ( )( ( )( ((() ) ()  ( (  (  (( ) ( ) )(( ))
(((  (( ) ((  ) ( ()( ) (( ) )(( ((( ()((( ) ( ) )((  ) (((((( )( () (
(( ) ( ) )(( ((((   ( ()(( )  ( ) ) ((((((( ( (()) ( )( ) ) (( )((((  
( ()) ) )) ( )( (()(((  ) (()( ( )( ) )  () )(( )((((  ( ()) ) )) ( )(
 ((() (()( ( )(  ( (  ( ( ) ) (( )((((  ( ()) ) )) ( )( (()(((  ) (()(
 ( )( ( () ( )( (()(( )(  (()( ( )( ) )  () )(( )((((  ( ()) ) )) ( )(
 (())((  ) (()( ()(( ((() ) ()  ( (((())

Isso compila o JavaScript expandido na minha outra resposta . Esta é uma submissão de piada.

Conor O'Brien
fonte
5

Lua, 222 216 204 201 bytes

Golfe:

s=io.read()g="%b()"c=1k=string l=k.find t=k.sub o=k.format a,b=l(s,g)while a do s=t(s,0,a-1)..o("<sup>%d</sup>",c)..t(s,b+1,#s).."\n\n"..o("<sub>%d %s</sub>",c,t(s,a+1,b-1))c=c+1 a,b=l(s,g)end print(s)

Ungolfed:

input=io.read() 
inputFormat="<sup>%d</sup>"
footnoteFormat="<sub>%d %s</sub>"
counter=1
a,b=string.find(input,"%b()")
while a do
    current=string.sub(input,a+1,b-1)
    input=input.."\n\n"..string.format(footnoteFormat, counter, current) 
    input=string.sub(input,0,a-1)..string.format(inputFormat, counter)..string.sub(input,b+1,#input)
    counter=counter+1
    a,b=string.find(input,"%b()")
end

print(input)
Nikolai97
fonte
um repeat a,b=l(s,g) ... untill a<1loop não seria mais curto que o seu tempo?
Katenkyo
4

Esquema, 92 bytes

Frustrados com a implementação da busca pela primeira vez no Real Lisp, 1 os futuros poderes decidem adotar uma abordagem mais pragmática. Afinal, os parênteses são sagrados, mas os parênteses não. 2

(lambda(s)(list->string(map(lambda(c)(case c((#\()#\[)((#\))#\])(else c)))(string->list s)))

1. não ouça os hereges da chamada "igreja" do Emacs!
2. Eles não são programadores de raquete, são?

xebtl
fonte
O esquema deve ser chamado de cisma: dizer que é o "Lisp real" é a heresia real. E você diz que é pragmático ? Este hack de uma resposta mostra a verdadeira natureza de schemers ;-)
coredump
@coredump E você diria que sua resposta elisp monstruosamente não funcional é uma instância do True Lisp? Pode demorar um pouco mais, é verdade, mas quando a resposta do esquema estiver concluída, será A coisa certa!
xebtl
3

Haskell, 210 bytes

n#x|b==""=a|1<2=a++"<sup>"++m++"</sup>"++((n+1)#(c++"\n\n<sub>"++m++' ':init d++"</sub>"))where m=show n;(a,b)=span(/='(')x;(d,c)=[x|x@(y,_)<-map(`splitAt`(tail b))[0..],'('!y<')'!y]!!0;c!l=[1|m<-l,m==c]
p=(1#)

Exemplo de uso:

*Main> putStrLn $ p "This has (nested (deeply (or highly?) nested)) parentheses (and several groups)."
This has <sup>1</sup> parentheses <sup>2</sup>.

<sub>1 nested <sup>3</sup></sub>

<sub>2 and several groups</sub>

<sub>3 deeply <sup>4</sup> nested</sub>

<sub>4 or highly?</sub>

Como funciona:

n # x                      -- # does all the work, n is the current number of the
                           --   footnote and x the input string
  | b=="" = a              -- if b (see below) is empty, there's no ( in the
                           --   string and the result is 'a' (see below)
  | 1<2   = a++"<sup>"++m++"</sup>"++ ((n+1)#(c++"\n\n<sub>"++m++' ':init d++"</sub>"))
                           -- otherwise (b not empty) build the output string
                           --   starting with 'a' and a footnote number and a
                           --   recursive call with the current footnote appended
                           --   to the rest of the string  

  where 
  m = show n;              -- turn n into string
  (a,b) = span (/='(') x;  -- split the input string x into two parts:
                           --   a: everything before the first (
                           --   b: beginning with the first ( to the end
                           --   if there's no (, a is x and b is empty
  (d,c) = [x|x@(y,_)<-map(`splitAt`(tail b))[0..],'('!y<')'!y]!!0;
                           -- find matching ) in the tail of b ('tail' to remove leading '(') 
                           --   d: everything before and including the matching )
                           --   c: everything behind the matching )
  c!l=[1|m<-l,m==c]        -- helper function that builds a list of 1s for every character searched for
                           --   we have reached the matching ) if the list for ( is
                           --   shorter (less than, <) the list for )

p=(1#)                     -- start with footnote 1
nimi
fonte
2

Esquema, 533 bytes

Com recuo:

(letrec ((l string->list)
         (n number->string)
         (? null?)
         (p (lambda (o) (or (pair? o)(? o))))
         (a car)
         (d cdr)
         (e append)
         (i 0)
         (x
          (lambda (h t)
            (if (? h)
                t
                (case (a h)
                  ((#\() 
                   (let ((s (x (d h) ())))
                     (x (a s) (e t (d s)))))
                  ((#\)) (cons (d h) (list t)))
                  (else 
                   (x (d h) (e t (list (a h)))))))))
         (f 
          (lambda (h t F)
            (cond ((? h)
                   (let ((w (e t F)))
                     (if (find p w) (f w()()) w)))
                  ((p(a h))
                   (set! i(+ 1 i))
                   (f (d h)
                      (e t (e (l "<sup>")
                              (l (n i))
                              (l "</sup>")))
                      (e F (e (l "\n\n<sub>")
                              (l (n i))
                              '(#\ )
                              (a h)
                              (l "</sub>")))))
                  (else (f (d h) 
                           (e t (list (a h)))
                           F))))))
  (print (list->string (f (x (l (read-line)) 
                             ())
                          ()
                          ()))))

Sim, são 533 bytes quando todo o espaço em branco opcional é removido. Aproveite a glória funcional.

Eu implementei mais ou menos o algoritmo na descrição: xagrupa a entrada entre parênteses e fsubstitui o primeiro nível de grupos por notas de rodapé, repetindo até que não haja mais grupos restantes. Estou certo de que pode ser feita mais curta, mas eu não vejo como isso poderia ser feito muito mais curto sem mudar para um algoritmo diferente.

Como está escrito, é um programa completo. Você pode experimentá-lo aqui , mas porque repl.it aparentemente não pode lidar com (read-line)você, você deve colocar a string de entrada em seu lugar. Uma versão completamente não destruída está aqui .

EDIT: Como apontado nos comentários, alterei os parênteses ()entre parênteses []nas versões repl.it. Isso foi puramente por conveniência durante a programação e a depuração. A versão postada agora funciona com ().

xebtl
fonte
11
+1, mas não entendo por que você muda colchetes. Se eu mudar #\['#] `pelos respectivos parênteses (e atualizar testes), isso funcionará sem problemas. Existe algum motivo para você deixar os quadrados? está relacionado à sua resposta anterior?
Coredump
11
@ Coredump você está absolutamente certo. Mudei para colchetes porque (a) literais de caracteres paren alteraram a correspondência de parêntes de repl.it e (b) na depuração, a saída (que incluirá muitas parênteses das listas) era muito mais legível com colchetes. Então eu apenas deixei assim. Eu vou editar.
Xebtl 17/09/2015
1

JavaScript ES6, 244 bytes

Resposta séria (só funciona no FireFox, que eu saiba)

d=(s,n=1)=>{u=s.search(/\(/);if(index<a=0)return s;for(i=index;i<s.length;i++){if(s[i]==")")a-=1;if(s[i]=="(")a+=1;if(!a)break}return d(s.replace(v=s.slice(index,i+1),"<sub>"+n+"</sub>")+`

<sub>`+n+" "+v.replace(/^\(|\)$/g,"")+"</sub>",n+1)}

Expandido:

function deparen(s,n=1){
    index = s.search(/\(/);
    if(index<0) return s;
    a=0;
    for(i=index;i<s.length;i++){
        if(s[i]==")") a-=1;
        if(s[i]=="(") a+=1;
        if(!a) break;
    }
    v=s.slice(index,i+1)
    f=v.replace(/^\(|\)$/g,"");
    return deparen(s.replace(v,"<sub>"+n+"</sub>")+"\n\n<sub>"+n+" "+f+"</sub>",n+1);
}
Conor O'Brien
fonte
0

Hássio , 315 bytes

Atualmente, isso não é concorrente, pois também não lida exatamente com os aninhados.

func main(){i=input();r="";f="";z=1;for(x=0;x<i.length;x++){c=i[Convert.toNumber(Convert.toString(x))];if(c=="("){f+="\n<sub>"+z+" ";for(x++;!(i[Convert.toNumber(Convert.toString(x))]==")");x++){f+=i[Convert.toNumber(Convert.toString(x))];}f+="</sub>\n";z++;r+="<sup>"+z+"</sup>";}else r+=c;}println(r);println(f);}

Expandido:

func main() {
    i = input();
    r = "";
    f = "";
    z = 1;
    for (x = 0; x < i.length; x++) {
            c = i[Convert.toNumber(Convert.toString(x))];
            if (c == "(") {
                    f += "\n<sub>" + z + " ";
                    for (x++; !(i[Convert.toNumber(Convert.toString(x))] == ")"); x++) {
                            f += i[Convert.toNumber(Convert.toString(x))];
                    }
                    f += "</sub>\n";
                    z++;
                    r += "<sup>" + z + "</sup>";
            } else
                    r += c;
    }

    println(r);
    println(f);

}

Jacob Misirian
fonte