Ile znaków na postać?

15

Na stronie http://shakespeare.mit.edu/ można znaleźć pełny tekst każdej sztuki Szekspira na jednej stronie (np. Hamleta ).

Napisz skrypt, który pobiera adres URL gry ze standardowego wejścia, taki jak http://shakespeare.mit.edu/hamlet/full.html , i wyświetla liczbę znaków tekstowych, z którymi każda postać odtwarzana przemawiała na standardowe wyjście, posortowane według tego, kto mówił najwięcej.

Tytuły dramatu / sceny / aktu oczywiście nie liczą się jako dialog, podobnie jak imiona bohaterów. Tekst pisany kursywą i [tekst w nawiasach kwadratowych] nie są dialogami, nie należy ich liczyć. Należy liczyć spacje i inne znaki interpunkcyjne w dialogu.

(Format przedstawień wygląda na bardzo spójny, choć nie oglądałem ich wszystkich. Powiedz mi, czy coś przeoczyłem. Twój skrypt nie musi działać dla wierszy.)

Przykład

Oto część symulowana z dużo hałasu o niczym, aby pokazać, czego oczekuję od wyników:

Więcej hałasu o nic

Scena 0.

Posłaniec

Będę.

BEATRICE

Robić.

LEONATO

Ty nigdy.

BEATRICE

Nie.

Oczekiwany wynik:

LEONATO 15
Messenger 7
BEATRICE 6

Punktacja

To jest kod golfowy. Wygra najmniejszy program w bajtach.

Hobby Calvina
źródło
8
Co jeśli ktoś rzucił wyzwanie Szekspirowi w Shakespeare? Byłoby niesamowicie, gdyby to było w ogóle możliwe ...
fuandon,
Czy możemy założyć, że mamy listę postaci w grze? Czy musimy wywnioskować znaki z tekstu? To ostatnie jest bardzo trudne, biorąc pod uwagę, że niektóre znaki (np. Messenger) mają kombinację wielkich i małych liter. Inne mają nazwy zawierające tylko wielkie litery (np. LEONATO); a niektóre z nich są nazwami złożonymi.
DavidC,
Tak, powinieneś wywnioskować nazwiska. Są one sformatowane bardzo inaczej niż dialog, więc biorąc pod uwagę różnicowanie ich w html nie powinno być zbyt trudne.
Calvin's Hobbies,
1
Czy „Wszystko” należy traktować jako osobny znak?
es1024
1
@ es1024 Tak. Każda postać z unikalnym tytułem jest uważana za osobną, nawet jeśli wynik nie ma dokładnie sensu.
Calvin's Hobbies

Odpowiedzi:

4

PHP (240 znaków)

Dzieli html na ciągi znaków (używając jako ogranicznik), a następnie uruchamia kilka wyrażeń regularnych w celu wyodrębnienia wypowiedzianych nazw i słów. Oszczędza długość słów wypowiadanych w tablicy. Gra w golfa:

<?@$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";

Nie golfowany:

<?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";

Uwaga: uważa to wszystko za osobny znak.

Przykład:

$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
es1024
źródło
1
Uprzejmie pokaż kilka przykładów wyników.
DavidC
@DavidCarraher Dodano przykład.
es1024
3

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

Prawdopodobnie można to pograć w golfa, jednak jest mało prawdopodobne, aby uzyskać odpowiedź poniżej podaną już:

Nie golfowany:

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

Ten program usuwa [tekst w nawiasach kwadratowych], a także przycina otaczające białe znaki z okna dialogowego. Bez tego wynik jest identyczny z odpowiedzią es1024 .

Przykład:

$ 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
draegtun
źródło
0

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

Wyjaśnienie

Jest to nieco zmodyfikowana wersja, która dodaje informacje o drukowaniu (patrz wklej).

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

Notatki

  • Usuwam tekst w nawiasach, a także wystąpienie „na bok:”, które nie występuje w nawiasach (usuwam również białe znaki). Oto ślad wykonania z dopasowanym tekstem i sumą dla każdego znaku, dla Hamleta .

  • Podobnie jak inne odpowiedzi, zakłada się , że Wszystko jest postacią. Dodanie wartości wszystkich do wszystkich innych postaci może być kuszące, ale byłoby to niepoprawne, ponieważ „Wszystko” odnosi się do postaci faktycznie obecnych na scenie, co wymaga zachowania kontekstu obecności (śledzenie „wyjścia”) „i„ wprowadź ”). To nie jest zrobione.

rdzeń rdzeniowy
źródło