Golf meine Shakespeare-Zitatreferenzen

45

Als ich meinen Aufsatz für Shakespeare schrieb, wurde mir klar, dass ich meine Zitatreferenzen auf überschaubarere Längen kürzen musste. Ich hatte vorher folgendes geschrieben:

(Act 1, Scene 2, Lines 345-346)

Aber mir wurde jetzt gesagt, dass ich sie so schreiben soll:

(I.ii.345-6)

Natürlich brauche ich Code, um meine Shakespeare-Zitatreferenzen ein wenig nach unten zu spielen.

Die Aufgabe

Schreiben Sie ein Programm oder eine Funktion, die bei einer Zeichenfolgeeingabe nach Vorlage 1 oder 2 eine Zeichenfolge nach Vorlage 3 oder 4 ausgibt oder zurückgibt. Sie müssen nur die Akte 1 bis 5 und die Szenen 1 bis 9 unterstützen.

Vorlagen

Vorlage 1

(Act x, Scene y, Lines a-b)

Sie können davon ausgehen, dass xniemals mehr als 5, yniemals mehr als 9 aund bimmer positive Ganzzahlen sind, die den maximalen positiven Standard-Ganzzahlwert Ihrer Sprache nicht überschreiten und aimmer ausschließlich kleiner als sind b.

Vorlage 2

(Act x, Scene y, Line a)

Gleiche Bedingungen wie Vorlage 1, ausgenommen Informationen zu b.

Vorlage 3

(x.y.a-b)

Wobei xeine römische Ziffer in yGroßbuchstaben , eine römische Ziffer in Kleinbuchstaben aund bZahlen sind und bauf nur die Ziffern gekürzt werden, die kleiner sind als die erste abweichende Ziffer von gleicher Bedeutung a.

Vorlage 4

(x.y.a)

Gleiche Bedingungen wie Vorlage 3, mit Ausnahme von Informationen zu b.

Testfälle

Sei f(s)die in der Aufgabe definierte Funktion. ""bezeichnet einen Zeichenkettenwert.

>>> f("(Act 1, Scene 2, Lines 345-346)")
"(I.ii.345-6)"

>>> f("(Act 3, Scene 4, Lines 34-349)")
"(III.iv.34-349)"

>>> f("(Act 5, Scene 9, Lines 123-234)")
"(V.ix.123-234)"

>>> f("(Act 3, Scene 4, Line 72)")
"(III.iv.72)"

>>> f("(Act 2, Scene 3, Lines 123-133)")
"(II.iii.123-33)"

>>> f("(Act 4, Scene 8, Lines 124-133)")
"(IV.viii.124-33)"

Für diese Herausforderung müssen die folgenden Übersetzungen von arabischen zu römischen Ziffern unterstützt werden:

1 i     I
2 ii    II
3 iii   III
4 iv    IV
5 v     V
6 vi    (you do not have to support past 5)
7 vii
8 viii
9 ix
Addison Crump
quelle
Sind Textdateien erlaubt?
Dat
21
Ich hoffe wirklich auf eine Antwort in SPL.
L3viathan
5
Testfall:(Act 1, Scene 2, Lines 345-3499)
dzaima
11
Wer ist bereit für eine Antwort in Shakespeare?
Titus
1
@ Grimy Fixed # 1, ist # 2 gut?
Addison Crump

Antworten:

12

Die Shakespeare-Programmiersprache (nicht konkurrierend)

Diese Frage hat mir sehr gut gefallen, und da ein gewisses Interesse an einer Shakespeare-Antwort bestand, hier eine.

A Tale of Two Cites (sic).

Julius Caesar, the first citizen of the Roman Republic.
Brutus, a traitor -- member of the Fifth Column.
Cicero, the greatest Roman orator.
Cleopatra, a proud queen, whom the Romans want to make one of their own.
Romeo, a man who's sometimes there.
Juliet, a maiden who can follow Romeo or stand on her own.


           Act I: Imperium Romanum.


           Scene I: Cleopatra puts men in their place.

[Enter Cleopatra and Julius Caesar]

Julius Caesar:
    Thou art as lovely as the sum of an amazing delicious gentle blossoming warm angel and a charming noble reddest rose.
    Speak your mind. Open your mind. Open your mind. Open your mind! Open your mind!

Cleopatra:
    You are as stuffed as the sum of a hard old green horse and the sum of a grandmother and
    a normal tiny bottomless furry small purple roman.

[Exit Julius Caesar]
[Enter Brutus]

Cleopatra:
    You are as sorry as the difference between a rich morning and a leech.
    You are as smelly as the difference between yourself and a sunny rural blue bold uncle.
    You are as vile as the difference between Julius Caesar and yourself.

[Exit Brutus]
[Enter Cicero]

Cleopatra:
    You are as half-witted as the difference between Brutus and the bluest death.


           Scene II: How do you solve a problem like Cleopatra?

[Exeunt]
[Enter Cleopatra and Julius Caesar]

Julius Caesar:
    Listen to your heart!

[Exit Cleopatra]
[Enter Brutus]

Julius Caesar:
    Is Cleopatra more pretty than a fair charming noble angel?

Brutus:
    If so, we must proceed to Scene IV. Is Cleopatra not worse than the sweetest small aunt?

Julius Caesar:
    If so, let us proceed to Scene III.

Brutus:
    Speak your mind.

Julius Caesar:
    Is Cleopatra nicer than the moon?

Brutus:
    If so, speak your mind.

Julius Caesar:
    Is Cleopatra better than a golden King?

Brutus:
    If so, speak your mind.

Julius Caesar:
    We shall proceed to Scene V.


          Scene III: Brutus and his friends.
Julius Caesar:
    Is Cleopatra as fair as the blossoming smooth sky?

Brutus:
    If so, speak your mind!

Julius Caesar:
    Speak your mind!

Julius Caesar:
    Is Cleopatra jollier than the sum of a yellow sweet road and a summer's day?

Brutus:
    If so, speak your mind!

Julius Caesar:
    Is Cleopatra friendlier than the sum of a sweet large angel and a white cow?

Brutus:
    If so, speak your mind!

Julius Caesar:
    Is Cleopatra as furry as a rich handsome huge mistletoe?

Brutus:
    If so, speak your mind!

Julius Caesar:
    We shall proceed to Scene V.


          Scene IV: Cicero is asked to speak.
[Exit Brutus]
[Enter Cicero]

Julius Caesar:
    Is Cleopatra as beautiful as the sum of a small furry white angel and a summer's day?

Cicero:
    If so, speak your mind!

Julius Caesar:
    Speak YOUR mind!


          Scene V: A period piece -- Cleopatra's reprisal.
[Exeunt]
[Enter Cleopatra and Julius Caesar]

Julius Caesar:
    You are as beautiful as the sum of a embroidered sweetest sunny delicious trustworthy Lord
    and a reddest charming mighty honest King.
    You are as healthy as the difference between yourself and a embroidered Lord. Speak your mind!
    Open your mind! Open your mind! Open your mind! Open your mind! Open your mind! Open your mind!

Cleopatra:
    Are you jollier than the sum of a little rural white bottomless blue blue sky and a rural furry white green old morning?

Julius Caesar:
    If so, we must proceed to Act II. Open your mind! Open your mind!

Cleopatra:
    You are as damned as the difference between yourself and a half-witted dusty snotty rotten oozing death.

[Exit Julius Caesar]
[Enter Brutus]

Cleopatra:
    You are as rotten as the difference between yourself and a rural rotten bottomless evil miserable famine.

[Exit Brutus]
[Enter Cicero]

Cleopatra:
    You are as fatherless as the difference between Brutus and a normal pig. Let us return to Scene II.



          Act II: Lovers' arithmetick.

          Scene I: Our lovers discuss what they have in common.

[Exeunt]
[Enter Romeo and Juliet]

Romeo:
    Thou art as bold as a curse. Listen to your heart!

Juliet:
    Am I better than nothing? If so, let us proceed to Scene III.

Romeo:
    Open your mind. Open your mind.

Juliet:
    Listen to your heart! Open your heart!

Romeo:
    Thou art as amazing as the product of the difference between a handsome white proud white grandfather and an aunt
    and the sum of a loving niece and the Heaven. Speak your mind! Open your mind.
    Listen to your heart. Is the quotient between yourself and the sum of the sum of
    a noble noble mighty blossoming embroidered good father
    and a gentle large large normal old joy and an old happy squirrel as yellow as the quotient between
    myself and the sum of the sum of a pretty beautiful yellow green bold charming kingdom and
    a beautiful blue normal cute large nephew and a pretty big cousin?

Juliet:
    If not, we shall proceed to Scene II.

Romeo:
    You are as sweet as the remainder of the quotient between yourself and the sum of the sum of
    a blossoming bottomless golden peaceful noble healthy nose and
    a happy honest sunny green healthy hero and a hard blue fellow.

Juliet:
    YOU are as sweet as the remainder of the quotient between yourself and the sum of the sum of
    a blossoming bottomless golden peaceful noble healthy nose and
    a happy honest sunny green healthy hero and a hard blue fellow.


          Scene II: Tense times.
Juliet:
    Is the quotient between yourself and the sum of a good beautiful delicious grandmother
    and a noble wind as amazing as the quotient between myself and the sum of
    a smooth furry embroidered roman and a honest sister?

Romeo:
    If so, you are as amazing as the remainder of the quotient between
    yourself and the sum of a cute healthy smooth kingdom and a normal mother.


          Scene III: Parting is such sweet sorrow.
Romeo:
    Open your heart! You are as noble as the sum of a honest charming smooth peaceful fine rose and the sum of
    a cute amazing trustworthy summer's day and an angel. Speak your mind!

(Es ist mehr als 6000 Byte.) Es gibt einige Tricks drin , aber ich habe nicht zu Golf versuchte es viel, weil: (1) Ich habe bereits dazu beigetragen , meinen Anteil an Golf auf eine andere Antwort, und (2) Ändern Sie alle Zeichen auf „Seite "und" Puck "oder alle Sätze zu" big big big big cat "scheinen den Spaß zu verderben. Stattdessen habe ich für den Teil, der sich mit römischen Ziffern befasst, Zeichen verwendet, die Römer usw. sind. :-)

Das Programm sollte größtenteils unkompliziert sein, aber ein erwähnenswerter Fehler ist, dass ich beim Schreiben davon ausgegangen bin, dass das Lesen einer Ganzzahl folgendermaßen funktionieren würde scanf: (1) Es werden nur so viele Zeichen aus der Eingabe verbraucht, wie einer Ganzzahl entsprechen, und (2) für den Fall Lassen Sie die Variable unverändert. (Ich habe diese zweite Eigenschaft verwendet, um zwischen Template 1 und 2 in Akt II zu unterscheiden, indem ich bis zu "Line" gelesen und versucht habe, eine Ganzzahl zu lesen.) Leider hat die ursprüngliche Implementierung von (was ich betrachte) einen Fehler Die Sprache, in der das Lesen einer Ganzzahl alles bis zum Ende der Zeile verbraucht und einen Fehler auslöst, falls dies fehlschlägt. Daher ist ein Patchlibspl.c erforderlich , um das int_inputVerhalten zu verbessern scanf.

Und damit funktioniert es:

% spl2c < good.spl > good.c
% gcc -lspl -o good good.c                                    
% for f in in-*; do cat $f; echo "->"; ./good < $f; echo "\n"; done    
(Act 1, Scene 2, Lines 345-346)
->
(I.ii.345-6)

(Act 3, Scene 4, Lines 34-349)
->
(III.iv.34-349)

(Act 5, Scene 9, Lines 123-234)
->
(V.ix.123-234)

(Act 3, Scene 4, Line 72)
->
(III.iv.72)

(Act 2, Scene 3, Lines 123-133)
->
(II.iii.123-33)

(Act 4, Scene 8, Lines 124-133)
->
(IV.viii.124-33)

Etwas höherer Pseudocode, an dem ich gearbeitet habe, um jedem zu helfen, der versucht zu verstehen:

Print `(`=40
Read 5 chars
Read Int A
Output A in Roman
Output `.`=46
Read 8 chars
Read Int S
Output S in roman
Output `.`=46
Read 6 chars
Set N to -1
Read Int N
If N ≠ -1 goto finish
Read 2 chars
Read Int M
Output Int M
Output `-`=45
Read 1 char
Read Int N
Reduce N wrt M
finish:
Output N
Print `)`=41

Das oben Gesagte mit dem endgültigen Code in Verbindung zu bringen, bleibt als Übung. :-) Beachten Sie, dass ShakespearePL Arithmetik und Stapel und GOTOS hat, aber keine Zeiger (nur Labels), so dass die Implementierung von "Unterprogrammen" wie der Konvertierung nach Roman ein bisschen ... interessant ist.

ShreevatsaR
quelle
Wow, das ist wunderschön. Danke! :)
Steve Bennett
1
klopft wiederholt auf den Upvote-Button
Addison Crump
9

LaTeX, 513 364 259 226 215 178 159 Bytes

Gute Aufsätze sollten immer in LaTeX geschrieben werden.

\documentclass{tui}\makeatletter\input{xstring}\def~#1 #2, #3 #4, #5 #6){(\@Roman#2.\@roman#4.\StrCut{#6}-\A\B\A\if\B\else-\fi\StrCompare\A\B[\P]\StrMid\B\P9)}

Dies verwendet das xstring-Paket, da nicht gerade viel String-Handling eingebaut ist. Auf der positiven Seite ist die Obergrenze für die eingebaute \RomanFormatierung größer, als wir jemals brauchen werden (sogar für die Sonette) 2^31-1. Ich habe \documentclass{ecv}in die Zählung aufgenommen, aber keinen der Testcodes:

\begin{document}
\t(Act 1, Scene 2, Lines 345-346) 

\t(Act 3, Scene 4, Lines 34-349)

\t(Act 5, Scene 9, Lines 123-234)

\t(Act 3, Scene 4, Line 72)

\t(Act 2, Scene 3, Lines 123-133)

\t(Act 4, Scene 8, Lines 124-133)
\end{document}

(Wenn Sie verrückt genug wären, dies tatsächlich zu verwenden, müssten Sie zumindest die Makronamen entgolfen. Das Überschreiben von Einzelzeichen-Makros ist eine schlechte Praxis.)

Ungolfed und kommentiert:

\documentclass{ecv}%We have to have a documentclass
\makeatletter %treat the @ sign as a normal character (it's used in "internal" macro names)
\input{xstring} %use the xstring package
\def\shortref#1 #2, #3 #4, #5 #6){ %macro with 6 positional arguments searated by spaces and commas 
    (%print the open bracket
    \@Roman#2 %arg 2 is the Act,  print uppercase Roman
    .%print the full stop
    \roman#4 %arg 4 is the Scene, lowercase roman
    .%print the full stop
    \StrCut{#6}{-}{\A}{\B}%split arg 6 (Lines) at the hyphen, into macros \A and \B
    \A %print the bit before the hyphen
    \ifx\B\empty%if \B has nothing in it do nothing
    \else %otherwise
        - %we need to print a hyphen
    \fi%endif
    \StrCompare{\A}{\B}[\P] %returns (in macro \P) the position at which \A and \B first differ
    \StrMid{\B}{\P}{9}%print \B starting from position \P (9 > the number of remaining characters)
)}%print the closing bracket

Beachten Sie, dass in dieser Version die Kommentare erforderlich sind , da sonst die neue Zeile als Leerzeichen interpretiert und zu einem Leerzeichen erweitert wird.

Chris H
quelle
Sie können drei Bytes einsparen, indem ~Sie anstelle von als Makroname verwenden \s. Aber eigentlich brauchen Sie \s( \stripcommain der ungolfed Version) überhaupt nicht: Sie können einfach \def\t#1 #2, #3 #4, #5 #6und TeX wird sich darum kümmern, die Kommas zu entfernen . (Sie können also stattdessen den ~Trick \t
anwenden
@ ShreevatsaR danke. Sie haben herausgefunden, wie Sie die Komma-Zurückweisung in die Zeile bekommen und es war einfacher als alles, was ich versucht habe. Der Trick mit dem Aktiv ~ist ein bisschen böse, aber ich mag es hier. Das bedeutete, dass ich die Dokumentenklasse ändern musste (in eine der anderen 3-Buchstaben- .clsDateien, die ich installiert hatte)
Chris H,
1
Ja, ich zähle 182 Bytes, was nicht nur die Python-Antwort
übertrifft,
1
@ShreevatsaR noch besser: 178 as \@roman und \@Romanbrauchen keine geschweiften Klammern um das Argument.
Chris H
1
Alle Hauptideen xstringwaren deine :-) Es hat Spaß gemacht, dies zusammen zu spielen!
ShreevatsaR
8

JavaScript (ES6), 210 183 178 177 171 Bytes

Einsparung von 27 Bytes durch das Abrollen von Restparametern (dank ETHproductions )

5 Bytes wurden eingespart, indem die Eröffnungsparen nicht übereinstimmten und die Generierung der römischen Zahl geändert wurde

1 Byte durch Anpassen des letzten ternären Ausdrucks gespeichert

6 Bytes gespart durch Kombination zweier übereinstimmender Gruppen

s=>s.replace(/Act (\d)\D*(\d)\D*(\d*)(\d*-?)\3(\d*)/,(_,a,b,c,d,e)=>'IIIV'.slice(a>3&&a-2,a)+'.'+'iiiviiix'.slice('233336'[b-4],b-(b>4))+'.'+c+d+(d.length>e.length?e:c+e))

Testfälle:

let f = s=>s.replace(/Act (\d)\D*(\d)\D*(\d*)(\d*-?)\3(\d*)/,(_,a,b,c,d,e)=>'IIIV'.slice(a>3&&a-2,a)+'.'+'iiiviiix'.slice('233336'[b-4],b-(b>4))+'.'+c+d+(d.length>e.length?e:c+e))

;[
  ["(Act 1, Scene 2, Lines 345-346)", "(I.ii.345-6)"],
  ["(Act 3, Scene 4, Lines 34-349)", "(III.iv.34-349)"],
  ["(Act 5, Scene 9, Lines 123-234)", "(V.ix.123-234)"],
  ["(Act 3, Scene 4, Line 72)", "(III.iv.72)"],
  ["(Act 2, Scene 3, Line 123-133)", "(II.iii.123-33)"],
  ["(Act 4, Scene 8, Line 124-133)", "(IV.viii.124-33)"],
  ["(Act 1, Scene 2, Lines 345-3499)", "(I.ii.345-3499)"]
].map(([a,b]) => console.log(`${a} => ${f(a)} (${f(a) == b ? 'Pass' : 'Fail'})`))
.as-console-wrapper { min-height: 100% }

gyre
quelle
Ich kann jetzt nicht testen, aber funktioniert es immer noch, wenn Sie ersetzen Act und jeweils \D*mit .*?
Patrick Roberts
Es könnte; Ich habe gezögert, es zu versuchen, da JavaScript standardmäßig gierige Übereinstimmungen verwendet. Ich werde es später heute testen und Sie wissen lassen, ob es funktioniert.
Gyre
8

Jelly ,  87 86  85 Bytes

DµU=/œr1LCṫ@Ṫ
Ṗ,Çj”-µ⁸L’$?W
⁾-,yḲḊm2Ṗ€Vµ“¬Q:’ṃ⁾IV;”X“¤|ʂ’BṚ¤œṗị@µ1,2¦Œl2¦µ;ṪÇ$“(..)”ż

Probieren Sie es online! oder sehen Sie sich eine Testsuite an

Wie?

DµU=/œr1LCṫ@Ṫ - Link 1, toPageShort: list of numbers [fromPage, toPage]  e.g.  [345,365]
D             - cast to decimal lists                                 [[3,4,5],[3,6,5]]
 µ            - monadic chain separation (call that d)
  U           - reverse each                                          [[5,4,3],[5,6,3]]
   =/         - reduce by equality                                              [1,0,1]
     œr1      - strip any 1s from the right                                       [1,0]
        L     - length                                                                2
         C    - complement (1-z)                                                     -1
            Ṫ - tail d                                                          [3,6,5]
          ṫ@  - tail from index (swap @rguments)                                  [6,5]

Ṗ,Çj”-µ⁸L’$?W - Link 2, format page number(s): number or list of two numbers
           ?  - if:
          $   -   last two links as a monad:
        L     -     length
         ’    -     decremented (0 for a number, 1 for a list of two numbers)
      µ       - then:
Ṗ             -   pop (list without the last item, i.e. just the from page)
  Ç           -   call the last link (1) as a monad with the list as its argument
 ,            -   pair
    ”-        -   literal '-'
   j          -   join
              - else:
       ⁸      -   link's left argument (the single page number)
            W - wrap the result in a list (for ease of post-formatting in Main)

⁾-,yḲḊm2Ṗ€Vµ ... µ1,2¦Œl2¦µ;ṪÇ$“(..)”ż - Main link: string s
⁾-,                                    - literal ['-',',']
   y                                   - map (change '-' to ',')
    Ḳ                                  - split at spaces
     Ḋ                                 - dequeue (get all but 1st)
      m2                               - mod-index-2 (1st,3rd,5th)
        Ṗ€                             - pop €ach (ditch last char)
          V                            - evaluate - list of numbers
                                       -   either [act,scene,page] or
                                       -   [act,scene,[from,to]]
           µ     µ   ¦                 - apply to indexes:
                  1,2                  - [1,2]
             ...                       -   see monadic chain " ... ", below
                        2¦             - apply to index 2:
                      Œl               -   lowercase
                          µ            - monadic chain separation
                              $        - last 2 links as a monad:
                            Ṫ          -   tail (page(s))
                             Ç         -   call last link (2) as a monad
                           ;           - concatenate
                               “(..)”  - literal ['(','.','.',')']
                                     ż - zip together
                                       - implicit print

“¬Q:’ṃ⁾IV;”X“¤|ʂ’BṚ¤œṗị@ - monadic chain " ... " from Main
                         -   Get Roman numeral: number n (n>0, n<10) (act or scene)
“¬Q:’                    - base 250 literal 520559
      ⁾IV                - literal ['I','V']
     ṃ                   - base decompression -> "IIIIIIIVVVIVIIVIIII"
          ”X             - literal 'X'
         ;               - concatenate -> "IIIIIIIVVVIVIIVIIIIX"
                   ¤     - nilad followed by link(s) as a nilad:
            “¤|ʂ’        -   base 250 literal 281418
                 B       -   convert to a binary list
                  Ṛ      -   reverse
                    œṗ   -   split at truthy indexes i.e: I II III IV V VI VII VIII IX
                      ị@ -   index into (swap @arguments) using n
Jonathan Allan
quelle
1
Das muss eine Art Rekord für ein Jelly-Drehbuch sein
MickyT
@ MickyT Nein, ich habe länger draußen ...
Jonathan Allan
Dies führt zu Kopfschmerzen. Lies es nicht 0/10. : P
Erik der Outgolfer
@EriktheOutgolfer Entschuldigung !!
Jonathan Allan
2
Scherz beiseite, ich kann einige wirklich einzigartige Dinge in diesem Code sehen, wie œr, Ṗ,Ç, Ṗ€V, ṪÇ$, Wals das letzte Glied auf einem Helfer Link, möglicherweise auch anderen, schöne Anstrengung! Dies ist nicht Ihre übliche 80-Jelly-Vorlage, dies verdient besondere Anerkennung unter den Jelly-Leuten.
Erik der Outgolfer
6

R , 94 126 112 166 Bytes

Und jetzt ist es wortreicher als bisher :(, zurück zum Golf zu versuchen , es weiter. Regex zur Verringerung der Seite Referenz schamlos gestohlenen von @FryAmTheEggman entlehnt.

Jetzt muss ich wirklich etwas arbeiten, um die Bytes zurückzubekommen, aber es funktioniert jetzt für den zweiten Fall.

R=as.roman;i=sub(',','',scan(,''));sprintf('(%s.%s.%s',R(i[2]),tolower(R(i[4])),`if`(!diff(c(nchar(el(strsplit(i[6],'-'))),0))-1,sub('((.+).*-)\\2','\\1',i[6]),i[6]))

Probieren Sie es online! - Beachten Sie, dass eldies bei TIO nicht funktioniert und durch ersetzt wurdeunlist

R=as.roman;                              # Used to convert to roman numeral class
i=sub(',','',scan(,''));                 # Get input, splits on spaces, remove ,'s
sprintf('(%s.%s.%s',                     # Use sprintf to format the output.
    R(i[2]),                             # Convert to roman numeral
    tolower(R(i[4])),                    # Convert to roman numeral and lowercase
    `if`(                                #
       !diff(                            # Test if the lengths of the last string
       c(nchar(el(strsplit(i[6],'-'))),0)# split on the hyphen are different (extra 0 to appease diff)
       )-1,                              # taking into account the trailing )
       sub('((.+).*-)\\2','\\1',i[6]),   # on true use regex to reduce range
       i[6]                              # else output as is
    )
)
MickyT
quelle
4

Netzhaut ,89 88 Bytes

T`, lL`._
2`(\d+)
$*i
i{5}
v
i{4}
iv
viv
ix
1T`l`L`\w+
(\b(.+)(.)*-)\2((?<-3>.)*)\b
$1$4

Probieren Sie es online!

3 Bytes gespart dank Neil.

Entfernt die unnötigen Zeichen, bevor die ersten beiden Ziffern durch iZeichenblöcke ersetzt werden. Dann werden Teile dieser is zu den entsprechenden römischen Ziffern zusammengefasst. Dann schreiben wir die erste römische Ziffer groß. Schließlich stimmen wir so viele Zahlen wie möglich vor und nach dem Bindestrich ab, sodass die Anzahl der Ziffern in der Zahl gleich ist. Wir entfernen dann dieses Präfix von der zweiten Zahl.

FryAmTheEggman
quelle
Das Ersetzen iiiiimit v, iiiimit ivund vivmit ixscheint ein paar Bytes zu sparen.
Neil
Die Verkürzung Ihrer Zeilennummer scheint jedoch falsch zu sein 345-356- ich hatte damit gerechnet 345-56.
Neil
@Neil Hoppla, hab die kleene Erweiterung vergessen. Trotzdem danke für den Tipp!
FryAmTheEggman
Können Sie \bam Ende der letzten Ersetzung verwenden, um zu vermeiden, dass Sie die Ersetzung wiederholen müssen )?
Neil
@Neil Ich dachte nicht, dass das funktionieren würde, da ich dachte, ich müsste es verwenden, \daber es scheint zu funktionieren, da es keine andere Wortgrenze gibt. Vielen Dank!
FryAmTheEggman
4

PHP> = 7.1, 195 Bytes

preg_match_all("#\d+#",$argn,$t);[[$a,$s,$b,$e]]=$t;for(;$e&&~$c=$e[$k-=1];$p="-".substr($e,$i))$c>$b[$k]&&$i=$k;echo"(",strtoupper(($r=[_,i,ii,iii,iv,v,vi,vii,viii,ix])[$a]),".$r[$s].$b",$p,")";

Testfälle

Erweitert

preg_match_all("#\d+#",$argn,$t); # match for all groups of digits
[[$a,$s,$b,$e]]=$t; # shorter variables names for these groups
for(;$e&&~$c=$e[$k-=1];$p="-".substr($e,$i)) # prepare the seceond line if exists
  $c>$b[$k]&&$i=$k; 
echo"(" # print the char (
,strtoupper(($r=[_,i,ii,iii,iv,v,vi,vii,viii,ix])[$a]) # print the upper roman digit for Act
,".$r[$s].$b" # print the lower roman digit for Scene and the first line with trailing "."
,$p # print shorted second Line
,")"; #Print the closing )
Jörg Hülsermann
quelle
1
preg_match_all("#\d+#",$argn,$m);[$a,$s,$b,$e]=$m[0];spart zwei Bytes. if($e){for(;$b[$i]==$e[$i];$i++);echo"-",substr($e,$i);}echo")";sollte 46 (you do not have to support past 5)speichern. spart 15 Bytes.
Titus
1
".$r[$s].$b"spart weitere 5 Bytes; und [[$a,$s,$b,$e]]=$m;noch einer. Leider funktionieren Array-Zuweisungen (noch) nicht per Referenz.
Titus
if($e&&$e-$b){for($x=str_pad($b,strlen($e),0,0);$x[$i]==$e[$i];$i++);echo"-",substr($e,$i);}Spart 10 Bytes und funktioniert möglicherweise.
Titus
Sieht für mich gut aus . Und &&$e-$bist für die Testfälle unnötig; so spart es 17 Bytes, nicht 10. Btw. du brauchst noch keine römischen 6 bis 9.;)
Titus
1
Sie könnten ersetzen for(;str_pad($b,strlen($e),0,0)[$i]==$e[$i];)$i++;mit for(;$e&&~$c=$e[-++$k];)$c>$b[-$k]&&$i=-$k;.
Christoph
3

Perl 5, 185 + 1 = 186 Bytes

1-Byte-Strafe für das erforderliche -nFlag.

Kann für einige Testfälle fehlschlagen, in denen die Szene mehr als 10 ^ 11 Zeilen hat, aber AFAIK keine Shakespeare-Szenen sind ziemlich lang;)

y/A-z //d;while($x++<9){s/,(\d+)(\d{$x})-\g1(\d{$x}\))/,$1$2-$3/};@F=split/,/;for($F[0],$F[1]){$_.='i'while(y/2-91/1-8/d);s/i{5}/v/g;s/i{4}/iv/;s/v(i)?v/$1x/;s/$/,/};$F[0]=uc$F[0];say@F

In lesbarer Form:

y/A-z //d; #Delete all characters besides numbers, parenthesis, and comma
while($x++<9){s/,(\d+)(\d{$x})-\g1(\d{$x}\))/,$1$2-$3/}; #Shortens the line numbers. Super ugly, but my simpler code broke on test case 2- that fix added 26 bytes :( I'll revisit this later, perhaps...
@F=split/,/; #Splits the input into an array so we can mess with the act and scene without messing with the lines
for($F[0],$F[1]){ #For loop over the act and scene
    $_.='i'while(y/2-91/1-8/d); #Recursively turn numbers into naive Roman numerals (i.e. 9 would be iiiiiiiii)
    s/i{5}/v/g;s/i{4}/iv/;s/v(i)?v/$1x/;s/$/,/ #Substitution rules to convert naive Roman numerals into real Roman numerals and add a comma to the end
}
$F[0]=uc$F[0]; #Convert act to uppercase
say@F #Output
Chris
quelle
2

Ruby , 204 + 1 = 205 Bytes

Verwendet die -pFlagge.

d=[r=%w"i ii iii iv v vi vii viii ix",r.map(&:upcase)]
i=-1
gsub(/\w+ ([\d-]+)/){(a=d.pop)?a[$1.hex]:(a,b=$1.split ?-;b ?(a="%0#{b.size}d"%a;b[0]=""while b[0]==a[i+=1];a.sub(/^0*/){}+?-+b):a)}
gsub", ",?.

Probieren Sie es online!

Wert Tinte
quelle
2

Python 2.7 298 Bytes

import re
r=lambda n:'iiiviiix'[2*(n>3)+(n>4)+3*(n>8):n-(n>4)]
o=lambda x,y,n=0:n*(len(x)==len(y))if not x or x[0]!=y[0]else o(x[1:],y[1:],n+1)
q=lambda a,s,g,h:(r(int(a)).upper(),r(int(s)),g+'-'+h[o(g,h):]if h else g)
f=lambda p:'(%s.%s.%s)'%q(*re.match('\D*(\d)\D*(\d)\D*(\d+).(\d*)',p).groups())
Chas Brown
quelle
2

Perl, 99 Bytes

/(.+)(-\1|.(?2).)\b/;@r=(s/-$1/-/,I,II,III,IV,V,VI,VII,VIII,IX);s/Act(.+)(.,).+ /$r[$1].\L$r[$2]./

Laufen Sie mit perl -pe. 98 Byte (Quelle) + 1 Byte ( pFlag) = 99.

Grimmig
quelle
Zum Zeitpunkt dieses Postings gab es eine andere Perl-Antwort ( codegolf.stackexchange.com/a/123400/6484 ), die jedoch 186 Byte lang ist und ganz andere Ideen verwendet. Ich fand es daher angemessen, eine separate Antwort zu geben.
Grimmy
Dies scheint verschwenderisch zu sein, da hier Vorkehrungen für römische Ziffern nach 5 getroffen werden müssen
Hagen von Eitzen,
2
@HagenvonEitzen die Herausforderung gibt an, dass Sie römische Ziffern bis 9 unterstützen müssen. Testfall 3 hat "Szene 9" und Testfall 6 hat "Szene 8"; beide würden scheitern, wenn ich nur römische Ziffern bis 5 unterstütze.
Grimmy
2

Python 2 , 301 259 252 221 Bytes

Satte -31 Bytes dank Chas Brown.

Also, ähm, das ist ... extrem lang ... Ich glaube, ich kann Golf spielen, aber ich habe mir eine Weile das Gehirn zerbrochen.

import re
def f(s):s,r=re.match(r'.*?(\d),.*?(\d), .*? (\d*)(\d*-?)\3(\d*)',s),'0 i ii iii iv v vi vii viii ix'.split();b,c,d,e,f=s.groups();print'(%s.%s.%s)'%(r[int(b)].upper(),r[int(c)],d+e+(f if len(e)>len(f)else d+f))

Probieren Sie es online!

Nervenzusammenbruch

import re                     # re module for regex stuff

def f(s):                     # function that accepts one argument

    s, r = (re.match(r'.*?(\d),.*?(\d), .*? (\d*)(\d*-?)\3(\d*)', s),
           # match the string and capture the important parts using regex

           '0 i ii iii iv v vi vii viii ix'.split()
           # array that stores roman numerals

    b, c, d, e, f = s.groups()
                    # all the numbers from the match to variables

    print '(%s.%s.%s)' % (
                              r[int(b)].upper(),
                              # get the respective roman numeral and make it uppercase

                              r[int(c)],
                              # get the respective roman numeral

                              d + e + (f if len(e) > len(f) else d + f)
                              # shorten the second number if it's shorter than the first number
                         )
total menschlich
quelle
Sie können ein wenig sparen, indem Sie b,c,d,e,f=s.groups()anstelle vona,b,c,d,e,f=[s.group(n) for n in range(6)]
Chas Brown
Und weitere 5 durch Verwenden von [0]+'i,ii,iii,iv,v,vi,vii,viii,ix'.split(',')anstelle von [s,'i','ii','iii','iv','v','vi','vii','viii','ix'].
Chas Brown
Geändert - und weitere 8 durch Verwenden von [0]+'i ii iii iv v vi vii viii ix'.split()anstelle von [s,'i','ii','iii','iv','v','vi','vii','viii','ix'].
Chas Brown
Oh, huh, ich wusste nicht, dass du das kannst. Vielen Dank!
Totalhuman
Netter Tweak, der das 0Innere der Anführungszeichen setzt. Eine letzte kleinere zwicken kann ich sehen: Sie verwenden: s,r=XXX,YYY;b,c,d,e,f=s.groups();Sie weitere 4 Bytes statt speichern kann äquivalent zu sagen: b,c,d,e,f=XXX.groups();r=YYY;. Sie haben also 81 Bytes weniger als ich! :)
Chas Brown
2

q / kdb + 200 187 Bytes

Lösung:

f:{R:(($:)N:(!)11)!($:)``i`ii`iii`iv`v`vi`vii`viii`ix`x;S:","vs x inter .Q.n,",-";L:"-"vs P:S 2;"(",("."sv(upper R S 0;R S 1;$[{x[y]=x z}[#:;F:L 0;T:L 1];F,"-",((*:)N(&:)F<>T)_T;P])),")"}

Beispiele:

q)f "(Act 1, Scene 2, Lines 345-346)"
"(I.ii.345-6)"
q)f "(Act 3, Scene 4, Lines 34-349)"
"(III.iv.34-349)"
q)f "(Act 5, Scene 9, Lines 123-234)"
"(V.ix.123-234)"
q)f "(Act 3, Scene 4, Line 72)"
"(III.iv.72)"
q)f "(Act 2, Scene 3, Lines 123-133)"
"(II.iii.123-33)"
q)f "(Act 4, Scene 8, Lines 124-133)"
"(IV.viii.124-33)"

Erklärung: (leicht ungolfed)

f:{
  // create map of 0->10 to roman numerals, e.g. "5" -> "v"
  R:(($:)N:(!)11)!($:)``i`ii`iii`iv`v`vi`vii`viii`ix`x;
  // remove everything from the input string except -, then split on ,
  S:","vs x inter .Q.n,",-";
  // split the final field on '-', also save final field in variable P
  L:"-"vs P:S 2;
  // if the length of from/to lines are the same then find the first character
  // where they differ, and cut this many characters from the 'to' string
  M:$[{x[y]=x z}[#:;F:L 0;T:L 1];F,"-",((*:)N(&:)F<>T)_T;P];
  // join everything together, use act/scene to index into 
  // the roman numeral map, uppercase the act
  "(",("."sv(upper R S 0;R S 1;M)),")"
  }

Anmerkungen:

Technisch kann es 2 Bytes kürzer sein (keine Notwendigkeit für die f:), aber es macht es einfacher, Beispiele auf diese Weise zu zeigen.

Bearbeitungen:

  • -13 Bytes; ersetzt stringdurch $:, countmit #:, tilmit (!)und firstmit (*:), um die Indizes von R in Strings umzuwandeln, damit wir Act / Scene nicht in Ints umwandeln müssen
Streetster
quelle