Referências das citações de Golf my Shakespeare

45

Enquanto escrevia meu ensaio para Shakespeare, percebi que precisava encurtar minhas referências de citações para comprimentos mais gerenciáveis. Eu já escrevia isso anteriormente:

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

Mas agora me disseram para escrevê-las assim:

(I.ii.345-6)

Claramente, eu preciso de um código de golfe para jogar um pouco as minhas citações de Shakespeare.

A tarefa

Escreva um programa ou função que, dada uma entrada de sequência seguindo os Modelos 1 ou 2, imprima ou retorne uma sequência seguindo os Modelos 3 ou 4, respectivamente. Você só precisa suportar os Atos 1 a 5 e as Cenas 1 a 9.

Modelos

Modelo 1

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

Você pode assumir que xnunca excede 5, ynunca excede 9 ae bsempre são números inteiros positivos que não excedem o valor inteiro positivo positivo máximo do seu idioma e aé sempre exclusivamente menor que b.

Modelo 2

(Act x, Scene y, Line a)

Mesmas condições do modelo 1, excluindo informações sobre b.

Modelo 3

(x.y.a-b)

Onde xé um numeral romano maiúsculo, yé um numeral romano em minúsculas ae bsão números, e bé reduzido para apenas os dígitos inferiores ao primeiro dígito diferente de igual significado a.

Modelo 4

(x.y.a)

Mesmas condições do modelo 3, excluindo informações sobre b.

Casos de teste

Let f(s)Ser a função definida na tarefa. ""indica um valor de sequência.

>>> 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 os fins deste desafio, as seguintes traduções de números arábicos para romanos devem ser suportadas:

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
fonte
Arquivos de texto são permitidos?
Dat
21
Estou realmente esperando por uma resposta no SPL.
L3viathan
5
Caso de teste:(Act 1, Scene 2, Lines 345-3499)
dzaima 29/05
11
Quem está disposto a responder em Shakespeare?
Titus
1
@ Grimy Fixed # 1, é # 2 bom?
Addison Crump

Respostas:

12

A linguagem de programação de Shakespeare (não concorrente)

Gostei muito dessa pergunta e, como havia algum interesse em uma resposta no idioma Shakespeare, aqui está uma.

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!

(Tem mais de 6000 bytes de comprimento.) Existem alguns truques, mas não tentei jogar muito, porque: (1) já contribuí com minha parte do golfe em outra resposta e (2) alterei todos os caracteres para "Página "e" Puck ", ou todas as frases de" grande, grande e grande gato ", parecem estragar a diversão. Em vez da parte que lida com números romanos, usei caracteres romanos etc. Reutilizei caracteres e instruções para economizar digitação. :-)

O programa deve ser mais direto, mas uma das rugas que vale a pena mencionar é que, quando escrevi isso, assumi que a leitura de um número inteiro funcionaria da seguinte forma scanf: (1) consumir apenas quantos caracteres da entrada corresponderem a um número inteiro e (2) no caso de falha, deixe a variável inalterada. (Usei essa segunda propriedade para distinguir entre os modelos 1 e 2 no Ato II, lendo "Linha" e tentando ler um número inteiro.) Infelizmente, acontece que há (o que considero) um erro na implementação original do o idioma em que a leitura de um número inteiro consome tudo até o final da linha e gera um erro se falhar; portanto, é necessário um patchlibspl.c para tornar o int_inputcomportamento mais parecido scanf.

E com isso, 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 nível um pouco mais alto do qual trabalhei, para ajudar alguém que tenta entender:

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 o código acima com o código final é deixado como um exercício. :-) Observe que o ShakespearePL tem aritmética, stacks e gotos, mas não possui ponteiros (apenas rótulos), portanto, implementar "sub-rotinas" como a conversão para romano é um pouco ... interessante.

ShreevatsaR
fonte
Uau, isso é lindo. Obrigado! :)
Steve Bennett
1
bate o botão upvote repetidamente
Addison Crump
9

LaTeX, 513 364 259 226 215 178 159 Bytes

Bons ensaios devem sempre ser escritos em 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)}

Isso usa o pacote xstring, pois não há exatamente um monte de manipulação de strings embutida. No lado positivo, o limite superior para a \Romanformatação embutida é maior do que o necessário em qualquer momento (mesmo para os sonetos) 2^31-1. Eu incluí \documentclass{ecv}na contagem, mas nenhum código de teste:

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

(Se você era louco o suficiente para realmente usar isso, teria que remover o nome dos macros pelo menos. Substituir macros de um caractere é uma prática ruim)

Ungolfed e comentou:

\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

Observe que nesta versão os comentários são necessários, caso contrário, a nova linha é interpretada como espaço em branco e se expande para um espaço.

Chris H
fonte
Você pode salvar três bytes usando ~como nome da macro em vez de \s. Mas na verdade você não precisa \s( \stripcommana versão ungolfed): você pode simplesmente \def\t#1 #2, #3 #4, #5 #6e o TeX cuidará de tirar as vírgulas. (Então, você poderia usar o ~truque em \tvez, economizando 1 byte.)
ShreevatsaR
@ShreevatsaR obrigado. Você descobriu como alinhar a rejeição por vírgula e era mais simples do que qualquer coisa que eu tentasse. O truque com o ativo ~é um pouco desagradável, mas eu gosto daqui. Isso significava que eu tinha que mudar o documentclass (para um dos outros 3 letras .clsarquivos que eu tinha instalado)
Chris H
1
Sim eu conto 182 bytes, que não bate apenas a resposta Python, mas também Ruby, PHP e uma das respostas Perl :-)
ShreevatsaR
1
@ShreevatsaR melhor ainda: 178 como \@roman e \@Romannão precisa de aparelho em torno do argumento.
Chris H
1
Todas as xstringidéias principais foram suas :-) Foi divertido jogar golfe juntos!
ShreevatsaR
8

JavaScript (ES6), 210 183 178 177 171 bytes

Economizou 27 bytes desenrolando os parâmetros de descanso (graças a ETHproductions )

Economizou 5 bytes não correspondendo ao parêntese de abertura e ajustando a geração do número romano

Economizou 1 byte ajustando a expressão ternária final

Economizou 6 bytes combinando dois grupos correspondentes

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 teste:

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
fonte
Não posso testar agora, mas ainda funciona se você substituir Act e cada um \D*com .*?
Patrick Roberts
Pode; Eu hesitava em tentar, porque o JavaScript emprega a correspondência gananciosa por padrão. Vou testá-lo hoje mais tarde e informar se funciona.
Gyre 30/05
8

Geléia ,  87 86  85 bytes

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

Experimente online! ou veja uma suíte de testes

Quão?

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
fonte
1
Deve
@MickyT Nope eu tenho mais lá fora ...
Jonathan Allan
Isso induz dor de cabeça. Não leia 0/10. : P
Erik the Outgolfer
@EriktheOutgolfer Sorry !!
27517 Jonathan Allan
2
Brincadeiras à parte, eu posso ver algumas coisas realmente único em que código, como œr, Ṗ,Ç, Ṗ€V, ṪÇ$, Wcomo o último elo em um link ajudante, possivelmente outros também, Nice esforço! Esta não é a sua submissão usual de 80 e poucos anos Jelly, isso merece reconhecimento especial entre as pessoas Jelly.
Erik the Outgolfer
6

R , 94 126 112 166 bytes

E agora está mais elaborado do que antes :(, voltando a tentar jogar mais. Regex por reduzir a referência da página roubada descaradamente emprestada de @FryAmTheEggman.

Agora eu realmente preciso fazer algum trabalho para recuperar os bytes, mas funciona para o segundo caso agora.

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

Experimente online! - Observe que elnão funciona no TIO e foi substituído 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
fonte
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

Experimente online!

Economizou 3 bytes graças a Neil.

Retira os caracteres desnecessários antes de substituir os dois primeiros números por blocos de icaracteres. Em seguida, combina pedaços desses is para formar os algarismos romanos apropriados. Então capitalizamos o primeiro numeral romano. Finalmente, combinamos o maior número possível de números antes e depois do hífen, de modo que o número de dígitos no número seja o mesmo. Em seguida, removemos esse prefixo do segundo número.

FryAmTheEggman
fonte
Substituir iiiiipor v, iiiipor ive vivpor ixparece economizar alguns bytes.
295 Neil
No entanto, o encurtamento do número da linha parece estar errado 345-356- eu estava esperando 345-56.
Neil
@ Neil Whoops, esqueceu a expansão kleene. De qualquer forma obrigado pela dica!
FryAmTheEggman
Você pode usar \bno final da última substituição para evitar repetir )a substituição?
Neil
@ Neil Eu não achei que funcionaria, pois achei que precisaria usar, \dmas parece funcionar, já que não há outro limite de palavras. Obrigado!
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 teste

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
fonte
1
preg_match_all("#\d+#",$argn,$m);[$a,$s,$b,$e]=$m[0];salva dois bytes. if($e){for(;$b[$i]==$e[$i];$i++);echo"-",substr($e,$i);}echo")";deve salvar 46. (you do not have to support past 5)salva 15 bytes.
Titus
1
".$r[$s].$b"salva outros 5 bytes; e [[$a,$s,$b,$e]]=$m;outro. Infelizmente, as atribuições de array ainda não funcionam por referência.
Titus
if($e&&$e-$b){for($x=str_pad($b,strlen($e),0,0);$x[$i]==$e[$i];$i++);echo"-",substr($e,$i);}economiza 10 bytes e pode funcionar.
Titus
Parece bom para mim . E &&$e-$bé desnecessário para os casos de teste; então ele salva 17 bytes, não 10. Btw. você ainda não precisa de romanos 6 a 9.;)
Titus
1
Você pode substituir for(;str_pad($b,strlen($e),0,0)[$i]==$e[$i];)$i++;por for(;$e&&~$c=$e[-++$k];)$c>$b[-$k]&&$i=-$k;.
Christoph
3

Perl 5, 185 + 1 = 186 bytes

Penalidade de 1 byte para a -nbandeira necessária .

Pode falhar em alguns casos de teste em que a cena tem mais de 10 ^ 11 linhas, mas as cenas do AFAIK no Shakespeare são muito longas;)

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

De forma legível:

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

Ruby , 204 + 1 = 205 bytes

Usa a -pbandeira.

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

Experimente online!

Value Ink
fonte
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
fonte
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]./

Corra com perl -pe. 98 bytes (origem) + 1 byte ( psinalizador) = 99.

Grimmy
fonte
No momento desta postagem, havia outra resposta Perl ( codegolf.stackexchange.com/a/123400/6484 ), mas ela tem 186 bytes de comprimento e usa idéias muito diferentes, então achei que fazer uma resposta separada era apropriada.
Grimmy
Este parece ser um desperdício, pois leva provisões para algarismos romanos além de 5
Hagen von Eitzen
2
@HagenvonEitzen, o desafio especifica que você precisa suportar números romanos de até 9. O caso de teste 3 tem “Cena 9” e o caso de teste 6 tem “Cena 8”; tanto seria um fracasso se eu suportado apenas algarismos romanos até 5.
Grimmy
2

Python 2 , 301 259 252 221 bytes

A -31 bytes gritante graças a Chas Brown.

Então, isso é ... extremamente longo ... Acho que posso jogar golfe, mas estou rachando meu cérebro há um tempo.

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

Experimente online!

Demolir

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
fonte
Você pode economizar um pouco usando b,c,d,e,f=s.groups()em vez dea,b,c,d,e,f=[s.group(n) for n in range(6)]
Chas Brown
E outros 5 usando em [0]+'i,ii,iii,iv,v,vi,vii,viii,ix'.split(',')vez de [s,'i','ii','iii','iv','v','vi','vii','viii','ix'].
Chas Brown
Alterado - e outros 8 usando em [0]+'i ii iii iv v vi vii viii ix'.split()vez de [s,'i','ii','iii','iv','v','vi','vii','viii','ix'].
Chas Brown
Ah, não sabia que você poderia fazer isso. Obrigado!
totallyhuman
Tweak agradável colocando o 0interior das aspas. Uma última menor puxão eu posso ver: você está usando: s,r=XXX,YYY;b,c,d,e,f=s.groups();você pode economizar mais 4 bytes por vez equivalentemente dizendo: b,c,d,e,f=XXX.groups();r=YYY;. Então você acaba com 81 bytes a menos do que o meu envio! :)
Chas Brown
2

q / kdb +, 200 187 bytes

Solução:

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

Exemplos:

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

Explicação: (ligeiramente não-destruído)

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:

Tecnicamente, pode ser 2 bytes mais curto (sem necessidade de f:), mas facilita a exibição de exemplos dessa maneira.

Editar% s:

  • -13 bytes; substituído stringpor $:, countcom #:, tilcom (!)e firstcom (*:), lança os índices de R em seqüências de caracteres, para que não tenhamos que converter ato / cena em ints
rua
fonte