Golf my Shakespeare cita referencias

45

Mientras escribía mi ensayo para Shakespeare, me di cuenta de que necesitaba acortar mis referencias de citas a longitudes más manejables. Anteriormente había estado escribiendo esto:

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

Pero ahora me han dicho que los escriba así:

(I.ii.345-6)

Claramente, necesito un código de golf para jugar un poco mis referencias de citas de Shakespeare.

La tarea

Escriba un programa o función que, dada una entrada de cadena que sigue a la Plantilla 1 o 2, imprima o devuelva una cadena que siga a la Plantilla 3 o 4, respectivamente. Solo tiene que admitir los actos 1 a 5 y las escenas 1 a 9.

Plantillas

Plantilla 1

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

Puede suponer que xnunca excede 5, ynunca excede 9, ay bsiempre son enteros positivos que no exceden el valor entero positivo máximo de su idioma, y asiempre es exclusivamente menor que b.

Plantilla 2

(Act x, Scene y, Line a)

Las mismas condiciones que la Plantilla 1, excluyendo información sobre b.

Plantilla 3

(x.y.a-b)

Donde xes un número romano en mayúscula, yes un número romano en minúscula ay bson números, y bse acorta a solo los dígitos menores que el primer dígito diferente de igual importancia a.

Plantilla 4

(x.y.a)

Las mismas condiciones que la Plantilla 3, excluyendo información sobre b.

Casos de prueba

Deje f(s)ser la función definida en la Tarea. ""denota un valor de cadena.

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

Para los propósitos de este desafío, se deben admitir las siguientes traducciones de números arábigos a romanos:

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
fuente
¿Se permiten archivos de texto?
Dat
21
Realmente espero una respuesta en SPL.
L3viathan
55
Caso de prueba:(Act 1, Scene 2, Lines 345-3499)
dzaima
11
¿Quién quiere una respuesta en Shakespeare?
Tito
1
@Grimy Corregido # 1, ¿es bueno el # 2?
Addison Crump

Respuestas:

12

El lenguaje de programación de Shakespeare (no competidor)

Realmente me gustó esta pregunta, y como había algún interés en una respuesta en lenguaje Shakespeare, aquí hay una.

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!

(Tiene más de 6000 bytes de longitud). Hay algunos trucos allí, pero no he intentado jugar mucho al golf porque: (1) ya contribuí mi parte del golf en otra respuesta y (2) cambié todos los caracteres a "Página "y" Puck ", o todas las frases para" big big big big big cat ", parecen estropear la diversión. En cambio, para la parte que trata con números romanos, he usado caracteres que son romanos, etc. Reutilicé caracteres e instrucciones para guardar algo de mecanografía. :-)

El programa debería ser en su mayoría directo, pero una arruga que vale la pena mencionar es que cuando escribí esto asumí que leer un número entero funcionaría de la siguiente manera scanf: (1) consumir solo tantos caracteres de la entrada como corresponda a un número entero, y (2) en caso de que de falla, deje la variable sin cambios. (Usé esta segunda propiedad para distinguir entre la Plantilla 1 y 2 en el Acto II, leyendo hasta "Línea" e intentando leer un número entero.) Desafortunadamente, resulta que (lo que considero) es un error en la implementación original de el lenguaje en el que leer un número entero consume todo hasta el final de la línea y arroja un error si falla, por lo que necesita un parchelibspl.c para que se int_inputcomporte más scanf.

Y con eso, funciona:

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

Pseudocódigo de nivel ligeramente superior en el que trabajé, para ayudar a cualquiera que intente comprender:

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

Relacionar lo anterior con el código final se deja como ejercicio. :-) Tenga en cuenta que ShakespearePL tiene aritmética y pilas y gotos pero no punteros (solo etiquetas), por lo que implementar "subrutinas" como la conversión a Roman es un poco ... interesante.

ShreevatsaR
fuente
Wow, eso es hermoso ¡Gracias! :)
Steve Bennett
1
golpea repetidamente el botón de votación positiva
Addison Crump
9

LaTeX, 513 364 259 226 215 178 159 Bytes

Los buenos ensayos siempre deben escribirse en LaTeX.

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

Esto utiliza el paquete xstring ya que no hay una gran cantidad de manejo de cadenas incorporado. En el lado positivo, el límite superior para el \Romanformato incorporado es mayor de lo que necesitaremos (incluso para los sonetos) 2^31-1. He incluido \documentclass{ecv}en el recuento, pero ninguno del código de prueba:

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

(Si estuvieras lo suficientemente loco como para usar esto, tendrías que eliminar los nombres de macro al menos. Sobrescribir macros de un solo carácter es una mala práctica)

Ungolfed y comentó:

\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

Tenga en cuenta que en esta versión los comentarios son obligatorios; de lo contrario, la nueva línea se interpreta como un espacio en blanco y se expande a un espacio.

Chris H
fuente
Puede guardar tres bytes si los usa ~como nombre de macro en lugar de \s. Pero en realidad no es necesario \s( \stripcommaen la versión no dirigida): puede \def\t#1 #2, #3 #4, #5 #6hacerlo y TeX se encargará de quitar las comas. (Para que puedas usar el ~truco \t, ahorrando 1 byte.)
ShreevatsaR
@ShreevatsaR gracias. Descubriste cómo poner en línea el rechazo de coma y fue más simple que cualquier cosa que intenté. El truco con el activo ~es un poco desagradable, pero me gusta aquí. Significaba que tenía que cambiar la clase de documento (a uno de los otros .clsarchivos de 3 letras que había instalado)
Chris H
1
Sí, cuento 182 bytes, que supera no solo la respuesta de Python sino también Ruby, PHP y una de las respuestas de Perl :-)
ShreevatsaR
1
@ShreevatsaR aún mejor: 178 como \@roman y \@Romanno necesita llaves alrededor del argumento.
Chris H
1
Todas las xstringideas principales fueron suyas :-) ¡Fue divertido jugar golf juntos!
ShreevatsaR
8

JavaScript (ES6), 210 183 178 177 171 bytes

Ahorró 27 bytes desenrollando parámetros de reposo (gracias a ETHproductions )

Ahorró 5 bytes al no coincidir con el par de apertura y al ajustar la generación de números romanos

Se guardó 1 byte ajustando la expresión ternaria final

Se guardaron 6 bytes combinando dos grupos coincidentes

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

Casos de prueba:

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

giro
fuente
No puedo probar en este momento, pero ¿sigue funcionando si reemplazas Act y cada uno \D*con .*?
Patrick Roberts
Que podría; Dudé en intentarlo porque JavaScript emplea la coincidencia codiciosa por defecto. Lo probaré más tarde hoy y le haré saber si funciona.
giro
8

Gelatina ,  87 86  85 bytes

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

Pruébalo en línea! o ver un conjunto de pruebas

¿Cómo?

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
fuente
1
Eso tiene que ser algún tipo de registro para un guión Jelly
MickyT
@MickyT No, tengo más tiempo ahí afuera ...
Jonathan Allan
Esto induce dolor de cabeza. No lo leas 0/10. : P
Erik the Outgolfer
@EriktheOutgolfer ¡Lo siento!
Jonathan Allan
2
Bromas aparte, me pueden ver algunas cosas realmente único en ese código, como œr, Ṗ,Ç, Ṗ€V, ṪÇ$, Wcomo el último eslabón en un enlace de ayuda, posiblemente, otros también, buen esfuerzo! Esta no es su presentación habitual de Jelly de los 80, merece un reconocimiento especial entre las personas Jelly.
Erik the Outgolfer
6

R , 94 126 112 166 bytes

Y ahora es más extenso que antes :(, volviendo a intentar jugar más golf. Regex para reducir la referencia de la página robada descaradamente prestada de @FryAmTheEggman.

Ahora realmente necesito hacer algo de trabajo para recuperar los bytes, pero ahora funciona para el segundo caso.

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

Pruébalo en línea! - Tenga en cuenta que elno funciona en TIO y ha sido reemplazado porunlist

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
fuente
4

retina ,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

Pruébalo en línea!

Guardado 3 bytes gracias a Neil.

Elimina los caracteres innecesarios antes de reemplazar los dos primeros números con bloques de icaracteres. Luego hace coincidir fragmentos de estos is para formar los números romanos apropiados. Luego capitalizamos el primer número romano. Finalmente, hacemos coincidir tantos números como podamos antes del guión y después del guión, de modo que el número de dígitos en el número sea el mismo. Luego eliminamos ese prefijo del segundo número.

FryAmTheEggman
fuente
Reemplazar iiiiicon v, iiiicon ivy vivcon ixparece ahorrar un par de bytes.
Neil
Sin embargo, su acortamiento del número de línea parece estar equivocado 345-356, esperaba 345-56.
Neil
@Neil Whoops, olvidé la expansión de Kleene. De todos modos gracias por el consejo!
FryAmTheEggman
¿Se puede usar \bal final del último reemplazo para evitar tener que repetirlo )en la sustitución?
Neil
@Neil No pensé que funcionaría ya que pensé que tendría que usarlo, \dpero parece funcionar ya que no hay otro límite de palabras. ¡Gracias!
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,")";

Casos de prueba

Expandido

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
fuente
1
preg_match_all("#\d+#",$argn,$m);[$a,$s,$b,$e]=$m[0];Guarda dos bytes. if($e){for(;$b[$i]==$e[$i];$i++);echo"-",substr($e,$i);}echo")";debería guardar 46. (you do not have to support past 5)ahorra 15 bytes.
Tito
1
".$r[$s].$b"guarda otros 5 bytes; y [[$a,$s,$b,$e]]=$m;otro Desafortunadamente, las asignaciones de matrices no funcionan por referencia (todavía).
Tito
if($e&&$e-$b){for($x=str_pad($b,strlen($e),0,0);$x[$i]==$e[$i];$i++);echo"-",substr($e,$i);}ahorra 10 bytes y podría funcionar.
Titus
A mí me parece bien . Y &&$e-$bes innecesario para los casos de prueba; entonces ahorra 17 bytes, no 10. Por cierto. todavía no necesita roman 6 a 9.;)
Tito
1
Podrías reemplazar for(;str_pad($b,strlen($e),0,0)[$i]==$e[$i];)$i++;con for(;$e&&~$c=$e[-++$k];)$c>$b[-$k]&&$i=-$k;.
Christoph
3

Perl 5, 185 + 1 = 186 bytes

Penalización de 1 byte para la -nbandera requerida .

Puede fallar en algunos casos de prueba donde la escena tiene más de 10 ^ 11 líneas, pero AFAIK no las escenas de Shakespeare son tan largas;)

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

En forma legible:

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

Rubí , 204 + 1 = 205 bytes

Usa la -pbandera.

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", ",?.

Pruébalo en línea!

Tinta de valor
fuente
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
fuente
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]./

Corre con perl -pe. 98 bytes (fuente) + 1 byte ( pbandera) = 99.

Mugriento
fuente
En el momento de esta publicación, hay otra respuesta de Perl ( codegolf.stackexchange.com/a/123400/6484 ), pero tiene 186 bytes de largo y utiliza ideas muy diferentes, por lo que sentí que hacer una respuesta por separado era apropiado.
Grimmy
Esto parece ser un desperdicio, ya que toma disposiciones para los números romanos más allá de 5
Hagen von Eitzen
2
@HagenvonEitzen el desafío especifica que debe admitir números romanos hasta 9. El caso de prueba 3 tiene "Escena 9" y el caso de prueba 6 tiene "Escena 8"; ambos fallarían si solo
admitiera
2

Python 2 , 301 259 252 221 bytes

Un enorme -31 bytes gracias a Chas Brown.

Entonces, esto es ... extremadamente largo ... Creo que puedo jugar al golf, pero he estado destrozando mi cerebro por un tiempo.

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

Pruébalo en línea!

Descompostura

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
                         )
totalmente humano
fuente
Puede ahorrar un poco usando en b,c,d,e,f=s.groups()lugar dea,b,c,d,e,f=[s.group(n) for n in range(6)]
Chas Brown
Y otros 5 usando en [0]+'i,ii,iii,iv,v,vi,vii,viii,ix'.split(',')lugar de [s,'i','ii','iii','iv','v','vi','vii','viii','ix'].
Chas Brown
Enmendado - Y otros 8 usando en [0]+'i ii iii iv v vi vii viii ix'.split()lugar de [s,'i','ii','iii','iv','v','vi','vii','viii','ix'].
Chas Brown
Oh, eh, no sabía que podías hacer eso. ¡Gracias!
Totalmente humano
Bonito ajuste poniendo el 0interior de las comillas. Un último pequeño ajuste que se puede ver: que esté utilizando: s,r=XXX,YYY;b,c,d,e,f=s.groups();se puede ahorrar otros 4 bytes por vez diciendo lo que es equivalente: b,c,d,e,f=XXX.groups();r=YYY;. ¡Entonces terminas con 81 bytes menos que mi envío! :)
Chas Brown
2

Q / KDB +, 200 187 bytes

Solución:

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])),")"}

Ejemplos:

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

Explicación: (un poco sin golf)

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

Notas:

Técnicamente puede ser 2 bytes más corto (no es necesario f:) pero facilita mostrar ejemplos de esta manera.

Ediciones:

  • -13 bytes; reemplazado stringcon $:, countcon #:, tilcon (!)y firstcon (*:), emite los índices de R a cadenas para que no tengamos que convertir el acto / escena en int
callejero
fuente