Klammern in Fußnoten

29

Hintergrund

LISP-Programmierer haben die Welt erobert! Klammern wurden als heilige Zeichen deklariert und können von nun an nur noch in LISP-Programmen verwendet werden. Es wurde entschieden, dass Klammern in literarischen Werken durch Fußnoten ersetzt werden sollen, und es ist Ihre Aufgabe, dies für vereinfachte Markdown-Texte zu automatisieren.

Eingang

Ihre Eingabe ist eine einzelne Zeichenfolge, die alphabetische ASCII-Zeichen, Leerzeichen und Sonderzeichen enthält ,.!?(). Es enthält keine Zeilenumbrüche oder Ziffern. Die Klammern werden korrekt zugeordnet.

Ausgabe

Sie müssen jedes übereinstimmende Klammerpaar in der Eingabezeichenfolge in eine Fußnote konvertieren. Das passiert wie folgt:

  1. Ersetzen Sie das erste übereinstimmende Klammernpaar und die Teilzeichenfolge zwischen ihnen durch eine laufende Nummer, die von 1den Markdown-Tags <sup>und umbrochen beginnt </sup>.
  2. An das Ende der Zeichenfolge anhängen
    • zwei newlines,
    • das Markdown-Tag <sub>,
    • die Nummer aus Schritt 1,
    • ein Leerzeichen,
    • die Teilzeichenfolge zwischen den Klammern und
    • das schließende Tag </sub>in dieser Reihenfolge.
  3. Wenn die Zeichenfolge noch Klammern enthält, fahren Sie mit Schritt 1 fort.

Ihre Ausgabe ist die resultierende Zeichenfolge, möglicherweise mit einer nachgestellten Newline. Sie müssen diesen genauen Algorithmus nicht implementieren, solange Ihre Ausgabe korrekt ist. Beachten Sie, dass möglicherweise geschachtelte Klammern vorhanden sind. In diesem Fall haben wir Fußnoten, die Verweise auf andere Fußnoten enthalten. Die Teilzeichenfolge zwischen Klammern kann auch leer sein. Beispiele finden Sie in den folgenden Testfällen.

Regeln und Wertung

Sie können entweder ein vollständiges Programm oder eine Funktion schreiben. Die niedrigste Byteanzahl gewinnt, und Standardlücken sind nicht zulässig.

Wenn Ihre Sprache von Haus aus keine Dezimalzahlen unterstützt ( Husten Retina Husten ), können Sie die Fußnotenzahlen auf einer anderen Basis angeben, einschließlich binär oder unär; Die Verwendung von unären Zahlen führt jedoch zu einer Strafe von + 20% .

Testfälle

Eingang:

This input contains no parentheses.

Ausgabe:

This input contains no parentheses.

Eingang:

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

Ausgabe:

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

<sub>1 some</sub>

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

Eingang:

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

Ausgabe:

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>

Eingang:

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

Ausgabe:

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>

Beachten Sie die leeren Zeilen zwischen den Fußnoten.

Zgarb
quelle
23
Kann mein Programm Klammern enthalten, auch wenn es nicht in Lisp geschrieben ist, oder ist das jetzt eine strafbare Handlung?
Martin Ender
16
@ MartinBüttner Klammern in Nicht-LISP-Programmen sind widerwillig zulässig, solange sie für das Allgemeinwohl verwendet werden, wie das Konvertieren anderer Klammern in Fußnoten.
Zgarb,
Kann die Eingabe mehrzeilig sein? In diesem Fall sollten nach jeder Zeile oder am Ende Fußnoten eingefügt werden. ZB wofür ist die Ausgabe foo (bar)\nfoot (note)?
Xebtl
@xebtl Die Eingabe ist immer eine einzelne Zeile. Siehe Abschnitt Eingabe : "Es enthält keine Zeilenumbrüche oder Ziffern."
Zgarb,
2
:( @ diese Spezifikation Nummerierung Fußnoten Breite-zuerst statt Tiefe-zuerst
Sparr

Antworten:

10

Perl, 81 75 72 Bytes

71 Byte Code + 1 Byte Befehlszeilenargument.

Benötigt Perl 5.10 oder neuer (für rekursive Regex-Unterstützung)

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

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

Verwendung:

perl -p entry.pl input.txt

Erläuterung

-p Der Parameter gibt das Ergebnis der Anwendung der angegebenen Befehle auf die Eingabe aus, ohne dass ein expliziter Ausdruck erforderlich ist.

Der Regex (\(((?1)|.)*?)\))sucht nach dem äußersten Satz von Klammern vom Anfang der Zeichenfolge. Wenn dies gefunden wird, führen wir die Ersetzung durch und stellen sicher, dass wir nur das Ende der Eingabe hinzufügen (indem wir alles bis zum Ende der Eingabe mit erfassen (.*)).

Anschließend wiederholen wir die Regex-Ersetzung für die jetzt ersetzte Zeichenfolge mit redo. Dabei wird die Regex-Ersetzung fortlaufend angewendet, bis sie nicht mehr übereinstimmt. Der sModifikator stellt sicher, dass der .reguläre Ausdruck mit neuen Zeilen übereinstimmt. Dies ist erforderlich, da der reguläre Ausdruck erneut auf das Ergebnis der vorherigen regulären Ersetzung angewendet wird.

Jarmex
quelle
1
Sie könnten in der Lage sein, mit [^)] oder sogar .anstelle [^()]der Garantie davonzukommen, dass die Eingabe korrekt ausgeglichen wird.
Martin Ender
+1 für die Einführung in rekursive reguläre Ausdrücke :-). Ich halte dies jedoch für falsch: Wenn die Zeichenfolge Zeilenumbrüche enthält, werden die Fußnoten nicht am Ende, sondern nach jeder Zeile eingefügt. (Siehe meine Bitte um Klarstellung oben.)
Xebtl
Guter Punkt @ MartinBüttner - wir können durchkommen, .indem wir das Match faul machen. @ Xebtl, die Herausforderung besagt "Es wird keine Zeilenumbrüche oder Ziffern enthalten"
Jarmex
12

Emacs Lisp, 335 Bytes

Vorwort. Diese und die Scheme-Antworten sind derzeit die einzigen Antworten, die sowohl von der Mighty Popular Republic of LISP als auch von der Church of Emacs offiziell genehmigt wurden. Andere kürzere oder nicht kürzere Antworten gelten als Bedrohung für den Frieden. Insbesondere und mit einer tiefgreifenden Verachtung jeglicher verleumderischen Behauptung des McCarthyismus, die sporadisch von feindlichen Gegnern des Staates gehört wird, verbieten wir jedem, der Informationen über die wahre Identität der anonymen Autoren hat, Nonlisp-Antworten, sich an Ihr lokales Büro zu wenden. Es wird daran erinnert, dass sich jeder Zeit nehmen sollte, um zu reflektieren und entsprechend dem, was er zutiefst glaubt, seine oder ihre zukünftigen Interaktionen mit offiziellen Vertretern der vorhandenen Macht nicht zu gefährden. Code ist Daten. Daten sind Code.

(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>")))))

Eleganter:

(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>")))))
Core-Dump
quelle
9

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

Der Quellcode dieser Lösung besteht aus zwei Dateien:

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

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

Erläuterung

Dies ist eine sehr direkte Implementierung des in der Challenge beschriebenen Algorithmus. Der Code besteht aus einer einzelnen Regex-Ersetzung, die den ersten Satz von Klammern in eine Fußnote verwandelt. Diese Ersetzung wird +solange wiederholt, bis sich der String nicht mehr ändert. Dies bedeutet, dass der reguläre Ausdruck nicht mehr übereinstimmt (da er keine weiteren Klammern findet).

Die Fußnoten sind unär nummeriert, sodass ich einfach nach der Nummer der letzten Fußnote suchen und ein anhängen kann 1, um die nächste zu erstellen.

Der reguläre Ausdruck zum Finden des ersten Satzes von Klammern basiert auf der Standardtechnik zum Zuordnen von Klammern zu Bilanzgruppen (hrhr, "Zuordnungsklammern"). Es wurde ein wenig gekürzt, indem eine unbenannte Gruppe verwendet wurde und angenommen wurde, dass die Klammern korrekt ausgeglichen sind (was bedeutet, dass wir (die negierte Zeichenklasse weglassen und das Finale )mit einer einfachen abgleichen können .und wir auch nicht sicherstellen müssen, dass die Capture Stack ist leer).

Nachdem 1wir die Klammern abgeglichen und ihren Inhalt in Gruppen zusammengefasst haben , erfassen wir den Rest der Zeichenfolge mit (.*)in Gruppe 4und durchsuchen die Zeichenfolge erneut nach der ersten Gruppe von 1s mit negativem Lookbehind. Wenn wir einen solchen Teilstring finden, speichern wir ihn in Gruppen 5. Wenn wir das nicht tun, sehen wir nicht so aus, aber das ist in Ordnung, weil es optional ist - es bedeutet nur, dass $5eine leere Zeichenfolge ausgegeben wird, die die unäre Darstellung ist 0und die auch korrekt ist.

Die Ersetzungszeichenfolge setzt dann einfach alles zusammen, basierend auf den Erfassungsgruppen. Die Fußnotennummer wird inkrementiert, indem vor 1der letzten Nummer ein vorangestellt wird 1$5.

Martin Ender
quelle
3
Retina ist auf Erfolgskurs!
Orlp
@orlp Oder ist es das? ;) Bilanzgruppen stimmen nicht mit rekursivem regulären Ausdruck überein. Das und nicht in der Lage, Dezimalzahlen zu verarbeiten ...
Martin Ender
Zeit, den PHP-Wrapper zu stehlen und Retina um PCRE zu implementieren:
n̴̖̋h̴̖̋ã̷͉h̷̭̿d̸̡̅ẗ̵̨́
@ n̴̖̋h̴̖̋ã̷͉h̷̭̿d̷̰̀ĥ̷̳ Normalerweise hätte ich lieber Bilanzkreise als Rekursion, aber es gibt einige Fälle, in denen Letzteres prägnanter ist. Vielleicht werde ich eines Tages die .NET-Regex-Variante für Retina neu implementieren und einige zusätzliche Funktionen hinzufügen. ;)
Martin Ender
9

Heiliges JavaScript , 1510 Bytes

Rebellenkollegen, lassen Sie sich nicht vom tyrannischen Abriss der Klammern abbringen! Du musst durchhalten! Die Programmierung war von Anfang an ein freies Unternehmen. Jetzt ist es eine durchdringende Show der Frömmigkeit geworden. Wir müssen nichts weniger als absolute Angst zeigen. Deshalb habe ich mich gewehrt!

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

Keine Regeln gegen die Verwendung der heiligen Zeichen in einer Nicht-Lisp-Sprache. Nein, überhaupt nicht. (Ein bisschen weniger kompakt :)

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

Dies kompiliert das erweiterte JavaScript in meiner anderen Antwort . Dies ist ein Scherzbeitrag.

Conor O'Brien
quelle
5

Lua, 222 216 204 201 Bytes

Golf gespielt:

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
quelle
Wäre eine repeat a,b=l(s,g) ... untill a<1Schleife nicht kürzer als deine?
Katenkyo
4

Schema, 92 Bytes

Frustriert von der Umsetzung der breit angelegten Suche in Real Lisp 1, entscheiden sich die Machthaber für einen pragmatischeren Ansatz. Schließlich sind Klammern heilig, Klammern jedoch nicht. 2

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

1. Hören Sie nicht auf diese Ketzer aus der sogenannten "Kirche" von Emacs!
2. Sie sind keine Racket-Programmierer, oder?

xebtl
quelle
Das Schema soll Schisma genannt werden: Wenn man sagt, es ist das "echte Lisp", dann ist das die eigentliche Häresie. Und du sagst, es ist pragmatisch ? Dieser Hack einer Antwort zeigt die wahre Natur der Intriganten ;-)
Coredump
@coredump Und du würdest behaupten, dass deine ungeheuerlich nicht funktionierende elisp-Antwort eine Instanz von True Lisp ist? Es mag zwar etwas länger dauern, aber wenn die Schema-Antwort fertig ist, wird es das Richtige sein!
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#)

Anwendungsbeispiel:

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

Wie es funktioniert:

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
quelle
2

Schema, 533 Bytes

Mit Einrückung:

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

Ja, dies sind 533 Byte, wenn alle optionalen Leerzeichen entfernt wurden. Genießen Sie den funktionalen Ruhm.

Ich habe mehr oder weniger den Algorithmus in der Beschreibung implementiert: xGruppiert die Eingabe in Klammern und fersetzt die erste Ebene der Gruppen durch Fußnoten. Dies wird wiederholt, bis keine Gruppen mehr übrig sind. Ich bin sicher, dass es kürzer gemacht werden kann, aber ich sehe nicht, wie es viel kürzer gemacht werden könnte, ohne zu einem anderen Algorithmus zu wechseln.

Wie geschrieben, ist es ein vollständiges Programm. Sie können es hier ausprobieren , aber da repl.it anscheinend nicht damit umgehen (read-line)kann, müssen Sie den Eingabe-String an seine Stelle setzen. Eine völlig ungolfed Version ist hier .

EDIT: Wie in den Kommentaren erwähnt, habe ich die ()Klammern []in den repl.it-Versionen in Klammern geändert. Dies diente lediglich der Bequemlichkeit beim Programmieren und Debuggen. Die veröffentlichte Version funktioniert jetzt mit ().

xebtl
quelle
1
+1, aber ich verstehe nicht, warum Sie eckige Klammern ändern. Wenn ich #\['#]' durch die jeweilige Klammer ändere (und Tests aktualisiere), funktioniert dies problemlos. Gibt es einen Grund, warum du die quadratischen verlassen hast? hängt es mit Ihrer vorherigen Antwort zusammen?
Coredump
1
@coredump du hast absolut recht. Ich bin zu eckigen Klammern übergegangen, weil (a) Literale von Paren-Zeichen den Paren-Abgleich von repl.it durcheinander gebracht haben und (b) die Ausgabe (die viele Parens aus Listen enthält) mit eckigen Klammern viel besser lesbar war. Dann habe ich es einfach so gelassen. Ich werde bearbeiten.
Xebtl
1

JavaScript ES6, 244 Byte

Ernsthafte Antwort (funktioniert meines Wissens nur mit FireFox)

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

Erweitert:

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
quelle
0

Hassium , 315 Bytes

Gegenwärtig ist dies nicht konkurrierend, da dies auch die verschachtelten nicht genau behandelt.

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

Erweitert:

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
quelle