Скільки символів на персонажа?


15

На сторінці http://shakespeare.mit.edu/ ви можете знайти повний текст кожної п’єси Шекспіра на одній сторінці (наприклад, Гамлет ).

Напишіть сценарій, який містить URL-адресу п’єси від stdin, наприклад http://shakespeare.mit.edu/hamlet/full.html , і виводить кількість текстових символів, які кожен персонаж відтворення розмовляв до stdout, відсортувавшись відповідно до того, хто говорив найбільше.

Назви п’єси / сцени / дії, очевидно, не вважаються діалогом, а також іменами персонажів. Італізований текст та [квадратний текст із дужкою] не є фактичним діалогом, їх не слід зараховувати. Пробіли та інші розділові знаки в діалозі повинні бути враховані.

(Формат п’єс виглядає дуже послідовно, хоча я не переглянув їх усіх. Скажіть, чи я щось не помітив. Ваш сценарій не повинен працювати на вірші.)

Приклад

Ось модельований розділ Much Ado About Nothing, щоб показати, що я очікую на вихід:

Більше Адо про Ніщо

Сцена 0.

Месенджер

Я буду.

BEATRICE

Робити.

ЛЕОНАТО

Ви ніколи не будете.

BEATRICE

Ні.

Очікуваний вихід:

LEONATO 15
Messenger 7
BEATRICE 6

Оцінка балів

Це код гольфу. Виграє найменша програма в байтах.


8
Що робити, якщо хтось зробив цей шекспірівський виклик у Шекспіра? Було б дивовижно, якби це було навіть можливо ...
fuandon

Чи можна припустити, що у нас є список персонажів п’єси? Або ми мусимо вивести символів з тексту? Останнє дуже важко, враховуючи те, що деякі символи (наприклад, Messenger) мають поєднання великих і малих літер. Інші мають назви лише великими літерами (наприклад, LEONATO); а деякі з них є складними іменами.
DavidC

Так, слід зробити висновок про імена. Вони відформатовані зовсім інакше, ніж діалог, тому враховуючи html розрізнення їх не повинно бути занадто складним.
Захоплення Кальвіна

1
Чи слід розглядати "Усі" як окремий символ?
es1024

1
@ es1024 Так. Будь-який ігровий персонаж з унікальним заголовком вважається окремим, навіть якщо результат точно не має сенсу.
Захоплення Кальвіна

Відповіді:


4

PHP (240 символів)

Розділяє html на рядки (використовуючи як деліметр), після чого виконує пару регулярних виразів для вилучення імені та слів, що вимовляються. Зберігає довжину слів, що вимовляються до масиву. Гольф:

<?@$p=preg_match_all;foreach(explode('/bl',implode(file(trim(fgets(STDIN)))))as$c)if($p('/=s.*?b>(.*?):?</',$c,$m)){$p('/=\d.*?>(.*?)</',$c,$o);foreach($m[1]as$n)@$q[$n]+=strlen(implode($o[1]));}arsort($q);foreach($q as$n=>$c)echo"$n $c\n";

Безголівки:

<?php
$html = implode(file(trim(fgets(STDIN))));
$arr = explode('/bl',$html);
foreach($arr as $chunk){
    if(preg_match_all('/=s.*?b>(.*?):?</',$chunk,$matches)){
        $name = $matches[1];
        preg_match_all('/=\d.*?>(.*?)</',$chunk,$matches);
        foreach($name as $n)
            @$names[$n] += strlen(implode($matches[1]));
    }
}
arsort($names);
foreach($names as $name=>$count)
    echo "$name $count\n";

Примітка. Це вважає "Усі" окремим символом.

Приклад:

$php shakespeare.php <<< "http://shakespeare.mit.edu/hamlet/full.html"
HAMLET 60063
KING CLAUDIUS 21461
LORD POLONIUS 13877
HORATIO 10605
LAERTES 7519
OPHELIA 5916
QUEEN GERTRUDE 5554
First Clown 3701
ROSENCRANTZ 3635
Ghost 3619
MARCELLUS 2350
First Player 1980
OSRIC 1943
Player King 1849
GUILDENSTERN 1747
Player Queen 1220
BERNARDO 1153
Gentleman 978
PRINCE FORTINBRAS 971
VOLTIMAND 896
Second Clown 511
First Priest 499
Captain 400
Lord 338
REYNALDO 330
FRANCISCO 287
LUCIANUS 272
First Ambassador 230
First Sailor 187
Messenger 185
Prologue 94
All 94
Danes 75
Servant 49
CORNELIUS 45

1
Будь ласка, покажіть кілька прикладів результатів.
DavidC

@DavidCarraher Додано приклад.
es1024

3

Ребол - 556 527

t: complement charset"<"d: charset"0123456789."m: map[]parse to-string read to-url input[any[(s: 0 a: copy[])some["<A NAME=speech"some d"><b>"copy n some t</b></a>(append a trim/with n":")some newline]<blockquote>newline any["<A NAME="some d">"copy q some t</a><br>newline(while[f: find q"["][q: remove/part f next find f"]"]s: s + length? trim head q)|<p><i>some t</i></p>newline][</blockquote>|</body>](foreach n a[m/:n: either none? m/:n[s][s + m/:n]])| skip]]foreach[x y]sort/reverse/skip/compare to-block m 2 2[print[x y]]

Це, ймовірно, може бути додатково гольф, але навряд чи вдасться отримати відповідь, що вже надається :(

Безголівки:

t: complement charset "<"
d: charset "0123456789."
m: map []

parse to-string read to-url input [
    any [
        (s: 0 a: copy [])

        some [
            "<A NAME=speech" some d "><b>" copy n some t </b></a>
            (append a trim/with n ":")
            some newline
        ]

        <blockquote> newline
        any [
            "<A NAME=" some d ">" copy q some t </a><br> newline (
                while [f: find q "["] [
                    q: remove/part f next find f "]"
                ]
                s: s + length? trim head q
            )
            | <p><i> some t </i></p> newline
        ]
        [</blockquote> | </body>]
        (foreach n a [m/:n: either none? m/:n [s] [s + m/:n]])

        | skip
    ]
]

foreach [x y] sort/reverse/skip/compare to-block m 2 2 [print [x y]]

Ця програма вилучає [квадратний текст із дужкою], а також обрізає навколо діалогового проміжку пробіл. Без цього вихід є ідентичним відповіді es1024 .

Приклад:

$ rebol -q shakespeare.reb <<< "http://shakespeare.mit.edu/hamlet/full.html"
HAMLET 59796
KING CLAUDIUS 21343
LORD POLONIUS 13685
HORATIO 10495
LAERTES 7402
OPHELIA 5856
QUEEN GERTRUDE 5464
First Clown 3687
ROSENCRANTZ 3585
Ghost 3556
MARCELLUS 2259
First Player 1980
OSRIC 1925
Player King 1843
GUILDENSTERN 1719
Player Queen 1211
BERNARDO 1135
Gentleman 978
PRINCE FORTINBRAS 953
VOLTIMAND 896
Second Clown 511
First Priest 499
Captain 400
Lord 338
REYNALDO 312
FRANCISCO 287
LUCIANUS 269
First Ambassador 230
First Sailor 187
Messenger 185
Prologue 89
All 76
Danes 51
Servant 49
CORNELIUS 45

0

Лист звичайний - 528

(use-package :plump)(lambda c(u &aux(h (make-hash-table))n r p)(traverse(parse(drakma:http-request u))(lambda(x &aux y)(case p(0(when(and n(not(ppcre:scan"speech"(attribute x"NAME"))))(setf r t y(#1=ppcre:regex-replace-all"aside: "(#1#"^(\\[[^]]*\\] |\\s*)"(text x)"")""))(dolist(w n)(incf(gethash w h 0)(length y)))))(1(if r(setf n()r()))(push(intern(text(aref(children x)0)))n)))):test(lambda(x)(and(element-p x)(setf p(position(tag-name x)'("A""b"):test #'string=)))))(format t"~{~a ~a~^~%~}"(alexandria:hash-table-plist h)))

Пояснення

Це дещо змінена версія, яка додає інформацію про друк (див. Вставку).

(defun c (u &aux
                 (h (make-hash-table)) ;; hash-table
                 n ;; last seen character name
                 r p
                 )
      (traverse                 ;; traverse the DOM generated by ...
       (parse                   ;; ... parsing the text string
        (drakma:http-request u) ;; ... resulting from http-request to link U
        )

       ;; call the function held in variable f for each traversed element
       (lambda (x &aux y)
         (case p
           (0 ;a
            (when(and n(not(alexandria:starts-with-subseq"speech"(attribute x "NAME"))))
              (setf r t)
              (setf y(#1=ppcre:regex-replace-all"aside: "(#1#"^(\\[[^]]*\\] |\\s*)"(text x)"")""))
              (format t "~A ~S~%" n y) ;; debugging
              (dolist(w n)
                (incf
                    (gethash w h 0) ;; get values in hash, with default value 0
                    (length y)))) ;; length of text
            )
           (1 ;b
            (if r(setf n()r()))
            (push (intern (text (aref (children x)0)))n))))

       ;; but only for elements that satisfy the test predicate
       :test
       (lambda(x)
         (and (element-p x) ;; must be an element node
              (setf p(position(tag-name x)'("A""b"):test #'string=)) ;; either <a> or <b>; save result of "position" in p
              )))

        ;; finally, iterate over the elements of the hash table, as a
        ;; plist, i.e. a list of alternating key values (k1 v1 k2 v2 ...),
        ;; and print them as requested. ~{ ~} is an iteration control format.
  (format t "~&~%~%TOTAL:~%~%~{~a ~a~^~%~}" (alexandria:hash-table-plist h)))

Примітки

  • Я видаляю текст із дужкою, а також виникнення "вбік:", яке немає в дужках (я також обрізаю символи пробілів). Ось слід слідування виконання тексту зі збігом тексту та загальним для кожного символу для Гамлета .

  • Як інші відповіді, всі вважаються персонажем. Можливо, було б привабливо додати значення всіх інших персонажів, але це було б неправильно, оскільки "Усі" посилаються на персонажів, які фактично присутні на сцені, що вимагає зберегти контекст того, хто присутній (відстеження "виходу" "виконавця "та" ввести "вказівки). Це не робиться.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.