Гольф мої посилання на Шекспіра


45

Під час написання реферату для Шекспіра я зрозумів, що мені потрібно скоротити свої посилання на цитати до більш керованих завдань. Я раніше писав це:

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

Але мені зараз сказали написати їх так:

(I.ii.345-6)

Зрозуміло, мені потрібен якийсь код для гольфу, щоб трохи знизити посилання на цитати Шекспіра.

Задача

Напишіть програму або функцію, яка, даючи рядок введення за шаблоном 1 або 2, друкує або повертає рядок відповідно до шаблону 3 або 4 відповідно. Вам потрібно лише підтримувати Дії 1 - 5 та Сценки 1 - 9.

Шаблони

Шаблон 1

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

Ви можете припустити, що xніколи не перевищує 5, yніколи не перевищує 9 aі bзавжди є додатними цілими числами, що не перевищують максимальне додатне стандартне ціле значення вашої мови, а aзавжди виключно менше b.

Шаблон 2

(Act x, Scene y, Line a)

Ті ж умови, що і Шаблон 1, за винятком інформації про b.

Шаблон 3

(x.y.a-b)

Де xє велика римська цифра, yє малою римською цифрою, aі bце числа, і bїї скорочують лише до цифр, менших від першої різної цифри, що має однакове значення від a.

Шаблон 4

(x.y.a)

Ті ж умови, що і Шаблон 3, за винятком інформації про b.

Випробування

Нехай f(s)буде функція, визначена у Завданні. ""позначає значення рядка.

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

Для цілей цього виклику слід підтримувати такі переклади з арабської на римську цифру:

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

Чи дозволені текстові файли?
Дат

21
Я дуже сподіваюся на відповідь у SPL.
L3viathan

5
Тестовий випадок:(Act 1, Scene 2, Lines 345-3499)
dzaima

11
Хто готовий відповісти в Шекспіра?
Тіт

1
@Grimy Виправлено №1, чи добре 2?
Аддісон Кримп

Відповіді:


12

Мова програмування Шекспіра (неконкурентна)

Мені дуже сподобався цей питання, і як це було якийсь - то інтерес в Shakespeare мовою відповідь на, ось один.

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!

(Тут більше 6000 байтів.) Тут є деякі хитрощі, але я не намагався його багато в гольфі, тому що: (1) Я вже вніс свою частку гольфу на іншу відповідь, і (2) змінив усіх символів на "Сторінка "і" Шайба ", або всі фрази" великий великий великий великий великий кіт ", схоже, псують задоволення. Натомість для частини, яка стосується римських цифр, я використав символи, які є римлянами, і т. Д. Я повторно використовував символи та інструкції, щоб зберегти деякі введення тексту. :-)

Програма повинна бути в основному простою, але одна зморшка, яку варто згадати, полягає в тому, що коли я писав це, я припускав, що читання цілого числа спрацює так scanf: (1) споживає лише стільки символів з вводу, скільки відповідає цілому числу, і (2) у випадку невдачі, залиште змінну незмінною. (Я використовував це друге властивість для розрізнення шаблону 1 і 2 в акті II, читаючи до "Рядок" і намагаючись прочитати ціле число.) На жаль, виявляється, що в початковій реалізації програми є (що я вважаю) помилка мова, де читання цілого числа споживає все до кінця рядка і видає помилку, якщо воно не вдається, тому йому потрібен патч,libspl.c щоб змусити int_inputсебе вести себе схожіше scanf.

І з цим воно працює:

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

Трохи вищий псевдокод, над яким я працював, щоб допомогти зрозуміти:

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

Пов'язане вищезазначене з кінцевим кодом залишається як вправа. :-) Зауважте, що у ShakespearePL є арифметика та стеки та готи, але немає покажчиків (лише мітки), тому реалізація "підпрограм" на зразок переходу на римську трохи ... цікава.


Вау, це прекрасно. Дякую! :)
Стів Беннетт

1
кілька разів плескає кнопку оновлення
Addison Crump

9

LaTeX, 513 364 259 226 215 178 159 байт

Хороші нариси завжди повинні писатися в 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)}

Для цього використовується пакет xstring, оскільки вбудовано не дуже багато обробних рядків. На плюсі ​​сторона верхньої межі вбудованого \Romanформатування більша, ніж нам коли-небудь знадобиться (навіть для сонетів) на 2^31-1. Я включив \documentclass{ecv}до складу підрахунку, але жоден з тестових кодів:

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

(Якщо ви були досить божевільні, щоб реально користуватися цим, вам доведеться принаймні скасовувати імена макросів. Переписування макросів одного символу - це погана практика)

Негольфірованний і прокоментував:

\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

Зауважте, що в цій версії коментарі потрібні, інакше нова лінія інтерпретується як пробіл і розширюється на пробіл.


Ви можете зберегти три байти, використовуючи ~замість імені макросу \s. Але насправді вам взагалі не потрібно \s( \stripcommaу безгольовій версії): ви просто можете, \def\t#1 #2, #3 #4, #5 #6і TeX подбає про те, щоб зняти коми. (Таким чином, ви можете використовувати ~фокус \tнатомість, економлячи 1 байт.)
ShreevatsaR

@ShreevatsaR дякую Ви придумали, як зробити відхилення коми через ряд, і це було простіше всього, що я намагався. Трюк з активним ~трохи неприємний, але мені тут подобається. Це означало, що мені довелося змінити .cls
Chris H

1
Так, я нараховую 182 байти, що перемагає не лише відповідь Python, але й Ruby, PHP та одну з відповідей Perl :-)
ShreevatsaR

1
@ShreevatsaR ще краще: 178 як \@roman і \@Romanне потрібні дужки навколо аргументу.
Кріс Х

1
Всі основні xstringідеї були вашими :-) Це було весело гольфувати разом!
ShreevatsaR

8

JavaScript (ES6), 210 183 178 177 171 байт

Збережено 27 байт, розгорнувши параметри відпочинку (завдяки ETHproductions )

Збережено 5 байтів, не збігаючись з початковим паролем та налаштовуючи покоління римських цифр

Збережено 1 байт, скоригувавши кінцевий потрійний вираз

Збережено 6 байтів, об’єднавши дві групи, що збігаються

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

Випробування:

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


Я зараз не можу перевірити, але чи все ще він працює, якщо ви заміните Act і кожен \D*з .*?
Патрік Робертс

Це могло б; Я вагався, щоб спробувати, тому що JavaScript використовує жадібну відповідність за замовчуванням. Я протестую це пізніше сьогодні, і я повідомлю вам, чи працює він.
gyre

8

Желе ,  87 86  85 байт

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

Спробуйте в Інтернеті! або переглянути тестовий набір

Як?

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

1
Це повинен бути якийсь запис для сценарію Jelly
MickyT

@MickyT Nope У мене довше ...
Джонатан Аллан

Це викликає головний біль. Не читайте це 0/10. : P
Ерік Аутгольфер

@EriktheOutgolfer Вибачте !!
Джонатан Аллан

2
Жарти в сторону, я можу побачити деякі дійсно унікальні речі в цьому коді, як œr, Ṗ,Ç, Ṗ€V, ṪÇ$, Wяк останню ланку на хелпер посилання, можливо , інші теж, хороші зусилля! Це не ваше звичайне подання на 80-ти желе, це заслуговує особливого визнання серед людей желе.
Ерік Аутгольфер

6

R , 94 126 112 166 байт

А тепер це складніше, ніж раніше :(, повернутися до спроб додатково гольфувати. Regex для зменшення посилання на сторінку безсоромно викраденого запозиченого у @FryAmTheEggman.

Зараз мені справді потрібно виконати деяку роботу, щоб повернути байти, але це працює для другого випадку зараз.

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

Спробуйте в Інтернеті! - Зауважте, що elTIO не працює і його заміненоunlist

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

4

Сітківка ,89 88 байт

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

Спробуйте в Інтернеті!

Збережено 3 байти завдяки Нілу.

Викресліть непотрібні символи, перш ніж замінити перші два числа блоками iсимволів. Тоді вона відповідає шматкам цих iс, щоб утворити відповідні римські цифри. Тоді ми пишемо великі літери першої римської цифри. Нарешті ми підбираємо стільки чисел, скільки ми можемо перед дефісом та після дефісу, таким чином, що число цифр у номері однакове. Потім вилучаємо цей префікс з другого числа.


Заміна iiiiiна v, iiiiз ivі vivна, ixздається, заощадить пару байтів.
Ніл

Однак, скорочення номера рядка, здається, не так 345-356- я очікував 345-56.
Ніл

@Neil Уотс, забув розширення kleene. Все одно дякую за пораду!
FryAmTheEggman

Чи можете ви використовувати \bв кінці останньої заміни, щоб уникнути повтору )заміни?
Ніл

@Neil Я не думав, що це спрацює, оскільки я вважав, що мені потрібно використовувати, \dале, здається, це працює, оскільки немає іншої межі слова. Дякую!
FryAmTheEggman

4

PHP> = 7,1, 195 байт

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

Тестові шафи

Розширено

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 )

1
preg_match_all("#\d+#",$argn,$m);[$a,$s,$b,$e]=$m[0];економить два байти. if($e){for(;$b[$i]==$e[$i];$i++);echo"-",substr($e,$i);}echo")";має зекономити 46. (you do not have to support past 5)економить 15 байт.
Тит

1
".$r[$s].$b"економить ще 5 байт; і [[$a,$s,$b,$e]]=$m;ще один. На жаль, призначення масивів не працює за посиланням (поки).
Тіт

if($e&&$e-$b){for($x=str_pad($b,strlen($e),0,0);$x[$i]==$e[$i];$i++);echo"-",substr($e,$i);}економить 10 байт і може працювати.
Тіт

Мені все гаразд . І &&$e-$bце не потрібно для тестових випадків; тому це економить 17 байт, а не 10. Btw. ти все ще не потребуєш римських 6 до 9;)
Тит

1
Ви можете замінити for(;str_pad($b,strlen($e),0,0)[$i]==$e[$i];)$i++;на for(;$e&&~$c=$e[-++$k];)$c>$b[-$k]&&$i=-$k;.
Крістоф

3

Perl 5, 185 + 1 = 186 байт

1 байт штрафу за потрібний -nпрапор.

Може не вдатися до деяких тестових випадків, коли сцена має більше 10 ^ 11 рядків, але сцени AFAIK без Шекспіра досить довгі;)

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

У читаному вигляді:

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


2

Python 2.7 298 байт

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

2

Perl, 99 байт

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

Бігайте з perl -pe. 98 байт (джерело) + 1 байт ( pпрапор) = 99.


На момент публікації повідомлення є ще одна відповідь Perl ( codegolf.stackexchange.com/a/123400/6484 ), але вона становить 186 байт і використовує дуже різні ідеї, тому я вважав, що окрема відповідь є доречною.
Grimmy

Це здається марним, оскільки воно передбачає положення для римських цифр після 5
Хаген фон Ейтцен

2
@HagenvonEitzen у виклику вказується, що ви повинні підтримувати римські цифри до 9. У тестовому випадку 3 є "Сцена 9", а в тестовому випадку 6 - "Сцена 8"; і те, і інше не вдасться, якби я підтримував лише римські цифри до 5.
Гриммі

2

Python 2 , 301 259 252 221 байт

Цілих -31 байт завдяки Шасу Брауну.

Отож, е-е, це ... надзвичайно довго ... Я думаю, що можу це в гольф, але я певний час закручував мозок.

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

Спробуйте в Інтернеті!

Зламатися

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
                         )

Можна трохи заощадити, скориставшись b,c,d,e,f=s.groups()замістьa,b,c,d,e,f=[s.group(n) for n in range(6)]
Chas Brown

І ще 5, використовуючи [0]+'i,ii,iii,iv,v,vi,vii,viii,ix'.split(',')замість [s,'i','ii','iii','iv','v','vi','vii','viii','ix'].
Час Браун

Змінено - І ще 8 за допомогою [0]+'i ii iii iv v vi vii viii ix'.split()замість [s,'i','ii','iii','iv','v','vi','vii','viii','ix'].
Час Браун

О, так, не знав, що ти можеш це зробити. Дякую!
повністюлюдсько

Хороший твіт, поклавши 0всередину котирування. Один останній неповнолітній Твік я бачу: ви використовуєте: s,r=XXX,YYY;b,c,d,e,f=s.groups();ви можете зберегти ще 4 байта на замість того, щоб той же самий , кажучи: b,c,d,e,f=XXX.groups();r=YYY;. Таким чином, у вас на 81 байт менше, ніж моє подання! :)
Час Браун

2

q / kdb +, 200 187 байт

Рішення:

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

Приклади:

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

Пояснення: (злегка неозорений)

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

Примітки:

Технічно це може бути на 2 байти коротше (не потрібно f:), але полегшує показ прикладів таким чином.

Зміни:

  • -13 байт; замінено stringна $:, countна #:, tilз (!)і firstз (*:), привласнити індекси R до рядків, так що нам не доведеться вводити акт / сцену в ints
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.