Гольф мой Шекспир цитаты ссылки

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
Аддисон Крамп
источник
Разрешены ли текстовые файлы?
Dat
21
Я действительно надеюсь на ответ в SPL.
L3viathan
5
Тестовый кейс:(Act 1, Scene 2, Lines 345-3499)
Дзайма
11
Кто ждёт ответа в Шекспире?
Тит
1
@ Грими Исправлено # 1, # 2 хорошо?
Эддисон Крамп

Ответы:

12

Язык программирования Шекспира (не конкурирующий)

Мне очень понравился этот вопрос, и поскольку был некоторый интерес к ответу на языке Шекспира, вот один.

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) изменив все символы на «Page «и« шайба », или все фразы« большой большой большой большой большой кот », кажется, портят удовольствие. Вместо этого для части, которая имеет дело с римскими цифрами, я использовал символы, которые являются римлянами, и т. Д. Я использовал символы и инструкции повторно, чтобы сохранить некоторую печать. :-)

Программа должна быть в основном простой, но стоит упомянуть одну сложность: когда я писал это, я предполагал, что чтение целого числа будет работать так 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 есть арифметика и стеки и переходы, но нет указателей (только метки), поэтому реализация «подпрограмм», таких как преобразование в роман, немного… интересна.

ShreevatsaR
источник
Вау, это прекрасно. Спасибо! :)
Стив Беннетт
1
несколько раз хлопает по кнопке upvote
Аддисон Крамп
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
Крис Х
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 использует жадное сопоставление по умолчанию. Я проверю это позже сегодня и дам вам знать, если это работает.
круговорот
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 Нет, у меня там больше нет ...
Джонатан Аллан
Это вызывает головную боль. Не читайте это 0/10. : P
Эрик Outgolfer
@EriktheOutgolfer Извините!
Джонатан Аллан
2
Шутки в стороне, я могу увидеть некоторые действительно уникальные вещи в этом коде, как œr, Ṗ,Ç, Ṗ€V, ṪÇ$, Wкак последнее звено на хелпер ссылку, возможно , другие тоже, хорошие усилия! Это не обычное 80-летнее представление Jelly, это заслуживает особого признания среди людей Jelly.
Эрик Outgolfer
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]))

Попробуйте онлайн! - Обратите внимание, что elне работает на TIO и был заменен на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
    )
)
MickyT
источник
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символов. Затем он соответствует кускам этих is, чтобы сформировать соответствующие римские цифры. Затем мы используем заглавную первую римскую цифру. Наконец, мы сопоставляем столько цифр, сколько сможем до дефиса и после дефиса, чтобы количество цифр в числе было одинаковым. Затем мы удаляем этот префикс из второго числа.

FryAmTheEggman
источник
Замена iiiiiс v, iiiiс ivи vivс, ixкажется, экономит пару байтов.
Нил
Тем не менее, укорочение номера вашей строки, похоже, неправильно, 345-356- я ожидал 345-56.
Нейл
@Neil Ой, забыл расширение Клин. В любом случае спасибо за совет!
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,")";

Testcases

расширенный

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. Кстати. вам все еще не нужен роман с 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

Рубин , 204 + 1 = 205 байт

Использует -pфлаг.

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

Попробуйте онлайн!

Значение чернил
источник
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.

Grimmy
источник
Во время этой публикации есть другой ответ Perl ( codegolf.stackexchange.com/a/123400/6484 ), но он имеет длину 186 байт и использует совершенно разные идеи, поэтому я чувствовал, что отдельный ответ был уместен.
Grimmy
Это кажется расточительным, так как он требует положений для римских цифр после 5
Хаген фон
2
@HagenvonEitzen В задании указано, что необходимо поддерживать римские цифры до 9. В тестовом примере 3 есть «сцена 9», а в контрольном примере 6 - «сцена 8»; как бы неудачу , если бы я только поддерживал римские цифры до 5
Grimmy
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
                         )
totallyhuman
источник
Вы можете сэкономить немного, используя b,c,d,e,f=s.groups()вместоa,b,c,d,e,f=[s.group(n) for n in range(6)]
Час Браун
И еще 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 к строкам, поэтому нам не нужно приводить акт / сцену в целые
streetster
источник