Berapa banyak karakter per karakter?

15

Di http://shakespeare.mit.edu/ Anda dapat menemukan teks lengkap dari setiap drama Shakespeare di satu halaman (misalnya Hamlet ).

Tulis skrip yang mengambil url lakon dari stdin, seperti http://shakespeare.mit.edu/hamlet/full.html , dan tampilkan jumlah karakter teks yang setiap karakter lakon dibicarakan dengan stdout, disortir berdasarkan siapa berbicara paling banyak.

Judul play / scene / act jelas tidak dihitung sebagai dialog, begitu pula nama karakternya. Teks yang dicetak miring dan [teks kurung siku] bukan dialog yang sebenarnya, mereka tidak harus dihitung. Spasi dan tanda baca lain dalam dialog harus dihitung.

(Format untuk lakon-lakonnya terlihat sangat konsisten meskipun saya belum melihat semuanya. Katakan padaku jika saya mengabaikan sesuatu. Naskah Anda tidak harus berfungsi untuk puisi-puisi itu.)

Contoh

Ini adalah bagian simulasi dari Much Ado About Nothing untuk menunjukkan apa yang saya harapkan untuk hasil:

Ado Lagi Tentang Tidak Ada

Adegan 0.

Kurir

Aku akan.

BEATRICE

Melakukan.

LEONATO

Kamu tidak akan pernah.

BEATRICE

Tidak.

Output yang diharapkan:

LEONATO 15
Messenger 7
BEATRICE 6

Mencetak gol

Ini golf kode. Program terkecil dalam byte akan menang.

Hobi Calvin
sumber
8
Bagaimana jika seseorang melakukan tantangan Shakespeare di Shakespeare ini? Akan luar biasa jika itu bahkan mungkin ...
fuandon
Bisakah kita menganggap kita memiliki daftar karakter dalam drama? Atau haruskah kita menyimpulkan karakter dari teks? Yang terakhir sangat sulit mengingat bahwa beberapa karakter (mis. Messenger) memiliki campuran huruf besar dan kecil. Yang lain memiliki nama dengan hanya huruf besar (misalnya LEONATO); dan beberapa di antaranya adalah nama majemuk.
DavidC
Ya, Anda harus menyimpulkan nama. Mereka diformat sangat berbeda dari dialog sehingga diberi html membedakan mereka tidak boleh terlalu rumit.
Hobi Calvin
1
Haruskah 'Semua' dianggap sebagai karakter yang terpisah?
es1024
1
@ es1024 Ya. Setiap karakter permainan dengan judul unik dianggap terpisah, meskipun hasilnya tidak masuk akal.
Hobi Calvin

Jawaban:

4

PHP (240 karakter)

Membagi html menjadi string (menggunakan sebagai delimeter), kemudian menjalankan beberapa ekspresi reguler untuk mengekstrak nama dan kata-kata yang diucapkan. Menghemat panjang kata yang diucapkan ke dalam array. Golf:

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

Tidak Disatukan:

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

Catatan: Ini menganggap 'Semua' sebagai karakter yang terpisah.

Contoh:

$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
sumber
1
Mohon tunjukkan beberapa contoh hasil.
DavidC
@ DavidVarraher Contoh telah ditambahkan.
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]]

Ini mungkin bisa di-golf lebih lanjut tetapi tidak mungkin untuk mendapatkan di bawah jawaban yang sudah disediakan :(

Tidak Disatukan:

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

Program ini menghapus [teks kurung kurawal] dan juga memotong whitespace sekitar dari dialog. Tanpa ini, output identik dengan jawaban es1024 .

Contoh:

$ 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
sumber
0

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

Penjelasan

Ini adalah versi yang sedikit dimodifikasi yang menambahkan informasi pencetakan (lihat tempel).

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

Catatan

  • Saya menghapus teks tanda kurung serta kejadian "samping:" yang tidak ada dalam tanda kurung (saya juga memangkas karakter spasi putih). Berikut adalah jejak eksekusi dengan teks yang cocok dan total untuk setiap karakter, untuk Hamlet .

  • Sebagai jawaban lain, Semua diasumsikan sebagai karakter. Mungkin tergoda untuk menambahkan nilai semua ke semua karakter lain, tetapi ini tidak benar karena "Semua" mengacu pada karakter yang benar-benar ada di panggung, yang mengharuskan untuk menjaga konteks siapa yang hadir (melacak "keluar" "exeunt "dan" masukkan "indikasi). Ini belum selesai.

coredump
sumber