Karakter başına kaç karakter?


15

At http://shakespeare.mit.edu/ Bir sayfada (örn üzerine Shakespeare'in oyunlarının her birinin tam metnini bulabilirsiniz Hamlet ).

Stdin'den http://shakespeare.mit.edu/hamlet/full.html gibi bir oyunun URL'sini alan ve her bir oynatma karakterinin stdout'a konuştuğu metin karakterlerinin sayısını kime göre sıralayan bir komut dosyası yazın en çok konuştu.

Oyun / sahne / eylem başlıkları diyalog olarak sayılmaz ve karakter isimleri sayılmaz. İtalik metin ve [köşeli parantezli metin] gerçek diyalog değildir, sayılmamalıdır. Diyalog içindeki boşluklar ve diğer noktalama işaretleri sayılmalıdır.

(Oyunların formatı çok tutarlı görünüyor, ancak hepsine bakmadım. Bana bir şey göz ardı etsem söyle. Senaryonuzun şiirler için çalışması gerekmez.)

Misal

İşte çok Ado Hakkında Hiçbir şey çıktı için ne beklediğim göstermek için:

Hiçbir Şey Hakkında Ado

Sahne 0.

haberci

Yapacağım.

BEATRICE

Yapmak.

LEONATO

Sen asla-mayacaksın.

BEATRICE

Hayır.

Beklenen çıktı:

LEONATO 15
Messenger 7
BEATRICE 6

puanlama

Bu kod golf. Bayttaki en küçük program kazanacaktır.


8
Ya Shakespeare'de bu Shakespeare meydan okumasını yaptıysa? Bu mümkün olsaydı çok şaşırtıcı olurdu ...
fuandon

Oyundaki karakterlerin bir listesine sahip olduğumuzu varsayabilir miyiz? Yoksa metni metinden çıkarmalı mıyız? İkincisi, bazı karakterlerin (örn. Messenger) büyük ve küçük harflerin bir karışımına sahip olması nedeniyle çok zordur. Diğerlerinin sadece büyük harfli isimleri vardır (örneğin LEONATO); ve bunlardan bazıları bileşik isimler.
DavidC

Evet isimleri çıkarmalısın. Diyalogdan çok farklı biçimlendirilmişlerdir, bu yüzden onları farklılaştıran html göz önüne alındığında çok zor olmamalıdır.
Calvin'in Hobileri

1
'Hepsi' ayrı bir karakter olarak mı düşünülmeli?
es1024

1
@ es1024 Evet. Sonuç tam olarak anlamlı olmasa bile, benzersiz bir başlığa sahip herhangi bir oyun karakteri ayrı olarak kabul edilir.
Calvin'in Hobileri

Yanıtlar:


4

PHP (240 karakter)

HTML'yi dizelere böler (ayırıcı olarak kullanarak), ardından adı ve konuşulan kelimeleri ayıklamak için birkaç normal ifade çalıştırır. Diziye söylenen sözcüklerin uzunluğunu kaydeder. golfed:

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

Ungolfed:

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

Not: Bu, 'Tümü'nün ayrı bir karakter olduğunu düşünür.

Misal:

$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
Lütfen bazı örnek (ler) i göster.
DavidC

@DavidCarraher Bir örnek eklendi.
es1024

3

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

Bu muhtemelen daha da golf olabilir, ancak zaten verilen cevapların altına düşmesi pek olası değildir :(

Ungolfed:

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

Bu program [köşeli parantez içindeki metni] kaldırır ve çevredeki boşlukları diyalogdan keser. Bu olmadan çıkış es1024 cevabı ile aynıdır .

Misal:

$ 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

Yaygın 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)))

açıklama

Bu, baskı bilgileri ekleyen biraz değiştirilmiş bir sürümdür (bkz. Yapıştır).

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

notlar

  • Köşeli ayraçlı metni yanı sıra köşeli ayraç içinde olmayan "kenara:" oluşumunu da kaldırırım (boşluk karakterlerini de keserim). İşte Hamlet için eşleşen metin ve her karakter için toplam ile bir yürütme izi .

  • Diğer cevaplar gibi, Her şeyin bir karakter olduğu varsayılır. Tüm karakterlerin değerini diğer tüm karakterlere eklemek cazip gelebilir, ancak bu yanlış olur çünkü "Tümü" aslında sahnede mevcut olan karakterleri ifade eder. "ve" enter "göstergeleri). Bu tamamlanmamış.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.