Buat bagan ASCII dari kata-kata yang paling umum digunakan dalam teks yang diberikan [ditutup]

156

Tantangan:

Buat bagan ASCII dari kata-kata yang paling umum digunakan dalam teks yang diberikan.

Aturan:

  • Hanya terima a-zdan A-Z(karakter alfabet) sebagai bagian dari kata.
  • Abaikan casing ( She== sheuntuk tujuan kami).
  • Abaikan kata-kata berikut (cukup arbiter, saya tahu): the, and, of, to, a, i, it, in, or, is
  • Klarifikasi: mempertimbangkan don't: ini akan dianggap sebagai 2 'kata' yang berbeda dalam rentang a-zdan A-Z: ( dondan t).

  • Secara opsional (sudah terlambat untuk secara resmi mengubah spesifikasi sekarang), Anda dapat memilih untuk menghapus semua 'kata-kata' satu huruf (ini juga berpotensi memperpendek daftar abaikan).

Parse yang diberikan text(baca file yang ditentukan melalui argumen baris perintah atau disalurkan; anggap us-ascii) dan buat kami word frequency chartdengan karakteristik berikut:

  • Tampilkan grafik (juga lihat contoh di bawah) untuk 22 kata yang paling umum (dipesan dengan frekuensi menurun).
  • Bilah widthmewakili jumlah kemunculan (frekuensi) kata (secara proporsional). Tambahkan satu spasi dan cetak kata.
  • Pastikan bilah-bilah ini (plus spasi-kata-spasi) selalu cocok : bar+ [space]+ word+ [space]harus selalu <= 80karakter (pastikan Anda memperhitungkan kemungkinan bar dan panjang kata yang berbeda: misalnya: kata yang paling umum kedua mungkin jauh lebih lama daripada saat pertama tidak berbeda jauh dalam frekuensi). Maksimalkan lebar batang dalam batasan ini dan skala batang dengan tepat (sesuai dengan frekuensi yang diwakilinya).

Sebuah contoh:

Teks sebagai contoh dapat ditemukan di sini ( Petualangan Alice di Negeri Ajaib, oleh Lewis Carroll ).

Teks khusus ini akan menghasilkan bagan berikut:

 _________________________________________________________________________
| _________________________________________________________________________ | | dia
| _______________________________________________________________ | kamu
| ____________________________________________________________ | kata
| ____________________________________________________ | Alice
| ______________________________________________ | dulu
| __________________________________________ | bahwa
| ___________________________________ | sebagai
| _______________________________ | -nya
| ____________________________ | dengan
| ____________________________ | di
| ___________________________ | s
| ___________________________ | t
| _________________________ | di
| _________________________ | semua
| ______________________ | ini
| ______________________ | untuk
| ______________________ | telah
| _____________________ | tapi
| ____________________ | menjadi
| ____________________ | tidak
| ___________________ | mereka
| __________________ | begitu


Untuk informasi Anda: ini adalah frekuensi bagan di atas dibangun di atas:

[('dia', 553), ('kamu', 481), ('kata', 462), ('alice', 403), ('adalah', 358), ('itu
', 330), (' as ', 274), (' dia ', 248), (' dengan ', 227), (' at ', 227), (' s ', 219), (' t '
, 218), ('on', 204), ('all', 200), ('this', 181), ('for', 179), ('had', 178), ('
tetapi ', 175), (' be ', 167), (' not ', 166), (' mereka ', 155), (' jadi ', 152)]

Contoh kedua (untuk memeriksa apakah Anda menerapkan spesifikasi lengkap): Ganti setiap kemunculan youdalam file Alice in Wonderland yang ditautkan dengan superlongstringstring:

 ________________________________________________________________
| ________________________________________________________________ | dia
| _______________________________________________________ | superlongstringstring
| _____________________________________________________ | kata
| ______________________________________________ | Alice
| ________________________________________ | dulu
| _____________________________________ | bahwa
| ______________________________ | sebagai
| ___________________________ | -nya
| _________________________ | dengan
| _________________________ | di
| ________________________ | s
| ________________________ | t
| ______________________ | di
| _____________________ | semua
| ___________________ | ini
| ___________________ | untuk
| ___________________ | telah
| __________________ | tapi
| _________________ | menjadi
| _________________ | tidak
| ________________ | mereka
| ________________ | begitu

Pemenang:

Solusi terpendek (berdasarkan jumlah karakter, per bahasa). Selamat bersenang-senang!


Sunting : Tabel merangkum hasil sejauh ini (2012-02-15) (awalnya ditambahkan oleh pengguna Nas Banov):

Bahasa Santai Ketat
========= ======= ======
GolfScript 130 143
Perl 185
Windows PowerShell 148 199
Mathematica 199
Ruby 185 205
Unix Toolchain 194 228
Python 183 243
Clojure 282
Scala 311
Haskell 333
Awk 336
R 298
Javascript 304 354
Groovy 321
Matlab 404
C # 422
Smalltalk 386
PHP 450
F # 452
TSQL 483 507

Angka-angka mewakili panjang solusi terpendek dalam bahasa tertentu. "Strict" mengacu pada solusi yang mengimplementasikan spec sepenuhnya (menggambar |____|bar, menutup bar pertama di atas dengan sebuah ____garis, menjelaskan kemungkinan kata-kata panjang dengan frekuensi tinggi dll). "Santai" berarti beberapa kebebasan diambil untuk dipersingkat menjadi solusi.

Hanya solusi yang lebih pendek dari 500 karakter yang disertakan. Daftar bahasa diurutkan berdasarkan lamanya solusi 'ketat'. 'Unix Toolchain' digunakan untuk menandai berbagai solusi yang menggunakan shell * nix tradisional plus campuran alat (seperti grep, tr, sortir, uniq, head, perl, awk).

ChristopheD
sumber
4
Nah, 'bilah terpanjang' + kata = 80 mungkin tidak muat dalam 80 cols jika kata yang paling umum kedua adalah kata yang jauh lebih panjang. Saya mencari 'batasan max' saya kira.
Brian
1
Apakah kita menormalkan casing? 'Dia' = 'dia'?
Brian
2
IMO membuat ini berkinerja, baik dalam hal waktu eksekusi dan penggunaan memori, sepertinya tantangan yang lebih menarik daripada jumlah karakter.
Frank Farmer
81
Saya senang melihat kata s- kata favorit saya dan tdiwakili.
indiv
8
@indiv, @Nas Banov - tokenizer konyol terlalu sederhana bertuliskan "not" as {didn, t} dan "she" as {she, s} :)
hobbs

Jawaban:

123

LabVIEW 51 node, 5 struktur, 10 diagram

Mengajar gajah untuk menari-nari tidak pernah indah. Saya akan, ah, melewatkan hitungan karakter.

kode labVIEW

hasil

Program mengalir dari kiri ke kanan:

kode labVIEW dijelaskan

Joe Zoller
sumber
10
Itu tidak layak
4
LabVIEW sangat senang dengan kontrol perangkat keras dan ceruk pengukuran, tetapi sangat mengerikan untuk manipulasi string.
Joe Z
19
Jawaban golf kode terbaik yang pernah saya lihat. +1 untuk berpikir di luar kotak!
Blair Holloway
1
Harus menghitung elemen untuk kami ... setiap kotak dan widget yang harus Anda seret ke jumlah layar.
dmckee --- ex-moderator kitten
1
Apakah mungkin untuk menambahkan tautan ke versi yang lebih besar dari bagan itu?
Svish
42

Ruby 1.9, 185 karakter

(sangat didasarkan pada solusi Ruby lainnya)

w=($<.read.downcase.scan(/[a-z]+/)-%w{the and of to a i it in or is}).group_by{|x|x}.map{|x,y|[-y.size,x]}.sort[0,22]
k,l=w[0]
puts [?\s+?_*m=76-l.size,w.map{|f,x|?|+?_*(f*m/k)+"| "+x}]

Alih-alih menggunakan switch baris perintah seperti solusi lain, Anda bisa dengan mudah memberikan nama file sebagai argumen. (yaitu ruby1.9 wordfrequency.rb Alice.txt)

Karena saya menggunakan karakter-literal di sini, solusi ini hanya berfungsi di Ruby 1.9.

Sunting: Mengganti titik koma dengan jeda baris untuk "keterbacaan". : P

Sunting 2: Shtééf menunjukkan saya lupa ruang tambahan - memperbaikinya.

Sunting 3: Menghapus ruang tambahan lagi;)

Ventero
sumber
Tidak ada ruang tambahan, setelah setiap kata.
Stéphan Kochen
Aww tembak, abaikan itu. Sepertinya golf baru saja diperbarui, ruang tambahan tidak lagi diperlukan. :)
Stéphan Kochen
Tampaknya tidak mengakomodasi 'superlongstringstring' di posisi ke-2 atau lebih baru? (lihat deskripsi masalah)
Nas Banov
2
Itu terlihat sangat terpelihara.
Zombi
39

GolfScript, 177 175 173 167 164 163 144 131 130 karakter

Lambat - 3 menit untuk sampel teks (130)

{32|.123%97<n@if}%]''*n%"oftoitinorisa"2/-"theandi"3/-$(1@{.3$>1{;)}if}/]2/{~~\;}$22<.0=~:2;,76\-:1'_':0*' '\@{"
|"\~1*2/0*'| '@}/

Penjelasan:

{           #loop through all characters
 32|.       #convert to uppercase and duplicate
 123%97<    #determine if is a letter
 n@if       #return either the letter or a newline
}%          #return an array (of ints)
]''*        #convert array to a string with magic
n%          #split on newline, removing blanks (stack is an array of words now)
"oftoitinorisa"   #push this string
2/          #split into groups of two, i.e. ["of" "to" "it" "in" "or" "is" "a"]
-           #remove any occurrences from the text
"theandi"3/-#remove "the", "and", and "i"
$           #sort the array of words
(1@         #takes the first word in the array, pushes a 1, reorders stack
            #the 1 is the current number of occurrences of the first word
{           #loop through the array
 .3$>1{;)}if#increment the count or push the next word and a 1
}/
]2/         #gather stack into an array and split into groups of 2
{~~\;}$     #sort by the latter element - the count of occurrences of each word
22<         #take the first 22 elements
.0=~:2;     #store the highest count
,76\-:1     #store the length of the first line
'_':0*' '\@ #make the first line
{           #loop through each word
"
|"\~        #start drawing the bar
1*2/0       #divide by zero
*'| '@      #finish drawing the bar
}/

"Benar" (semoga). (143)

{32|.123%97<n@if}%]''*n%"oftoitinorisa"2/-"theandi"3/-$(1@{.3$>1{;)}if}/]2/{~~\;}$22<..0=1=:^;{~76@,-^*\/}%$0=:1'_':0*' '\@{"
|"\~1*^/0*'| '@}/

Kurang lambat - setengah menit. (162)

'"'/' ':S*n/S*'"#{%q
'\+"
.downcase.tr('^a-z','
')}\""+~n%"oftoitinorisa"2/-"theandi"3/-$(1@{.3$>1{;)}if}/]2/{~~\;}$22<.0=~:2;,76\-:1'_':0*S\@{"
|"\~1*2/0*'| '@}/

Output terlihat dalam log revisi.

Nabb
sumber
2
Tentang GolfScript: golfscript.com/golfscript
Assaf Lavie
2
Tidak benar, dalam hal itu jika kata kedua sangat panjang itu akan membungkus ke baris berikutnya.
Gabe
5
"bagi dengan nol" ... GolfScript memungkinkan itu?
JAB
35

206

shell, grep, tr, grep, sortir, uniq, sort, head, perl

~ % wc -c wfg
209 wfg
~ % cat wfg
egrep -oi \\b[a-z]+|tr A-Z a-z|egrep -wv 'the|and|of|to|a|i|it|in|or|is'|sort|uniq -c|sort -nr|head -22|perl -lape'($f,$w)=@F;$.>1or($q,$x)=($f,76-length$w);$b="_"x($f/$q*$x);$_="|$b| $w ";$.>1or$_=" $b\n$_"'
~ % # usage:
~ % sh wfg < 11.txt

hm, baru dilihat di atas: sort -nr-> sort -ndan kemudian head-> tail=> 208 :)
update2: erm, tentu saja hal di atas konyol, karena akan dibalik kemudian. Jadi, 209.
update3: mengoptimalkan regexp pengecualian -> 206

egrep -oi \\b[a-z]+|tr A-Z a-z|egrep -wv 'the|and|o[fr]|to|a|i[tns]?'|sort|uniq -c|sort -nr|head -22|perl -lape'($f,$w)=@F;$.>1or($q,$x)=($f,76-length$w);$b="_"x($f/$q*$x);$_="|$b| $w ";$.>1or$_=" $b\n$_"'



untuk bersenang-senang, inilah versi perl-only (jauh lebih cepat):

~ % wc -c pgolf
204 pgolf
~ % cat pgolf
perl -lne'$1=~/^(the|and|o[fr]|to|.|i[tns])$/i||$f{lc$1}++while/\b([a-z]+)/gi}{@w=(sort{$f{$b}<=>$f{$a}}keys%f)[0..21];$Q=$f{$_=$w[0]};$B=76-y///c;print" "."_"x$B;print"|"."_"x($B*$f{$_}/$Q)."| $_"for@w'
~ % # usage:
~ % sh pgolf < 11.txt
stor
sumber
35

Solusi transaksi berbasis kumpulan SQL (SQL Server 2005) 1063 892 873 853 827 820 783 683 647 644 630 karakter

Terima kasih kepada Gabe untuk beberapa saran berguna untuk mengurangi jumlah karakter.

NB: Jeda baris ditambahkan untuk menghindari scrollbar hanya jeda baris terakhir yang diperlukan.

DECLARE @ VARCHAR(MAX),@F REAL SELECT @=BulkColumn FROM OPENROWSET(BULK'A',
SINGLE_BLOB)x;WITH N AS(SELECT 1 i,LEFT(@,1)L UNION ALL SELECT i+1,SUBSTRING
(@,i+1,1)FROM N WHERE i<LEN(@))SELECT i,L,i-RANK()OVER(ORDER BY i)R INTO #D
FROM N WHERE L LIKE'[A-Z]'OPTION(MAXRECURSION 0)SELECT TOP 22 W,-COUNT(*)C
INTO # FROM(SELECT DISTINCT R,(SELECT''+L FROM #D WHERE R=b.R FOR XML PATH
(''))W FROM #D b)t WHERE LEN(W)>1 AND W NOT IN('the','and','of','to','it',
'in','or','is')GROUP BY W ORDER BY C SELECT @F=MIN(($76-LEN(W))/-C),@=' '+
REPLICATE('_',-MIN(C)*@F)+' 'FROM # SELECT @=@+' 
|'+REPLICATE('_',-C*@F)+'| '+W FROM # ORDER BY C PRINT @

Versi yang Dapat Dibaca

DECLARE @  VARCHAR(MAX),
        @F REAL
SELECT @=BulkColumn
FROM   OPENROWSET(BULK'A',SINGLE_BLOB)x; /*  Loads text file from path
                                             C:\WINDOWS\system32\A  */

/*Recursive common table expression to
generate a table of numbers from 1 to string length
(and associated characters)*/
WITH N AS
     (SELECT 1 i,
             LEFT(@,1)L

     UNION ALL

     SELECT i+1,
            SUBSTRING(@,i+1,1)
     FROM   N
     WHERE  i<LEN(@)
     )
  SELECT   i,
           L,
           i-RANK()OVER(ORDER BY i)R
           /*Will group characters
           from the same word together*/
  INTO     #D
  FROM     N
  WHERE    L LIKE'[A-Z]'OPTION(MAXRECURSION 0)
             /*Assuming case insensitive accent sensitive collation*/

SELECT   TOP 22 W,
         -COUNT(*)C
INTO     #
FROM     (SELECT DISTINCT R,
                          (SELECT ''+L
                          FROM    #D
                          WHERE   R=b.R FOR XML PATH('')
                          )W
                          /*Reconstitute the word from the characters*/
         FROM             #D b
         )
         T
WHERE    LEN(W)>1
AND      W NOT IN('the',
                  'and',
                  'of' ,
                  'to' ,
                  'it' ,
                  'in' ,
                  'or' ,
                  'is')
GROUP BY W
ORDER BY C

/*Just noticed this looks risky as it relies on the order of evaluation of the 
 variables. I'm not sure that's guaranteed but it works on my machine :-) */
SELECT @F=MIN(($76-LEN(W))/-C),
       @ =' '      +REPLICATE('_',-MIN(C)*@F)+' '
FROM   #

SELECT @=@+' 
|'+REPLICATE('_',-C*@F)+'| '+W
             FROM     #
             ORDER BY C

PRINT @

Keluaran

 _________________________________________________________________________ 
|_________________________________________________________________________| she
|_______________________________________________________________| You
|____________________________________________________________| said
|_____________________________________________________| Alice
|_______________________________________________| was
|___________________________________________| that
|____________________________________| as
|________________________________| her
|_____________________________| at
|_____________________________| with
|__________________________| on
|__________________________| all
|_______________________| This
|_______________________| for
|_______________________| had
|_______________________| but
|______________________| be
|_____________________| not
|____________________| they
|____________________| So
|___________________| very
|__________________| what

Dan dengan benang panjang

 _______________________________________________________________ 
|_______________________________________________________________| she
|_______________________________________________________| superlongstringstring
|____________________________________________________| said
|______________________________________________| Alice
|________________________________________| was
|_____________________________________| that
|_______________________________| as
|____________________________| her
|_________________________| at
|_________________________| with
|_______________________| on
|______________________| all
|____________________| This
|____________________| for
|____________________| had
|____________________| but
|___________________| be
|__________________| not
|_________________| they
|_________________| So
|________________| very
|________________| what
Martin Smith
sumber
12
Saya memberi Anda +1 karena Anda melakukannya di T-SQL, dan mengutip Team America - "Anda punya bola. Saya suka bola."
Saya mengambil kebebasan mengubah beberapa spasi menjadi baris baru agar lebih mudah dibaca. Mudah-mudahan saya tidak mengacaukan segalanya. Saya juga mengurangi itu sedikit lagi.
Gabe
3
Kode itu meneriaki saya! : O
Joey
1
Satu cara yang baik untuk menyimpan adalah dengan mengubah 0.000ke adil 0, lalu menggunakan -Calih-alih 1.0/C. Dan membuat FLOATmenjadi REALakan menghemat stroke juga. Namun, hal terbesarnya adalah sepertinya Anda memiliki banyak ASinstance yang harus opsional.
Gabe
1
OK, bagaimana dengan SELECT [ ] FROM (SELECT $0 O, ' '+REPLICATE('_', MAX(C)*@F)+' ' [ ] FROM # UNION SELECT $1/C, '|'+REPLICATE('_',C*@F)+'| '+W FROM #)X ORDER BY O?
Gabe
34

Ruby 207 213 211 210 207 203 201 200 karakter

Peningkatan pada Anurag, menggabungkan saran dari rfusca. Juga menghapus argumen untuk mengurutkan dan beberapa pegolf kecil lainnya.

w=(STDIN.read.downcase.scan(/[a-z]+/)-%w{the and of to a i it in or is}).group_by{|x|x}.map{|x,y|[-y.size,x]}.sort.take 22;k,l=w[0];m=76.0-l.size;puts' '+'_'*m;w.map{|f,x|puts"|#{'_'*(m*f/k)}| #{x} "}

Jalankan sebagai:

ruby GolfedWordFrequencies.rb < Alice.txt

Sunting: masukkan 'memasukkan' kembali, perlu ada di sana untuk menghindari kuotasi dalam output.
Edit2: File Berubah-> IO
Edit3: dihapus / i
Edit4: Tanda kurung dihapus sekitar (f * 1.0), menceritakan
Edit5: Gunakan penambahan string untuk baris pertama; berkembang sdi tempat.
Sunting6: Made m float, dihapus 1.0. EDIT: Tidak berfungsi, mengubah panjang. EDIT: Tidak lebih buruk dari sebelumnya
Edit7: Gunakan STDIN.read.

archgoon
sumber
+1 - cinta bagian penyortiran, sangat pintar :)
Anurag
Hai, optimasi kecil dibandingkan dengan menghasilkan sebagian besar di tempat pertama. :)
Archgoon
Bagus! Menambahkan dua perubahan yang saya buat dalam versi Anurag. Shave off 4. lainnya
Stéphan Kochen
Solusinya telah menyimpang dari output asli, saya akan totry dan mencari tahu di mana itu terjadi.
Archgoon
1
Ada varian yang lebih pendek dari ini lebih lanjut.
Archgoon
28

Mathematica ( 297 284 248 244 242 199 karakter) Fungsional Murni

dan Pengujian Hukum Zipf

Lihatlah Mamma ... tidak ada vars, tidak ada tangan, .. tidak ada kepala

Sunting 1> beberapa singkatan didefinisikan (284 karakter)

f[x_, y_] := Flatten[Take[x, All, y]]; 

BarChart[f[{##}, -1], 
         BarOrigin -> Left, 
         ChartLabels -> Placed[f[{##}, 1], After], 
         Axes -> None
] 
& @@
Take[
  SortBy[
     Tally[
       Select[
        StringSplit[ToLowerCase[Import[i]], RegularExpression["\\W+"]], 
       !MemberQ[{"the", "and", "of", "to", "a", "i", "it", "in", "or","is"}, #]&]
     ], 
  Last], 
-22]

Beberapa penjelasan

Import[] 
   # Get The File

ToLowerCase []
   # To Lower Case :)

StringSplit[ STRING , RegularExpression["\\W+"]]
   # Split By Words, getting a LIST

Select[ LIST, !MemberQ[{LIST_TO_AVOID}, #]&]
   #  Select from LIST except those words in LIST_TO_AVOID
   #  Note that !MemberQ[{LIST_TO_AVOID}, #]& is a FUNCTION for the test

Tally[LIST]
   # Get the LIST {word,word,..} 
     and produce another  {{word,counter},{word,counter}...}

SortBy[ LIST ,Last]
   # Get the list produced bt tally and sort by counters
     Note that counters are the LAST element of {word,counter}

Take[ LIST ,-22]
   # Once sorted, get the biggest 22 counters

BarChart[f[{##}, -1], ChartLabels -> Placed[f[{##}, 1], After]] &@@ LIST
   # Get the list produced by Take as input and produce a bar chart

f[x_, y_] := Flatten[Take[x, All, y]]
   # Auxiliary to get the list of the first or second element of lists of lists x_
     dependending upon y
   # So f[{##}, -1] is the list of counters
   # and f[{##}, 1] is the list of words (labels for the chart)

Keluaran

alt teks http://i49.tinypic.com/2n8mrer.jpg

Mathematica tidak cocok untuk bermain golf, dan itu hanya karena nama fungsi yang panjang dan deskriptif. Fungsi seperti "RegularExpression []" atau "StringSplit []" hanya membuat saya terisak :(.

Pengujian Hukum Zipf

The Hukum Zipf memprediksi bahwa untuk teks bahasa alami, Log (Peringkat) vs Log (kejadian) Plot mengikuti linear hubungan.

Hukum digunakan dalam mengembangkan algoritma untuk kriptografi dan kompresi data. (Tapi BUKAN "Z" dalam algoritma LZW).

Dalam teks kami, kami dapat mengujinya dengan berikut ini

 f[x_, y_] := Flatten[Take[x, All, y]]; 
 ListLogLogPlot[
     Reverse[f[{##}, -1]], 
     AxesLabel -> {"Log (Rank)", "Log Counter"}, 
     PlotLabel -> "Testing Zipf's Law"]
 & @@
 Take[
  SortBy[
    Tally[
       StringSplit[ToLowerCase[b], RegularExpression["\\W+"]]
    ], 
   Last],
 -1000]

Hasilnya adalah (cukup baik linear)

alt teks http://i46.tinypic.com/33fcmdk.jpg

Edit 6> (242 Chars)

Refactoring the Regex (tidak ada fungsi Pilih lagi)
Menjatuhkan 1 kata char
Definisi yang lebih efisien untuk fungsi "f"

f = Flatten[Take[#1, All, #2]]&; 
BarChart[
     f[{##}, -1], 
     BarOrigin -> Left, 
     ChartLabels -> Placed[f[{##}, 1], After], 
     Axes -> None] 
& @@
  Take[
    SortBy[
       Tally[
         StringSplit[ToLowerCase[Import[i]], 
          RegularExpression["(\\W|\\b(.|the|and|of|to|i[tns]|or)\\b)+"]]
       ],
    Last],
  -22]

Edit 7 → 199 karakter

BarChart[#2, BarOrigin->Left, ChartLabels->Placed[#1, After], Axes->None]&@@ 
  Transpose@Take[SortBy[Tally@StringSplit[ToLowerCase@Import@i, 
    RegularExpression@"(\\W|\\b(.|the|and|of|to|i[tns]|or)\\b)+"],Last], -22]
  • Diganti fdengan Transposedan Slot( #1/ #2) argumen.
  • Kami tidak membutuhkan braket stinkin (gunakan f@xalih-alih f[x]jika memungkinkan)

belisarius
sumber
9
Anda pikir "RegularExpression" buruk? Saya menangis ketika saya mengetik "System.Text.RegularExpressions.Regex.Split" ke dalam versi C #, hingga saya melihat kode Objective-C: "stringWithContentsOfFile", "enumerateSubstringsInRange", "NSStringEnumerationByombolan", "sort .
Gabe
2
@ Ayo Terima kasih ... Saya merasa lebih baik sekarang. Dalam bahasa Spanyol kita mengatakan "mal de muchos, consuelo de tontos" .. Sesuatu seperti "Banyak yang bermasalah, orang-orang bodoh merasa lega": D
Dr. belisarius
1
Itu |i|berlebihan di regex Anda karena Anda sudah punya .|.
Gabe
1
Saya suka pepatah Spanyol itu. Hal terdekat yang dapat saya pikirkan dalam bahasa Inggris adalah "kesengsaraan mencintai perusahaan". Inilah upaya terjemahan saya: "Bodoh, yang ketika menderita, mendapat penghiburan dalam memikirkan orang lain dalam situasi yang sama." Pekerjaan luar biasa pada implementasi Mathematica, btw.
Dreeves
@dreeves Foolishness melampaui hambatan bahasa dengan mudah ... Senang melihat Anda menyukai program Mathematica kecil saya, saya baru mulai belajar bahasa
Dr. belisarius
26

C # - 510 451 436 446 434 426 422 karakter (diperkecil)

Tidak sesingkat itu, tapi sekarang mungkin benar! Catatan, versi sebelumnya tidak menunjukkan baris pertama bilah, tidak mengatur skala bilah dengan benar, mengunduh file alih-alih mendapatkannya dari stdin, dan tidak menyertakan semua verbositas C # yang diperlukan. Anda dapat dengan mudah mencukur banyak guratan jika C # tidak membutuhkan terlalu banyak omong kosong. Mungkin Powershell bisa berbuat lebih baik.

using C=System.Console;   // alias for Console
using System.Linq;  // for Split, GroupBy, Select, OrderBy, etc.

class Class // must define a class
{
    static void Main()  // must define a Main
    {
        // split into words
        var allwords = System.Text.RegularExpressions.Regex.Split(
                // convert stdin to lowercase
                C.In.ReadToEnd().ToLower(),
                // eliminate stopwords and non-letters
                @"(?:\b(?:the|and|of|to|a|i[tns]?|or)\b|\W)+")
            .GroupBy(x => x)    // group by words
            .OrderBy(x => -x.Count()) // sort descending by count
            .Take(22);   // take first 22 words

        // compute length of longest bar + word
        var lendivisor = allwords.Max(y => y.Count() / (76.0 - y.Key.Length));

        // prepare text to print
        var toPrint = allwords.Select(x=> 
            new { 
                // remember bar pseudographics (will be used in two places)
                Bar = new string('_',(int)(x.Count()/lendivisor)), 
                Word=x.Key 
            })
            .ToList();  // convert to list so we can index into it

        // print top of first bar
        C.WriteLine(" " + toPrint[0].Bar);
        toPrint.ForEach(x =>  // for each word, print its bar and the word
            C.WriteLine("|" + x.Bar + "| " + x.Word));
    }
}

422 karakter dengan lendivisor inline (yang membuatnya 22 kali lebih lambat) dalam bentuk di bawah ini (baris baru digunakan untuk spasi tertentu):

using System.Linq;using C=System.Console;class M{static void Main(){var
a=System.Text.RegularExpressions.Regex.Split(C.In.ReadToEnd().ToLower(),@"(?:\b(?:the|and|of|to|a|i[tns]?|or)\b|\W)+").GroupBy(x=>x).OrderBy(x=>-x.Count()).Take(22);var
b=a.Select(x=>new{p=new string('_',(int)(x.Count()/a.Max(y=>y.Count()/(76d-y.Key.Length)))),t=x.Key}).ToList();C.WriteLine(" "+b[0].p);b.ForEach(x=>C.WriteLine("|"+x.p+"| "+x.t));}}
Gabe
sumber
+1 untuk smart-ass mengunduh file inline. :)
sarnold
1
Curi URL pendek dari jawaban Matt.
indiv
2
Spesifikasi mengatakan file tersebut harus di-piped atau diteruskan sebagai argumen. Jika Anda berasumsi bahwa args [0] berisi nama file lokal, Anda dapat mempersingkatnya dengan menggunakan args [0] alih-alih (WebClient baru ()) .StringString (@ " gutenberg.org/files/11/11. txt " ) -> itu akan menghemat sekitar 70 karakter
thorkia
1
Berikut adalah versi yang menggantikan panggilan WebClient dengan args 0, panggilan ke StreamReader, dan menghapus beberapa spasi tambahan. Total jumlah char = 413 var a = Regex.Replace ((StreamReader baru (args [0])). ReadToEnd (), "[^ a-zA-Z]", "") .ToLower (). Split ('' ). Dimana (x =>! (Baru [] {"the", "dan", "dari", "to", "a", "i", "it", "in", "atau", " is "}). Berisi (x)). GroupBy (x => x) .Pilih (g => baru {w = g.Key, c = g.Count ()}). OrderByDescending (x => xc). Lewati (1) .Ambil (22) .ToList (); var m = a.OrderByDescending (x => xc) .First (); a.ForEach (x => Console.WriteLine ("|" + new String (' _ ', xc * (80-mw Panjang-4) / mc) + "|" + xw));
thorkia
"new StreamReader" tanpa "menggunakan" kotor. File.ReadAllText (args [0]) atau Console.In.ReadToEnd () jauh lebih baik. Dalam kasus terakhir Anda bahkan dapat menghapus argumen dari Main () Anda. :)
Rotsor
25

Perl, 237 229 209 karakter

(Diperbarui lagi untuk mengalahkan versi Ruby dengan lebih banyak trik golf kotor, diganti split/[^a-z/,lcdengan lc=~/[a-z]+/g, dan menghilangkan cek untuk string kosong di tempat lain. Ini terinspirasi oleh versi Ruby, jadi kreditlah yang memberi kredit.)

Perbarui: sekarang dengan Perl 5.10! Ganti printdengan say, dan gunakan ~~untuk menghindari a map. Ini harus dipanggil pada baris perintah sebagai perl -E '<one-liner>' alice.txt. Karena keseluruhan skrip ada dalam satu baris, menulisnya sebagai satu-baris tidak akan menimbulkan kesulitan :).

 @s=qw/the and of to a i it in or is/;$c{$_}++foreach grep{!($_~~@s)}map{lc=~/[a-z]+/g}<>;@s=sort{$c{$b}<=>$c{$a}}keys%c;$f=76-length$s[0];say" "."_"x$f;say"|"."_"x($c{$_}/$c{$s[0]}*$f)."| $_ "foreach@s[0..21];

Perhatikan bahwa versi ini menormalkan untuk kasus. Ini tidak memperpendek solusinya, karena melepas ,lc(untuk casing yang lebih rendah) mengharuskan Anda untuk menambah A-Zregex split, jadi ini adalah pencucian.

Jika Anda berada di sistem di mana baris baru adalah satu karakter dan bukan dua, Anda dapat mempersingkat ini dengan dua karakter lain dengan menggunakan baris baru literal sebagai pengganti \n. Namun, saya belum menulis contoh di atas seperti itu, karena "lebih jelas" (ha!) Seperti itu.


Berikut ini sebagian besar solusi perl yang benar, tetapi tidak cukup pendek:

use strict;
use warnings;

my %short = map { $_ => 1 } qw/the and of to a i it in or is/;
my %count = ();

$count{$_}++ foreach grep { $_ && !$short{$_} } map { split /[^a-zA-Z]/ } (<>);
my @sorted = (sort { $count{$b} <=> $count{$a} } keys %count)[0..21];
my $widest = 76 - (length $sorted[0]);

print " " . ("_" x $widest) . "\n";
foreach (@sorted)
{
    my $width = int(($count{$_} / $count{$sorted[0]}) * $widest);
    print "|" . ("_" x $width) . "| $_ \n";
}

Berikut ini adalah tentang sesingkat itu bisa tetap relatif dapat dibaca. (392 karakter).

%short = map { $_ => 1 } qw/the and of to a i it in or is/;
%count;

$count{$_}++ foreach grep { $_ && !$short{$_} } map { split /[^a-z]/, lc } (<>);
@sorted = (sort { $count{$b} <=> $count{$a} } keys %count)[0..21];
$widest = 76 - (length $sorted[0]);

print " " . "_" x $widest . "\n";
print"|" . "_" x int(($count{$_} / $count{$sorted[0]}) * $widest) . "| $_ \n" foreach @sorted;
JSB ձոգչ
sumber
Memiliki beberapa bug saat ini; memperbaiki dan memperpendek.
JSB ձոգչ
4
Ini tidak mencakup kasus ketika kata kedua jauh lebih lama dari yang pertama, bukan?
Joey
1
Keduanya foreachdapat ditulis sebagai fors. Itu 8 karakter. Maka Anda memiliki grep{!($_~~@s)}map{lc=~/[a-z]+/g}<>, yang saya percaya dapat ditulis grep{!(/$_/i~~@s)}<>=~/[a-z]+/guntuk turun lebih 4. Ganti " "dengan $"dan Anda turun 1 lagi ...
Zaid
sort{$c{$b}-$c{$a}}...untuk menyimpan dua lagi. Anda juga bisa hanya meneruskan %calih-alih keys %cke sortfungsi dan menyimpan empat lagi.
mob
20

Windows PowerShell, 199 karakter

$x=$input-split'\P{L}'-notmatch'^(the|and|of|to|.?|i[tns]|or)$'|group|sort *
filter f($w){' '+'_'*$w
$x[-1..-22]|%{"|$('_'*($w*$_.Count/$x[-1].Count))| "+$_.Name}}
f(76..1|?{!((f $_)-match'.'*80)})[0]

(Pemutusan baris terakhir tidak perlu, tetapi termasuk di sini agar mudah dibaca.)

(Kode saat ini dan file pengujian saya tersedia di repositori SVN saya . Saya berharap kasus pengujian saya menangkap kesalahan yang paling umum (panjang bilah, masalah dengan pencocokan regex dan beberapa lainnya))

Asumsi:

  • AS ASCII sebagai masukan. Mungkin aneh dengan Unicode.
  • Setidaknya dua kata tanpa henti dalam teks

Sejarah

Versi santai (137), karena itu dihitung secara terpisah sekarang, tampaknya:

($x=$input-split'\P{L}'-notmatch'^(the|and|of|to|.?|i[tns]|or)$'|group|sort *)[-1..-22]|%{"|$('_'*(76*$_.Count/$x[-1].Count))| "+$_.Name}
  • tidak menutup bilah pertama
  • tidak memperhitungkan panjang kata selain kata pertama

Variasi panjang batang satu karakter dibandingkan dengan solusi lain adalah karena PowerShell menggunakan pembulatan alih-alih pemotongan ketika mengubah angka titik-mengambang menjadi bilangan bulat. Karena tugas yang diperlukan hanya panjang batang proporsional, ini harus baik-baik saja.

Dibandingkan dengan solusi lain, saya mengambil pendekatan yang sedikit berbeda dalam menentukan panjang bar terpanjang hanya dengan mencoba dan mengambil panjang tertinggi di mana tidak ada garis yang lebih panjang dari 80 karakter.

Versi yang lebih lama dijelaskan dapat ditemukan di sini .

Јοеу
sumber
Mengesankan, sepertinya Powershell adalah lingkungan yang cocok untuk bermain golf. Pendekatan Anda mempertimbangkan panjang batang adalah apa yang saya coba gambarkan (tidak begitu cemerlang, saya akui) dalam spesifikasi.
ChristopheD
1
@ChristopheD: Dalam pengalaman saya (Anarchy Golf, beberapa tugas Project Euler dan beberapa tugas hanya untuk bersenang-senang), PowerShell biasanya hanya sedikit lebih buruk daripada Ruby dan sering diikat dengan atau lebih baik dari Perl dan Python. Tidak cocok dengan GolfScript. Tetapi sejauh yang saya bisa lihat, ini mungkin solusi terpendek yang dengan benar memperhitungkan panjang batang ;-)
Joey
Ternyata saya benar. Powershell dapat melakukan yang lebih baik - jauh lebih baik! Harap berikan versi yang diperluas dengan komentar.
Gabe
Johannes: Apakah Anda sudah mencoba -split("\b(?:the|and|of|to|a|i[tns]?|or)\b|[^a-z]")? Ini bekerja untuk saya.
Gabe
Jangan lupa untuk menginterpolasi string output: "|$('_'*($w*$_.count/$x[0].count))| $($_.name) "(atau menghilangkan spasi terakhir, karena ini semacam otomatis). Dan Anda dapat menggunakan -split("(?:\b(?:the|and|of|to|a|i[tns]?|or)\b|[^a-z])+")untuk menyimpan lebih banyak dengan tidak memasukkan blank (atau gunakan [-2..-23]).
Gabe
19

Ruby, 215, 216 , 218 , 221 , 224 , 236 , 237 karakter

pembaruan 1: Hore ! Ini dasi dengan JS Bangs ' solusi . Tidak bisa memikirkan cara untuk mengurangi lagi :)

pembaruan 2: Memainkan trik golf yang kotor. Diubah eachmenjadi mapuntuk menyimpan 1 karakter :)

pembaruan 3: Diubah File.readke IO.read+2. Array.group_bytidak terlalu membuahkan hasil, berubah menjadi reduce+6. Pengecekan case case tidak diperlukan setelah casing lebih rendah dengan downcasedi regex +1. Menyortir dalam urutan menurun mudah dilakukan dengan meniadakan nilai +6. Total penghematan +15

perbarui 4: [0]daripada .first, +3. (@ Shtééf)

pembaruan 5: Perluas variabel ldi tempat, +1. Perluas variabel sdi tempat, +2. (@ Shtééf)

pembaruan 6: Gunakan penambahan string daripada interpolasi untuk baris pertama, +2. (@ Shtééf)

w=(IO.read($_).downcase.scan(/[a-z]+/)-%w{the and of to a i it in or is}).reduce(Hash.new 0){|m,o|m[o]+=1;m}.sort_by{|k,v|-v}.take 22;m=76-w[0][0].size;puts' '+'_'*m;w.map{|x,f|puts"|#{'_'*(f*1.0/w[0][1]*m)}| #{x} "}

pembaruan 7: Saya mengalami banyak kehebohan untuk mendeteksi iterasi pertama di dalam loop, menggunakan variabel instan. Yang saya dapatkan adalah +1, meskipun mungkin ada potensi. Mempertahankan versi sebelumnya, karena saya percaya ini adalah ilmu hitam. (@ Shtééf)

(IO.read($_).downcase.scan(/[a-z]+/)-%w{the and of to a i it in or is}).reduce(Hash.new 0){|m,o|m[o]+=1;m}.sort_by{|k,v|-v}.take(22).map{|x,f|@f||(@f=f;puts' '+'_'*(@m=76-x.size));puts"|#{'_'*(f*1.0/@f*@m)}| #{x} "}

Versi yang mudah dibaca

string = File.read($_).downcase

words = string.scan(/[a-z]+/i)
allowed_words = words - %w{the and of to a i it in or is}
sorted_words = allowed_words.group_by{ |x| x }.map{ |x,y| [x, y.size] }.sort{ |a,b| b[1] <=> a[1] }.take(22)
highest_frequency = sorted_words.first
highest_frequency_count = highest_frequency[1]
highest_frequency_word = highest_frequency[0]

word_length = highest_frequency_word.size
widest = 76 - word_length

puts " #{'_' * widest}"    
sorted_words.each do |word, freq|
  width = (freq * 1.0 / highest_frequency_count) * widest
  puts "|#{'_' * width}| #{word} "
end

Menggunakan:

echo "Alice.txt" | ruby -ln GolfedWordFrequencies.rb

Keluaran:

 _________________________________________________________________________
|_________________________________________________________________________| she 
|_______________________________________________________________| you 
|____________________________________________________________| said 
|_____________________________________________________| alice 
|_______________________________________________| was 
|___________________________________________| that 
|____________________________________| as 
|________________________________| her 
|_____________________________| with 
|_____________________________| at 
|____________________________| s 
|____________________________| t 
|__________________________| on 
|__________________________| all 
|_______________________| this 
|_______________________| for 
|_______________________| had 
|_______________________| but 
|______________________| be 
|_____________________| not 
|____________________| they 
|____________________| so 
Anurag
sumber
3
Bukankah "p" cara pintas untuk "menempatkan"? Itu bisa mencukur beberapa.
rfusca
1
Bagus. Penggunaan Anda scan, meskipun, memberi saya ide yang lebih baik, jadi saya maju lagi :).
JSB ձոգչ
2
Anda perlu mengatur skala bilah sehingga kata paling panjang ditambah bilahnya muat pada 80 karakter. Seperti yang disarankan Brian, kata kedua yang panjang akan merusak program Anda.
Gabe
3
Saya heran mengapa ini masih mengumpulkan suara. Solusinya salah (dalam kasus umum) dan solusi Ruby dua arah yang lebih pendek ada di sini sekarang.
Joey
1
Sekarang, koreksi saya jika saya salah, tetapi alih-alih menggunakan "downcase", mengapa Anda tidak menggunakan flag case case REGEXP yang tidak sensitif, yang menghemat 6-7 byte, bukan?
st0le
19

Python 2.x, pendekatan latitudinarian = 227 183 karakter

import sys,re
t=re.split('\W+',sys.stdin.read().lower())
r=sorted((-t.count(w),w)for w in set(t)if w not in'andithetoforinis')[:22]
for l,w in r:print(78-len(r[0][1]))*l/r[0][0]*'=',w

Mengizinkan kebebasan dalam implementasi, saya membuat rangkaian string yang berisi semua kata yang diminta untuk dikecualikan ( the, and, of, to, a, i, it, in, or, is) - ditambah juga mengecualikan dua "kata" yang terkenal sdan tdari contoh - dan saya melemparkan secara gratis pengecualian untuk an, for, he. Saya mencoba semua rangkaian kata-kata itu terhadap kumpulan kata-kata dari Alice, King James 'Bible dan file Jargon untuk melihat apakah ada kata-kata yang akan dikecualikan oleh string. Dan itulah yang saya akhiri dengan dua string pengecualian: itheandtoforinisdan andithetoforinis.

PS. dipinjam dari solusi lain untuk mempersingkat kode.

=========================================================================== she 
================================================================= you
============================================================== said
====================================================== alice
================================================ was
============================================ that
===================================== as
================================= her
============================== at
============================== with
=========================== on
=========================== all
======================== this
======================== had
======================= but
====================== be
====================== not
===================== they
==================== so
=================== very
=================== what
================= little

Kata-kata kasar

Mengenai kata-kata yang diabaikan, orang akan berpikir itu akan diambil dari daftar kata-kata yang paling banyak digunakan dalam bahasa Inggris. Daftar itu tergantung pada corpus teks yang digunakan. Per salah satu daftar paling populer ( http://en.wikipedia.org/wiki/Most_common_words_in_English , http://www.english-for-students.com/Frequently-Used-Words.html , http: // www. sporcle.com/games/common_english_words.php ), 10 kata teratas adalah:the be(am/are/is/was/were) to of and a in that have I

10 kata teratas dari teks Alice in Wonderland adalah the and to a of it she i you said
10 kata teratas dari File Jargon (v4.4.7) adalahthe a of to and in is that or for

Jadi pertanyaannya adalah mengapa ordimasukkan dalam daftar pengabaian masalah, di mana itu ~ 30 dalam popularitas ketika kata that(8 paling banyak digunakan) tidak. dll, dll. Oleh karena itu saya percaya daftar abaikan harus diberikan secara dinamis (atau bisa dihilangkan).

Gagasan alternatif adalah melompati 10 kata teratas dari hasil - yang sebenarnya akan mempersingkat solusinya (elementer - harus hanya menampilkan entri ke-11 hingga ke-32).


Python 2.x, pendekatan tepat waktu = 277 243 karakter

Bagan yang digambar dalam kode di atas disederhanakan (hanya menggunakan satu karakter untuk bilah). Jika seseorang ingin mereproduksi bagan dengan tepat dari deskripsi masalah (yang tidak diperlukan), kode ini akan melakukannya:

import sys,re
t=re.split('\W+',sys.stdin.read().lower())
r=sorted((-t.count(w),w)for w in set(t)-set(sys.argv))[:22]
h=min(9*l/(77-len(w))for l,w in r)
print'',9*r[0][0]/h*'_'
for l,w in r:print'|'+9*l/h*'_'+'|',w

Saya mengambil masalah dengan pilihan 10 kata yang agak acak untuk dikecualikan the, and, of, to, a, i, it, in, or, issehingga harus dilewatkan sebagai parameter baris perintah, seperti:
python WordFrequencyChart.py the and of to a i it in or is <"Alice's Adventures in Wonderland.txt"

Ini adalah 213 karakter + 30 jika kita memperhitungkan daftar abaikan "asli" yang diteruskan pada baris perintah = 243

PS. Kode kedua juga melakukan "penyesuaian" untuk panjang semua kata teratas, sehingga tidak ada yang akan meluap dalam huruf besar.

 _______________________________________________________________
|_______________________________________________________________| she
|_______________________________________________________| superlongstringstring
|_____________________________________________________| said
|______________________________________________| alice
|_________________________________________| was
|______________________________________| that
|_______________________________| as
|____________________________| her
|__________________________| at
|__________________________| with
|_________________________| s
|_________________________| t
|_______________________| on
|_______________________| all
|____________________| this
|____________________| for
|____________________| had
|____________________| but
|___________________| be
|___________________| not
|_________________| they
|_________________| so
Nas Banov
sumber
Solusi yang bagus sejauh ini meskipun daftar abaikan kata belum diimplementasikan (belum) dan bilah-bilahnya agak belum sempurna saat ini.
ChristopheD
@ChristopheD: ada di sana, tetapi tidak ada "panduan pengguna". Baru saja menambahkan banyak teks
Nas Banov
Mengenai daftar bahasa dan solusi Anda: Silakan cari solusi yang menggunakan pemisahan \Watau penggunaan \bdalam regex karena itu kemungkinan besar tidak sesuai dengan spesifikasi, yang berarti mereka tidak akan terpecah pada angka atau _dan mereka juga mungkin tidak menghapus kata berhenti dari string seperti the_foo_or123bar. Mereka mungkin tidak muncul dalam teks pengujian tetapi spesifikasinya cukup jelas dalam kasus itu.
Joey
Kerja luar biasa Nas, saya menghabiskan sore hari mencoba mengoptimalkan ini dan hanya menemukan satu perbaikan. Anda dapat memotongnya menjadi 239 karakter dengan menghapus sys.argvre.findall(r'\b(?!(?:the|and|.|of|to|i[tns]|or)\b)\w+',sys.stdin.read().lower())
retasan
12

Haskell - 366 351 344 337 333 karakter

(Satu baris maintambahan ditambahkan agar mudah dibaca, dan tidak ada baris tambahan diperlukan pada akhir baris terakhir.)

import Data.List
import Data.Char
l=length
t=filter
m=map
f c|isAlpha c=toLower c|0<1=' '
h w=(-l w,head w)
x!(q,w)='|':replicate(minimum$m(q?)x)'_'++"| "++w
q?(g,w)=q*(77-l w)`div`g
b x=m(x!)x
a(l:r)=(' ':t(=='_')l):l:r
main=interact$unlines.a.b.take 22.sort.m h.group.sort
  .t(`notElem`words"the and of to a i it in or is").words.m f

Cara kerjanya paling baik dilihat dengan membaca argumen di interactbelakang:

  • map f alfabet huruf kecil, menggantikan yang lainnya dengan spasi.
  • words menghasilkan daftar kata, menjatuhkan spasi yang memisahkan.
  • filter (notElem words "the and of to a i it in or is")membuang semua entri dengan kata-kata terlarang.
  • group . sort mengurutkan kata-kata, dan mengelompokkan yang identik ke dalam daftar.
  • map hmemetakan setiap daftar kata yang identik ke tupel formulir (-frequency, word).
  • take 22 . sort mengurutkan tupel dengan frekuensi menurun (entri tupel pertama), dan hanya menyimpan 22 tupel pertama.
  • b peta tupel ke bar (lihat di bawah).
  • a menambahkan baris pertama garis bawah, untuk melengkapi bilah paling atas.
  • unlines bergabung dengan semua baris ini bersama dengan baris baru.

Agak sulit adalah mendapatkan panjang bar yang benar. Saya berasumsi bahwa hanya garis bawah yang dihitung terhadap panjang bilah, jadi ||bilah dengan panjang nol. Fungsi bpeta c xberakhir x, di mana xdaftar histogram. Seluruh daftar diteruskan ke c, sehingga setiap doa cdapat menghitung faktor skala untuk dirinya sendiri dengan menelepon u. Dengan cara ini, saya menghindari menggunakan matematika atau rasional floating-point, yang fungsi konversi dan impornya akan memakan banyak karakter.

Perhatikan trik menggunakan -frequency. Hal ini menghilangkan kebutuhan untuk reverseyang sortsejak menyortir (naik) -frequencyakan tempat kata-kata dengan frekuensi terbesar pertama. Kemudian, dalam fungsi u, dua -frequencynilai dikalikan, yang akan membatalkan negasi keluar.

Thomas
sumber
Kerja yang sangat bagus (akan mendukung tetapi kehabisan suara untuk hari ini dengan semua jawaban bagus di utas ini).
ChristopheD
Ini menyakitkan mata saya dengan cara yang menyakitkan bahkan untuk dipikirkan, tetapi saya belajar banyak dari Haskell dengan merekayasa baliknya menjadi kode yang dapat dibaca. Bagus, tuan. :-)
Owen S.
Ini sebenarnya Haskell masih cukup idiomatis, meskipun tidak terlalu efisien. Nama-nama pendek membuatnya terlihat jauh lebih buruk daripada yang sebenarnya.
Thomas
@ Thomas: Anda bisa mengatakan itu lagi. :-)
Owen S.
1
Tidak bisa memindahkannya div, sebenarnya! Cobalah - hasilnya salah. Alasannya adalah bahwa melakukan divsebelum *kehilangan presisi.
MtnViewMark
11

JavaScript 1.8 (SpiderMonkey) - 354

x={};p='|';e=' ';z=[];c=77
while(l=readline())l.toLowerCase().replace(/\b(?!(the|and|of|to|a|i[tns]?|or)\b)\w+/g,function(y)x[y]?x[y].c++:z.push(x[y]={w:y,c:1}))
z=z.sort(function(a,b)b.c-a.c).slice(0,22)
for each(v in z){v.r=v.c/z[0].c
c=c>(l=(77-v.w.length)/v.r)?l:c}for(k in z){v=z[k]
s=Array(v.r*c|0).join('_')
if(!+k)print(e+s+e)
print(p+s+p+e+v.w)}

Sayangnya, for([k,v]in z)dari versi Badak sepertinya tidak mau bekerja di SpiderMonkey, dan readFile()sedikit lebih mudah daripada menggunakan readline()tetapi naik ke 1,8 memungkinkan kita untuk menggunakan fungsi penutupan untuk memotong beberapa baris lagi ....

Menambahkan spasi putih untuk dibaca:

x={};p='|';e=' ';z=[];c=77
while(l=readline())
  l.toLowerCase().replace(/\b(?!(the|and|of|to|a|i[tns]?|or)\b)\w+/g,
   function(y) x[y] ? x[y].c++ : z.push( x[y] = {w: y, c: 1} )
  )
z=z.sort(function(a,b) b.c - a.c).slice(0,22)
for each(v in z){
  v.r=v.c/z[0].c
  c=c>(l=(77-v.w.length)/v.r)?l:c
}
for(k in z){
  v=z[k]
  s=Array(v.r*c|0).join('_')
  if(!+k)print(e+s+e)
  print(p+s+p+e+v.w)
}

Pemakaian: js golf.js < input.txt

Keluaran:

 _________________________________________________________________________ 
| _________________________________________________________________________ | | dia
| _______________________________________________________________ | kamu
| ____________________________________________________________ | kata
| ____________________________________________________ | Alice
| ______________________________________________ | dulu
| ___________________________________________ | bahwa
| ___________________________________ | sebagai
| ________________________________ | -nya
| _____________________________ | di
| _____________________________ | dengan
| ____________________________ | s
| ____________________________ | t
| __________________________ | di
| _________________________ | semua
| _______________________ | ini
| ______________________ | untuk
| ______________________ | telah
| ______________________ | tapi
| _____________________ | menjadi
| _____________________ | tidak
| ___________________ | mereka
| ___________________ | begitu

(versi dasar - tidak menangani lebar batang dengan benar)

JavaScript (Badak) - 405 395 387 377 368 343 304 karakter

Saya pikir logika penyortiran saya tidak aktif, tapi .. saya duno. Brainfart diperbaiki.

Diminimalkan (penyalahgunaan \ndiartikan sebagai ;kadang - kadang):

x={};p='|';e=' ';z=[]
readFile(arguments[0]).toLowerCase().replace(/\b(?!(the|and|of|to|a|i[tns]?|or)\b)\w+/g,function(y){x[y]?x[y].c++:z.push(x[y]={w:y,c:1})})
z=z.sort(function(a,b){return b.c-a.c}).slice(0,22)
for([k,v]in z){s=Array((v.c/z[0].c)*70|0).join('_')
if(!+k)print(e+s+e)
print(p+s+p+e+v.w)}
Matt
sumber
Ah, tuan. Saya percaya ini adalah tantangan Anda. Apakah kedua Anda berbicara kepada saya.
dmckee --- ex-moderator kitten
2
BTW - Saya suka i[tns]?bitnya. Sangat licik.
dmckee --- ex-moderator kitten
@dmckee - dimainkan dengan baik, saya tidak berpikir saya bisa mengalahkan 336 Anda, nikmati upvote Anda yang sangat layak :)
Matt
Anda pasti bisa mengalahkan 336 ... Ada potongan 23 karakter yang tersedia - .replace(/[^\w ]/g, e).split(/\s+/).map(dapat diganti dengan .replace(/\w+/g,dan menggunakan fungsi yang sama seperti yang Anda .maplakukan ... Juga tidak yakin apakah Badak mendukung function(a,b)b.c-a.calih-alih fungsi sortir Anda (spidermonkey tidak), tetapi itu akan bercukur {return }... b.c-a.cadalah jenis yang lebih baik daripada a.c<b.c... Mengedit versi Spidermonkey di bagian bawah dengan perubahan ini
gnarf
Saya memindahkan versi SpiderMonkey saya ke atas karena sesuai dengan batasan lebar bar ... Juga berhasil memotong beberapa karakter di versi asli Anda dengan menggunakan regexp lookahead negatif untuk menolak kata-kata yang memungkinkan penggantian tunggal (), dan bermain golf seandainya saja dengan ?:dasar yang bagus untuk bekerja!
gnarf
11

Versi PHP CLI (450 karakter)

Solusi ini memperhitungkan persyaratan terakhir yang sebagian besar puritan telah dipilih untuk diabaikan. Itu menghabiskan 170 karakter!

Pemakaian: php.exe <this.php> <file.txt>

Diperkecil:

<?php $a=array_count_values(array_filter(preg_split('/[^a-z]/',strtolower(file_get_contents($argv[1])),-1,1),function($x){return !preg_match("/^(.|the|and|of|to|it|in|or|is)$/",$x);}));arsort($a);$a=array_slice($a,0,22);function R($a,$F,$B){$r=array();foreach($a as$x=>$f){$l=strlen($x);$r[$x]=$b=$f*$B/$F;if($l+$b>76)return R($a,$f,76-$l);}return$r;}$c=R($a,max($a),76-strlen(key($a)));foreach($a as$x=>$f)echo '|',str_repeat('-',$c[$x]),"| $x\n";?>

Dapat dibaca manusia:

<?php

// Read:
$s = strtolower(file_get_contents($argv[1]));

// Split:
$a = preg_split('/[^a-z]/', $s, -1, PREG_SPLIT_NO_EMPTY);

// Remove unwanted words:
$a = array_filter($a, function($x){
       return !preg_match("/^(.|the|and|of|to|it|in|or|is)$/",$x);
     });

// Count:
$a = array_count_values($a);

// Sort:
arsort($a);

// Pick top 22:
$a=array_slice($a,0,22);


// Recursive function to adjust bar widths
// according to the last requirement:
function R($a,$F,$B){
    $r = array();
    foreach($a as $x=>$f){
        $l = strlen($x);
        $r[$x] = $b = $f * $B / $F;
        if ( $l + $b > 76 )
            return R($a,$f,76-$l);
    }
    return $r;
}

// Apply the function:
$c = R($a,max($a),76-strlen(key($a)));


// Output:
foreach ($a as $x => $f)
    echo '|',str_repeat('-',$c[$x]),"| $x\n";

?>

Keluaran:

|-------------------------------------------------------------------------| she
|---------------------------------------------------------------| you
|------------------------------------------------------------| said
|-----------------------------------------------------| alice
|-----------------------------------------------| was
|-------------------------------------------| that
|------------------------------------| as
|--------------------------------| her
|-----------------------------| at
|-----------------------------| with
|--------------------------| on
|--------------------------| all
|-----------------------| this
|-----------------------| for
|-----------------------| had
|-----------------------| but
|----------------------| be
|---------------------| not
|--------------------| they
|--------------------| so
|-------------------| very
|------------------| what

Ketika ada kata yang panjang, bilah disesuaikan dengan benar:

|--------------------------------------------------------| she
|---------------------------------------------------| thisisareallylongwordhere
|-------------------------------------------------| you
|-----------------------------------------------| said
|-----------------------------------------| alice
|------------------------------------| was
|---------------------------------| that
|---------------------------| as
|-------------------------| her
|-----------------------| with
|-----------------------| at
|--------------------| on
|--------------------| all
|------------------| this
|------------------| for
|------------------| had
|-----------------| but
|-----------------| be
|----------------| not
|---------------| they
|---------------| so
|--------------| very
pengguna382874
sumber
11

Python 3.1 - 245 229 karakter

Saya kira menggunakan Counter agak curang :) Saya baru saja membacanya sekitar seminggu yang lalu, jadi ini adalah kesempatan sempurna untuk melihat cara kerjanya.

import re,collections
o=collections.Counter([w for w in re.findall("[a-z]+",open("!").read().lower())if w not in"a and i in is it of or the to".split()]).most_common(22)
print('\n'.join('|'+76*v//o[0][1]*'_'+'| '+k for k,v in o))

Mencetak:

|____________________________________________________________________________| she
|__________________________________________________________________| you
|_______________________________________________________________| said
|_______________________________________________________| alice
|_________________________________________________| was
|_____________________________________________| that
|_____________________________________| as
|__________________________________| her
|_______________________________| with
|_______________________________| at
|______________________________| s
|_____________________________| t
|____________________________| on
|___________________________| all
|________________________| this
|________________________| for
|________________________| had
|________________________| but
|______________________| be
|______________________| not
|_____________________| they
|____________________| so

Beberapa kode "dipinjam" dari solusi AKX.

sdolan
sumber
Baris pertama tidak ada. Dan panjang bilah tidak benar.
Joey
di kode Anda tampaknya open('!')membaca dari stdin - yang versi / OS yang aktif? atau Anda harus memberi nama file '!'?
Nas Banov
Beri nama file "!" :) Maaf itu sangat tidak jelas, dan saya harus menyebutkannya.
Sam Dolan
11

perl, 205 191 189 karakter / 205 karakter (sepenuhnya diimplementasikan)

Beberapa bagian terinspirasi oleh pengiriman perl / ruby ​​sebelumnya, beberapa ide serupa tiba di independen, yang lain asli. Versi yang lebih pendek juga menggabungkan beberapa hal yang saya lihat / pelajari dari kiriman lainnya.

Asli:

$k{$_}++for grep{$_!~/^(the|and|of|to|a|i|it|in|or|is)$/}map{lc=~/[a-z]+/g}<>;@t=sort{$k{$b}<=>$k{$a}}keys%k;$l=76-length$t[0];printf" %s
",'_'x$l;printf"|%s| $_
",'_'x int$k{$_}/$k{$t[0]}*$l for@t[0..21];

Versi terbaru hingga 191 karakter:

/^(the|and|of|to|.|i[tns]|or)$/||$k{$_}++for map{lc=~/[a-z]+/g}<>;@e=sort{$k{$b}<=>$k{$a}}keys%k;$n=" %s
";$r=(76-y///c)/$k{$_=$e[0]};map{printf$n,'_'x($k{$_}*$r),$_;$n="|%s| %s
"}@e[0,0..21]

Versi terbaru hingga 189 karakter:

/^(the|and|of|to|.|i[tns]|or)$/||$k{$_}++for map{lc=~/[a-z]+/g}<>;@_=sort{$k{$b}<=>$k{$a}}keys%k;$n=" %s
";$r=(76-m//)/$k{$_=$_[0]};map{printf$n,'_'x($k{$_}*$r),$_;$n="|%s| %s
"}@_[0,0..21]

Versi ini (205 karakter) menyumbang baris dengan kata-kata lebih panjang dari apa yang akan ditemukan nanti.

/^(the|and|of|to|.|i[tns]|or)$/||$k{$_}++for map{lc=~/[a-z]+/g}<>;($r)=sort{$a<=>$b}map{(76-y///c)/$k{$_}}@e=sort{$k{$b}<=>$k{$a}}keys%k;$n=" %s
";map{printf$n,'_'x($k{$_}*$r),$_;$n="|%s| %s
";}@e[0,0..21]
pdehaan
sumber
10

Perl: 203 202 201 198 195 208 208/231 chars

$/=\0;/^(the|and|of|to|.|i[tns]|or)$/i||$x{lc$_}++for<>=~/[a-z]+/gi;map{$z=$x{$_};$y||{$y=(76-y///c)/$z}&&warn" "."_"x($z*$y)."\n";printf"|%.78s\n","_"x($z*$y)."| $_"}(sort{$x{$b}<=>$x{$a}}keys%x)[0..21]

Alternatif, implementasi penuh termasuk perilaku yang ditunjukkan (global bar-squishing) untuk kasus patologis di mana kata kedua populer dan cukup lama untuk digabung menjadi lebih dari 80 karakter ( implementasi ini 231 karakter ):

$/=\0;/^(the|and|of|to|.|i[tns]|or)$/i||$x{lc$_}++for<>=~/[a-z]+/gi;@e=(sort{$x{$b}<=>$x{$a}}keys%x)[0..21];for(@e){$p=(76-y///c)/$x{$_};($y&&$p>$y)||($y=$p)}warn" "."_"x($x{$e[0]}*$y)."\n";for(@e){warn"|"."_"x($x{$_}*$y)."| $_\n"}

Spesifikasi tidak menyatakan di mana pun bahwa ini harus pergi ke STDOUT, jadi saya menggunakan perl perl () alih-alih mencetak - empat karakter disimpan di sana. Peta yang digunakan alih-alih foreach, tapi saya merasa masih ada penghematan lagi di split (gabung ()). Namun, turun ke 203 - mungkin tidur di atasnya. Setidaknya Perl sekarang di bawah "shell, grep, tr, grep, sort, uniq, sort, head, perl" hitungan char untuk saat ini;)

PS: Reddit mengatakan "Hai";)

Pembaruan: Dihapus join () yang mendukung penugasan dan konversi skalar implisit bergabung. Turun ke 202. Juga harap dicatat saya telah memanfaatkan aturan opsional "abaikan kata-kata 1" untuk mencukur 2 karakter, jadi ingatlah bahwa frekuensi akan mencerminkan hal ini.

Pembaruan 2: Menukar tugas dan bergabung secara implisit karena membunuh $ / untuk mendapatkan file dalam sekali teguk menggunakan <> di tempat pertama. Ukuran yang sama, tetapi nastier. Diganti jika (! $ Y) {} untuk $ y || {} &&, disimpan 1 karakter lagi => 201.

Pembaruan 3: Mengambil kendali lebih rendah dari awal (lc <>) dengan memindahkan lc keluar dari blok peta - Mengganti kedua regex ke tidak lagi menggunakan opsi / i, karena tidak lagi diperlukan. Tukar kondisional eksplisit x? Y: z dibangun untuk perlgolf tradisional || konstruksi kondisional implisit - /^...$/i?1:$x{$ } ++ untuk /^...$/||$x{$ } ++ Menyimpan tiga karakter! => 198, memecahkan 200 penghalang. Mungkin akan segera tidur ... mungkin.

Pembaruan 4: Kurang tidur membuat saya gila. Baik. Lebih gila. Mengira bahwa ini hanya perlu mengurai file teks bahagia normal, saya membuatnya menyerah jika hits nol. Menyimpan dua karakter. Diganti "length" dengan 1-char lebih pendek (dan lebih golf) y /// c - Anda dengar, GolfScript ?? Aku datang untukmu!!! menangis

Pembaruan 5: Sleep dep membuat saya lupa tentang batas 22row dan pembatasan baris berikutnya. Cadangkan hingga 208 dengan yang ditangani. Tidak terlalu buruk, 13 karakter untuk menanganinya bukan akhir dari dunia. Bermain-main dengan regex inline eval perl, tetapi mengalami kesulitan untuk membuatnya bekerja dan menghemat karakter ... lol. Diperbarui contoh untuk mencocokkan keluaran saat ini.

Pembaruan 6: Menghapus kawat gigi yang tidak dibutuhkan yang melindungi (...) untuk, karena permen sintaksis ++ memungkinkan mendorongnya ke atas untuk bahagia. Terima kasih atas masukan dari Chas. Owens (mengingatkan otak saya yang lelah), mendapat solusi kelas karakter di sana. Kembali ke 203.

Pembaruan 7: Menambahkan karya kedua, implementasi penuh spesifikasi (termasuk perilaku bar-squishing penuh untuk kata-kata sekunder, bukan pemotongan yang dilakukan kebanyakan orang, berdasarkan spesifikasi asli tanpa contoh kasus patologis)

Contoh:

 _________________________________________________________________________
|_________________________________________________________________________| she
|_______________________________________________________________| you
|____________________________________________________________| said
|_____________________________________________________| alice
|_______________________________________________| was
|___________________________________________| that
|____________________________________| as
|________________________________| her
|_____________________________| with
|_____________________________| at
|__________________________| on
|__________________________| all
|_______________________| this
|_______________________| for
|_______________________| had
|_______________________| but
|______________________| be
|_____________________| not
|____________________| they
|____________________| so
|___________________| very
|__________________| what

Implementasi alternatif dalam contoh kasus patologis:

 _______________________________________________________________
|_______________________________________________________________| she
|_______________________________________________________| superlongstringstring
|____________________________________________________| said
|______________________________________________| alice
|________________________________________| was
|_____________________________________| that
|_______________________________| as
|____________________________| her
|_________________________| with
|_________________________| at
|_______________________| on
|______________________| all
|____________________| this
|____________________| for
|____________________| had
|____________________| but
|___________________| be
|__________________| not
|_________________| they
|_________________| so
|________________| very
|________________| what
Syntaera
sumber
Anda dapat mempersingkat regex untuk kata-kata berhenti oleh runtuh is|in|it|ike i[snt]?- dan kemudian tidak ada perbedaan dengan aturan opsional lagi. (Hm, saya tidak akan pernah berpikir untuk memberi tahu seorang pria Perl cara melakukan Regex: D) - satu-satunya masalah sekarang: Saya harus melihat bagaimana saya dapat mengurangi tiga byte dari solusi saya sendiri untuk menjadi lebih baik daripada Perl lagi: - |
Joey
Ok, abaikan bagian dari apa yang saya katakan sebelumnya. Mengabaikan kata satu huruf memang satu byte lebih pendek daripada tidak melakukannya.
Joey
Setiap byte dihitung;) Saya mempertimbangkan untuk melakukan trik baris baru, tetapi saya pikir itu sebenarnya jumlah byte yang sama, bahkan jika itu lebih sedikit karakter yang dapat dicetak. Masih bekerja untuk melihat apakah saya dapat mengecilkannya lagi :)
Syntaera
Ah, normalisasi kasus membuat saya kembali ke 209. Saya tidak melihat apa lagi yang bisa saya potong. Meskipun PowerShell bisa lebih pendek dari Perl. ;-)
Joey
Saya tidak melihat di mana Anda membatasi output ke 22 kata teratas, atau di mana Anda memastikan bahwa kata lama tidak membungkus.
Gabe
9

F #, 452 karakter

Strightforward: dapatkan urutan apasangan jumlah kata, temukan pengganda jumlah kata per kolom yang terbaik k, kemudian hasil cetak.

let a=
 stdin.ReadToEnd().Split(" .?!,\":;'\r\n".ToCharArray(),enum 1)
 |>Seq.map(fun s->s.ToLower())|>Seq.countBy id
 |>Seq.filter(fun(w,n)->not(set["the";"and";"of";"to";"a";"i";"it";"in";"or";"is"].Contains w))
 |>Seq.sortBy(fun(w,n)-> -n)|>Seq.take 22
let k=a|>Seq.map(fun(w,n)->float(78-w.Length)/float n)|>Seq.min
let u n=String.replicate(int(float(n)*k)-2)"_"
printfn" %s "(u(snd(Seq.nth 0 a)))
for(w,n)in a do printfn"|%s| %s "(u n)w

Contoh (Saya memiliki jumlah freq berbeda dari Anda, tidak yakin mengapa):

% app.exe < Alice.txt

 _________________________________________________________________________
|_________________________________________________________________________| she
|_______________________________________________________________| you
|_____________________________________________________________| said
|_____________________________________________________| alice
|_______________________________________________| was
|___________________________________________| that
|___________________________________| as
|________________________________| her
|_____________________________| with
|_____________________________| at
|____________________________| t
|____________________________| s
|__________________________| on
|_________________________| all
|_______________________| this
|______________________| had
|______________________| for
|_____________________| but
|_____________________| be
|____________________| not
|___________________| they
|__________________| so
Brian
sumber
ternyata solusi saya sendiri memang sedikit tidak aktif (karena spec yang sedikit berbeda), solusinya sesuai sekarang ;-)
ChristopheD
+1 untuk satu-satunya implementasi penskalaan batang yang benar sejauh ini
Rotsor
2
(@Rotsor: Ironic, mengingat milik saya adalah solusi tertua.)
Brian
Saya yakin Anda bisa mempersingkat sedikit dengan menggabungkan tahap pemisahan, peta, dan filter. Saya juga berharap Anda tidak akan membutuhkan begitu banyak float.
Gabe
Bukankah fungsi bersarang biasanya lebih pendek daripada menggunakan operator pipa |>?
Joey
8

Python 2.6, 347 karakter

import re
W,x={},"a and i in is it of or the to".split()
[W.__setitem__(w,W.get(w,0)-1)for w in re.findall("[a-z]+",file("11.txt").read().lower())if w not in x]
W=sorted(W.items(),key=lambda p:p[1])[:22]
bm=(76.-len(W[0][0]))/W[0][1]
U=lambda n:"_"*int(n*bm)
print "".join(("%s\n|%s| %s "%((""if i else" "+U(n)),U(n),w))for i,(w,n)in enumerate(W))

Keluaran:

 _________________________________________________________________________
|_________________________________________________________________________| she 
|_______________________________________________________________| you 
|____________________________________________________________| said 
|_____________________________________________________| alice 
|_______________________________________________| was 
|___________________________________________| that 
|____________________________________| as 
|________________________________| her 
|_____________________________| with 
|_____________________________| at 
|____________________________| s 
|____________________________| t 
|__________________________| on 
|__________________________| all 
|_______________________| this 
|_______________________| for 
|_______________________| had 
|_______________________| but 
|______________________| be 
|_____________________| not 
|____________________| they 
|____________________| so 
AKX
sumber
1
Anda dapat kehilangan garis bm=(76.-len(W[0][0]))/W[0][1]karena Anda hanya menggunakan bm sekali (buat baris berikutnya U=lambda n:"_"*int(n*(76.-len(W[0][0]))/W[0][1]), kurangi 5 karakter. Juga: mengapa Anda menggunakan nama variabel 2 karakter dalam kode golf? ;-)
ChristopheD
Pada baris terakhir, spasi setelah cetak tidak diperlukan, menghilangkan satu karakter
ChristopheD
1
Tidak mempertimbangkan kasus ketika kata yang paling sering kedua sangat panjang, bukan?
Joey
@ChristopheD: Karena saya sudah terlalu lama menatap kode itu. : P Tangkapan bagus. @ Johnannes: Itu bisa diperbaiki juga, ya. Tidak yakin semua implementasi lain melakukannya ketika saya menulis ini juga.
AKX
7

* sh (+ curl), solusi parsial

Ini tidak lengkap, tapi untuk itu, inilah separuh kata yang menghitung frekuensi dari masalah dalam 192 byte:

curl -s http://www.gutenberg.org/files/11/11.txt|sed -e 's@[^a-z]@\n@gi'|tr '[:upper:]' '[:lower:]'|egrep -v '(^[^a-z]*$|\b(the|and|of|to|a|i|it|in|or|is)\b)' |sort|uniq -c|sort -n|tail -n 22
Frank Farmer
sumber
7

Gawk - 336 (awalnya 507) karakter

(Setelah memperbaiki format output; Memperbaiki hal kontraksi; tweaking; tweaking lagi; menghapus langkah penyortiran yang sama sekali tidak perlu; tweak lagi; dan lagi (oops yang satu ini memecah format); tweak lagi; mengambil tantangan Matt Saya mati-matian men-tweak jadi lebih banyak; temukan tempat lain untuk menyimpan beberapa, tetapi berikan dua kembali untuk memperbaiki bug panjang batang)

Heh heh! Saya sesaat di depan tantangan penghitung solusi [Matt's JavaScript] [1] ! ;) dan [python AKX] [2].

Masalahnya tampaknya memanggil bahasa yang mengimplementasikan array asosiatif asli, jadi tentu saja saya telah memilih satu dengan satu set operator yang sangat buruk pada mereka. Secara khusus, Anda tidak dapat mengontrol urutan awk yang menawarkan unsur-unsur peta hash, jadi saya berulang kali memindai seluruh peta untuk menemukan item yang paling banyak saat ini, mencetaknya dan menghapusnya dari array.

Itu semua sangat tidak efisien, dengan semua golf yang saya buat sudah cukup mengerikan juga.

Diperkecil:

{gsub("[^a-zA-Z]"," ");for(;NF;NF--)a[tolower($NF)]++}
END{split("the and of to a i it in or is",b," ");
for(w in b)delete a[b[w]];d=1;for(w in a){e=a[w]/(78-length(w));if(e>d)d=e}
for(i=22;i;--i){e=0;for(w in a)if(a[w]>e)e=a[x=w];l=a[x]/d-2;
t=sprintf(sprintf("%%%dc",l)," ");gsub(" ","_",t);if(i==22)print" "t;
print"|"t"| "x;delete a[x]}}

jeda baris hanya untuk kejelasan: mereka tidak perlu dan tidak boleh dihitung.


Keluaran:

$ gawk -f wordfreq.awk.min < 11.txt 
 _________________________________________________________________________
|_________________________________________________________________________| she
|_______________________________________________________________| you
|____________________________________________________________| said
|____________________________________________________| alice
|______________________________________________| was
|__________________________________________| that
|___________________________________| as
|_______________________________| her
|____________________________| with
|____________________________| at
|___________________________| s
|___________________________| t
|_________________________| on
|_________________________| all
|______________________| this
|______________________| for
|______________________| had
|_____________________| but
|____________________| be
|____________________| not
|___________________| they
|__________________| so
$ sed 's/you/superlongstring/gI' 11.txt | gawk -f wordfreq.awk.min
 ______________________________________________________________________
|______________________________________________________________________| she
|_____________________________________________________________| superlongstring
|__________________________________________________________| said
|__________________________________________________| alice
|____________________________________________| was
|_________________________________________| that
|_________________________________| as
|______________________________| her
|___________________________| with
|___________________________| at
|__________________________| s
|__________________________| t
|________________________| on
|________________________| all
|_____________________| this
|_____________________| for
|_____________________| had
|____________________| but
|___________________| be
|___________________| not
|__________________| they
|_________________| so

Dapat dibaca; 633 karakter (aslinya 949):

{
    gsub("[^a-zA-Z]"," ");
    for(;NF;NF--)
    a[tolower($NF)]++
}
END{
    # remove "short" words
    split("the and of to a i it in or is",b," ");
    for (w in b) 
    delete a[b[w]];
    # Find the bar ratio
    d=1;
    for (w in a) {
    e=a[w]/(78-length(w));
    if (e>d)
        d=e
    }
    # Print the entries highest count first
    for (i=22; i; --i){               
    # find the highest count
    e=0;
    for (w in a) 
        if (a[w]>e)
        e=a[x=w];
        # Print the bar
    l=a[x]/d-2;
    # make a string of "_" the right length
    t=sprintf(sprintf("%%%dc",l)," ");
    gsub(" ","_",t);
    if (i==22) print" "t;
    print"|"t"| "x;
    delete a[x]
    }
}
dmckee
sumber
Kerja bagus, bagus Anda memasukkan versi indentasi / komentar ;-)
ChristopheD
7

LISP umum, 670 karakter

Saya seorang pemula LISP, dan ini merupakan upaya menggunakan tabel hash untuk menghitung (jadi mungkin bukan metode yang paling kompak).

(flet((r()(let((x(read-char t nil)))(and x(char-downcase x)))))(do((c(
make-hash-table :test 'equal))(w NIL)(x(r)(r))y)((not x)(maphash(lambda
(k v)(if(not(find k '("""the""and""of""to""a""i""it""in""or""is"):test
'equal))(push(cons k v)y)))c)(setf y(sort y #'> :key #'cdr))(setf y
(subseq y 0(min(length y)22)))(let((f(apply #'min(mapcar(lambda(x)(/(-
76.0(length(car x)))(cdr x)))y))))(flet((o(n)(dotimes(i(floor(* n f)))
(write-char #\_))))(write-char #\Space)(o(cdar y))(write-char #\Newline)
(dolist(x y)(write-char #\|)(o(cdr x))(format t "| ~a~%"(car x))))))
(cond((char<= #\a x #\z)(push x w))(t(incf(gethash(concatenate 'string(
reverse w))c 0))(setf w nil)))))

dapat dijalankan misalnya dengan cat alice.txt | clisp -C golf.lisp.

Dalam bentuk yang mudah dibaca adalah

(flet ((r () (let ((x (read-char t nil)))
               (and x (char-downcase x)))))
  (do ((c (make-hash-table :test 'equal))  ; the word count map
       w y                                 ; current word and final word list
       (x (r) (r)))  ; iteration over all chars
       ((not x)

        ; make a list with (word . count) pairs removing stopwords
        (maphash (lambda (k v)
                   (if (not (find k '("" "the" "and" "of" "to"
                                      "a" "i" "it" "in" "or" "is")
                                  :test 'equal))
                       (push (cons k v) y)))
                 c)

        ; sort and truncate the list
        (setf y (sort y #'> :key #'cdr))
        (setf y (subseq y 0 (min (length y) 22)))

        ; find the scaling factor
        (let ((f (apply #'min
                        (mapcar (lambda (x) (/ (- 76.0 (length (car x)))
                                               (cdr x)))
                                y))))
          ; output
          (flet ((outx (n) (dotimes (i (floor (* n f))) (write-char #\_))))
             (write-char #\Space)
             (outx (cdar y))
             (write-char #\Newline)
             (dolist (x y)
               (write-char #\|)
               (outx (cdr x))
               (format t "| ~a~%" (car x))))))

       ; add alphabetic to current word, and bump word counter
       ; on non-alphabetic
       (cond
        ((char<= #\a x #\z)
         (push x w))
        (t
         (incf (gethash (concatenate 'string (reverse w)) c 0))
         (setf w nil)))))
6502
sumber
Sudahkah Anda mencoba memasang makro pembaca kustom untuk mengurangi ukuran input?
Aaron
@ Harun sebenarnya itu tidak sepele bagi saya bahkan hanya mendapatkan ini berfungsi ... :-) untuk bagian golf yang sebenarnya saya hanya menggunakan variabel satu huruf dan itu saja. Lagi pula selain verbositas agak tinggi yang melekat dalam CL untuk skala masalah ini ("string concatenate '," setf "atau" gethash "adalah pembunuh ... dalam python mereka adalah" + "," = "," [] " ) saya masih merasa ini jauh lebih buruk yang saya harapkan bahkan pada tingkat yang logis. Dalam arti saya punya perasaan bahwa cadel adalah ok, tetapi cadel umum adalah begitu-begitu dan ini di luar penamaan (membaca kembali itu komentar yang sangat tidak adil karena pengalaman saya dengan CL hampir nol).
6502
benar. Skema akan membuat golf sedikit lebih mudah, dengan namespace tunggal. alih-alih menambahkan string ke semua tempat, Anda dapat (letrec ((menambahkan string)) (b gethash)) ... (a "x" "yz") ...)
Aaron
6

C (828)

Tampaknya banyak seperti kode yang dikaburkan, dan menggunakan glib untuk string, daftar dan hash. Char menghitung dengan wc -mmengatakan 828 . Itu tidak mempertimbangkan kata-kata char tunggal. Untuk menghitung panjang maksimum bilah, itu mempertimbangkan kata yang paling panjang mungkin di antara semua, bukan hanya 22 yang pertama. Apakah ini penyimpangan dari spesifikasi?

Itu tidak menangani kegagalan dan tidak melepaskan memori yang digunakan.

#include <glib.h>
#define S(X)g_string_##X
#define H(X)g_hash_table_##X
GHashTable*h;int m,w=0,z=0;y(const void*a,const void*b){int*A,*B;A=H(lookup)(h,a);B=H(lookup)(h,b);return*B-*A;}void p(void*d,void*u){int *v=H(lookup)(h,d);if(w<22){g_printf("|");*v=*v*(77-z)/m;while(--*v>=0)g_printf("=");g_printf("| %s\n",d);w++;}}main(c){int*v;GList*l;GString*s=S(new)(NULL);h=H(new)(g_str_hash,g_str_equal);char*n[]={"the","and","of","to","it","in","or","is"};while((c=getchar())!=-1){if(isalpha(c))S(append_c)(s,tolower(c));else{if(s->len>1){for(c=0;c<8;c++)if(!strcmp(s->str,n[c]))goto x;if((v=H(lookup)(h,s->str))!=NULL)++*v;else{z=MAX(z,s->len);v=g_malloc(sizeof(int));*v=1;H(insert)(h,g_strdup(s->str),v);}}x:S(truncate)(s,0);}}l=g_list_sort(H(get_keys)(h),y);m=*(int*)H(lookup)(h,g_list_first(l)->data);g_list_foreach(l,p,NULL);}
rev ShinTakezou
sumber
Baris baru dihitung sebagai karakter, tetapi Anda dapat menghapus garis apa pun dari yang bukan instruksi preprosesor. Untuk bermain golf, saya tidak akan menganggap tidak membebaskan memori sebagai latihan yang buruk.
Stéphan Kochen
ok ... letakkan semua dalam satu baris (harapkan makro preproc) dan diberikan vers tanpa membebaskan mem (dan dengan dua spasi lain dihapus ... sedikit perbaikan dapat dilakukan pada "kebingungan", misalnya *v=*v*(77-lw)/makan memberikan 929. .. tapi saya pikir itu bisa baik-baik saja kecuali saya menemukan cara untuk melakukannya jauh lebih pendek)
ShinTakezou
Saya pikir Anda dapat memindahkan setidaknya int cke dalam maindeklarasi dan mainsecara implisit int(seperti setiap argumen untyped, afaik): main(c){...}. Anda mungkin juga bisa menulis 0saja NULL.
Joey
melakukannya ... tentu saja akan memicu beberapa peringatan dengan -Wallatau dengan -std=c99bendera di ... tapi saya kira ini tidak ada gunanya untuk golf kode, kan?
ShinTakezou
uff, maaf untuk suntingan waktu jeda pendek, ... Saya harus mengubah Without freeing memory stuff, it reaches 866 (removed some other unuseful space)ke sesuatu yang lain untuk tidak berpikir orang-orang bahwa perbedaan dengan versi memori bebas adalah semua dalam hal itu: sekarang versi tanpa memori bebas memiliki banyak lebih banyak "perbaikan".
ShinTakezou
6

Perl, 185 char

200 (sedikit rusak) 199 197 195 195 193 187 185 karakter. Dua baris terakhir terakhir signifikan. Sesuai dengan spesifikasi.

map$X{+lc}+=!/^(.|the|and|to|i[nst]|o[rf])$/i,/[a-z]+/gfor<>;
$n=$n>($:=$X{$_}/(76-y+++c))?$n:$:for@w=(sort{$X{$b}-$X{$a}}%X)[0..21];
die map{$U='_'x($X{$_}/$n);" $U
"x!$z++,"|$U| $_
"}@w

Baris pertama memuat jumlah kata yang valid ke dalam %X.

Baris kedua menghitung faktor penskalaan minimum sehingga semua baris output akan menjadi <= 80 karakter.

Baris ketiga (berisi dua karakter baris baru) menghasilkan output.

mob
sumber
Ini tidak akan menghapus kata berhenti dari string seperti "foo_the_bar". Panjang garis juga satu terlalu panjang (baca ulang spek: "bilah + spasi + kata + spasi <= 80 karakter")
Joey
5

Java - 886 865 756 744 742 744 752 742 714 680 karakter

  • Pembaruan sebelum 742 pertama : regex ditingkatkan, dihapus tipe parameter berlebihan, dihapus spasi berlebihan.

  • Perbarui 742> 744 karakter : perbaiki hack dengan panjang tetap Itu hanya tergantung pada kata pertama, bukan kata lain (belum). Menemukan beberapa tempat untuk mempersingkat kode ( \\sdi regex digantikan oleh dan ArrayListdigantikan oleh Vector). Saya sekarang mencari cara singkat untuk menghapus ketergantungan Commons IO dan membaca dari stdin.

  • Perbarui 744> 752 karakter : Saya menghapus ketergantungan commons. Sekarang membaca dari stdin. Rekatkan teks di stdin dan tekan Ctrl+Zuntuk mendapatkan hasil.

  • Perbarui 752> 742 karakter : Saya menghapus publicdan spasi, membuat classname 1 char bukan 2 dan sekarang mengabaikan kata satu huruf.

  • Perbarui 742> 714 karakter : Diperbarui sesuai komentar Carl: dihapus tugas yang berlebihan (742> 730), digantikan m.containsKey(k)oleh m.get(k)!=null(730> 728), memperkenalkan substring garis (728> 714).

  • Perbarui 714> 680 karakter : Diperbarui sesuai komentar Rotsor: peningkatan perhitungan ukuran bilah untuk menghapus pengecoran yang tidak perlu dan ditingkatkan split()untuk menghapus yang tidak perlu replaceAll().


import java.util.*;class F{public static void main(String[]a)throws Exception{StringBuffer b=new StringBuffer();for(int c;(c=System.in.read())>0;b.append((char)c));final Map<String,Integer>m=new HashMap();for(String w:b.toString().toLowerCase().split("(\\b(.|the|and|of|to|i[tns]|or)\\b|\\W)+"))m.put(w,m.get(w)!=null?m.get(w)+1:1);List<String>l=new Vector(m.keySet());Collections.sort(l,new Comparator(){public int compare(Object l,Object r){return m.get(r)-m.get(l);}});int c=76-l.get(0).length();String s=new String(new char[c]).replace('\0','_');System.out.println(" "+s);for(String w:l.subList(0,22))System.out.println("|"+s.substring(0,m.get(w)*c/m.get(l.get(0)))+"| "+w);}}

Versi yang lebih mudah dibaca:

import java.util.*;
class F{
 public static void main(String[]a)throws Exception{
  StringBuffer b=new StringBuffer();for(int c;(c=System.in.read())>0;b.append((char)c));
  final Map<String,Integer>m=new HashMap();for(String w:b.toString().toLowerCase().split("(\\b(.|the|and|of|to|i[tns]|or)\\b|\\W)+"))m.put(w,m.get(w)!=null?m.get(w)+1:1);
  List<String>l=new Vector(m.keySet());Collections.sort(l,new Comparator(){public int compare(Object l,Object r){return m.get(r)-m.get(l);}});
  int c=76-l.get(0).length();String s=new String(new char[c]).replace('\0','_');System.out.println(" "+s);
  for(String w:l.subList(0,22))System.out.println("|"+s.substring(0,m.get(w)*c/m.get(l.get(0)))+"| "+w);
 }
}

Keluaran:

 _________________________________________________________________________
| _________________________________________________________________________ | | dia
| _______________________________________________________________ | kamu
| ____________________________________________________________ | kata
| _____________________________________________________ | Alice
| _______________________________________________ | dulu
| ___________________________________________ | bahwa
| ____________________________________ | sebagai
| ________________________________ | -nya
| _____________________________ | dengan
| _____________________________ | di
| __________________________ | di
| __________________________ | semua
| _______________________ | ini
| _______________________ | untuk
| _______________________ | telah
| _______________________ | tapi
| ______________________ | menjadi
| _____________________ | tidak
| ____________________ | mereka
| ____________________ | begitu
| ___________________ | sangat
| __________________ | apa

Sangat menyebalkan bahwa Java tidak memiliki String#join()dan penutupan (belum).

Edit oleh Rotsor:

Saya telah membuat beberapa perubahan pada solusi Anda:

  • Daftar yang Diganti dengan String []
  • Menggunakan kembali argumen 'args' alih-alih mendeklarasikan array String saya sendiri. Juga menggunakannya sebagai argumen untuk .ToArray ()
  • StringBuffer yang diganti dengan sebuah String (ya, ya, kinerja mengerikan)
  • Pengurutan Java yang diganti dengan sort-selection dengan penghentian awal (hanya 22 elemen pertama yang harus ditemukan)
  • Menggabungkan beberapa deklarasi int menjadi satu pernyataan
  • Menerapkan algoritma non-kecurangan untuk menemukan jalur keluaran yang paling membatasi. Diimplementasikan tanpa FP.
  • Memperbaiki masalah program macet ketika ada kurang dari 22 kata yang berbeda dalam teks
  • Menerapkan algoritma baru input bacaan, yang cepat dan hanya 9 karakter lebih lama dari yang lambat.

Kode yang dikondensasi adalah 688 711 684 karakter:

import java.util.*;class F{public static void main(String[]l)throws Exception{Map<String,Integer>m=new HashMap();String w="";int i=0,k=0,j=8,x,y,g=22;for(;(j=System.in.read())>0;w+=(char)j);for(String W:w.toLowerCase().split("(\\b(.|the|and|of|to|i[tns]|or)\\b|\\W)+"))m.put(W,m.get(W)!=null?m.get(W)+1:1);l=m.keySet().toArray(l);x=l.length;if(x<g)g=x;for(;i<g;++i)for(j=i;++j<x;)if(m.get(l[i])<m.get(l[j])){w=l[i];l[i]=l[j];l[j]=w;}for(;k<g;k++){x=76-l[k].length();y=m.get(l[k]);if(k<1||y*i>x*j){i=x;j=y;}}String s=new String(new char[m.get(l[0])*i/j]).replace('\0','_');System.out.println(" "+s);for(k=0;k<g;k++){w=l[k];System.out.println("|"+s.substring(0,m.get(w)*i/j)+"| "+w);}}}

Versi cepat ( 720 693 karakter)

import java.util.*;class F{public static void main(String[]l)throws Exception{Map<String,Integer>m=new HashMap();String w="";int i=0,k=0,j=8,x,y,g=22;for(;j>0;){j=System.in.read();if(j>90)j-=32;if(j>64&j<91)w+=(char)j;else{if(!w.matches("^(|.|THE|AND|OF|TO|I[TNS]|OR)$"))m.put(w,m.get(w)!=null?m.get(w)+1:1);w="";}}l=m.keySet().toArray(l);x=l.length;if(x<g)g=x;for(;i<g;++i)for(j=i;++j<x;)if(m.get(l[i])<m.get(l[j])){w=l[i];l[i]=l[j];l[j]=w;}for(;k<g;k++){x=76-l[k].length();y=m.get(l[k]);if(k<1||y*i>x*j){i=x;j=y;}}String s=new String(new char[m.get(l[0])*i/j]).replace('\0','_');System.out.println(" "+s);for(k=0;k<g;k++){w=l[k];System.out.println("|"+s.substring(0,m.get(w)*i/j)+"| "+w);}}}

Versi yang lebih mudah dibaca:

import java.util.*;class F{public static void main(String[]l)throws Exception{
    Map<String,Integer>m=new HashMap();String w="";
    int i=0,k=0,j=8,x,y,g=22;
    for(;j>0;){j=System.in.read();if(j>90)j-=32;if(j>64&j<91)w+=(char)j;else{
        if(!w.matches("^(|.|THE|AND|OF|TO|I[TNS]|OR)$"))m.put(w,m.get(w)!=null?m.get(w)+1:1);w="";
    }}
    l=m.keySet().toArray(l);x=l.length;if(x<g)g=x;
    for(;i<g;++i)for(j=i;++j<x;)if(m.get(l[i])<m.get(l[j])){w=l[i];l[i]=l[j];l[j]=w;}
    for(;k<g;k++){x=76-l[k].length();y=m.get(l[k]);if(k<1||y*i>x*j){i=x;j=y;}}
    String s=new String(new char[m.get(l[0])*i/j]).replace('\0','_');
    System.out.println(" "+s);
    for(k=0;k<g;k++){w=l[k];System.out.println("|"+s.substring(0,m.get(w)*i/j)+"| "+w);}}
}

Versi tanpa peningkatan perilaku adalah 615 karakter:

import java.util.*;class F{public static void main(String[]l)throws Exception{Map<String,Integer>m=new HashMap();String w="";int i=0,k=0,j=8,g=22;for(;j>0;){j=System.in.read();if(j>90)j-=32;if(j>64&j<91)w+=(char)j;else{if(!w.matches("^(|.|THE|AND|OF|TO|I[TNS]|OR)$"))m.put(w,m.get(w)!=null?m.get(w)+1:1);w="";}}l=m.keySet().toArray(l);for(;i<g;++i)for(j=i;++j<l.length;)if(m.get(l[i])<m.get(l[j])){w=l[i];l[i]=l[j];l[j]=w;}i=76-l[0].length();String s=new String(new char[i]).replace('\0','_');System.out.println(" "+s);for(k=0;k<g;k++){w=l[k];System.out.println("|"+s.substring(0,m.get(w)*i/m.get(l[0]))+"| "+w);}}}
BalusC
sumber
Tidak bisakah Anda menggunakan nama yang sepenuhnya memenuhi syarat untuk IOUtilsalih-alih mengimpornya? Sejauh yang saya bisa lihat Anda hanya menggunakannya sekali saja.
Joey
5
Anda agak dicurangi dengan mengasumsikan bahwa bilah terpanjang tepatnya 75 karakter. Anda harus memastikan bahwa tidak ada bilah + kata yang lebih panjang dari 80 karakter.
Gabe
Anda kehilangan spasi setelah kata. ;)
st0le
Ketika saya sedang memotong jawaban saya , saya berharap saya akan mengalahkan pengajuan BalusC. Saya masih memiliki 200 karakter lagi, ugh! Saya bertanya-tanya berapa lama ini tanpa asumsi Commons IO & 75 char.
Jonathon Faust
1
Sepertinya Anda dapat mencukur beberapa karakter dengan membuat bString alih-alih StringBuffer. Saya tidak ingin memikirkan bagaimana performanya nanti (terutama karena Anda menambahkan satu karakter pada satu waktu).
Michael Myers
4

Scala 2.8, 311 314 320 330 332 336 341 375 karakter

termasuk penyesuaian kata yang panjang. Ide dipinjam dari solusi lain.

Sekarang sebagai skrip ( a.scala):

val t="\\w+\\b(?<!\\bthe|and|of|to|a|i[tns]?|or)".r.findAllIn(io.Source.fromFile(argv(0)).mkString.toLowerCase).toSeq.groupBy(w=>w).mapValues(_.size).toSeq.sortBy(-_._2)take 22
def b(p:Int)="_"*(p*(for((w,c)<-t)yield(76.0-w.size)/c).min).toInt
println(" "+b(t(0)._2))
for(p<-t)printf("|%s| %s \n",b(p._2),p._1)

Jalankan dengan

scala -howtorun:script a.scala alice.txt

BTW, hasil edit dari 314 hingga 311 karakter sebenarnya hanya menghapus 1 karakter. Seseorang salah menghitung sebelumnya (Windows CRs?).

mkneissl
sumber
4

Clojure 282 ketat

(let[[[_ m]:as s](->>(slurp *in*).toLowerCase(re-seq #"\w+\b(?<!\bthe|and|of|to|a|i[tns]?|or)")frequencies(sort-by val >)(take 22))[b](sort(map #(/(- 76(count(key %)))(val %))s))p #(do(print %1)(dotimes[_(* b %2)](print \_))(apply println %&))](p " " m)(doseq[[k v]s](p \| v \| k)))

Agak lebih terbaca:

(let[[[_ m]:as s](->> (slurp *in*)
                   .toLowerCase
                   (re-seq #"\w+\b(?<!\bthe|and|of|to|a|i[tns]?|or)")
                   frequencies
                   (sort-by val >)
                   (take 22))
     [b] (sort (map #(/ (- 76 (count (key %)))(val %)) s))
     p #(do
          (print %1)
          (dotimes[_(* b %2)] (print \_))
          (apply println %&))]
  (p " " m)
  (doseq[[k v] s] (p \| v \| k)))
Alex Taggart
sumber
4

Scala, 368 karakter

Pertama, versi yang dapat dibaca dalam 592 karakter:

object Alice {
  def main(args:Array[String]) {
    val s = io.Source.fromFile(args(0))
    val words = s.getLines.flatMap("(?i)\\w+\\b(?<!\\bthe|and|of|to|a|i|it|in|or|is)".r.findAllIn(_)).map(_.toLowerCase)
    val freqs = words.foldLeft(Map[String, Int]())((countmap, word)  => countmap + (word -> (countmap.getOrElse(word, 0)+1)))
    val sortedFreqs = freqs.toList.sort((a, b)  => a._2 > b._2)
    val top22 = sortedFreqs.take(22)
    val highestWord = top22.head._1
    val highestCount = top22.head._2
    val widest = 76 - highestWord.length
    println(" " + "_" * widest)
    top22.foreach(t => {
      val width = Math.round((t._2 * 1.0 / highestCount) * widest).toInt
      println("|" + "_" * width + "| " + t._1)
    })
  }
}

Output konsol terlihat seperti ini:

$ scalac alice.scala 
$ scala Alice aliceinwonderland.txt
 _________________________________________________________________________
|_________________________________________________________________________| she
|_______________________________________________________________| you
|_____________________________________________________________| said
|_____________________________________________________| alice
|_______________________________________________| was
|____________________________________________| that
|____________________________________| as
|_________________________________| her
|______________________________| at
|______________________________| with
|_____________________________| s
|_____________________________| t
|___________________________| on
|__________________________| all
|_______________________| had
|_______________________| but
|______________________| be
|______________________| not
|____________________| they
|____________________| so
|___________________| very
|___________________| what

Kami dapat melakukan beberapa pemangkasan yang agresif dan menurunkannya menjadi 415 karakter:

object A{def main(args:Array[String]){val l=io.Source.fromFile(args(0)).getLines.flatMap("(?i)\\w+\\b(?<!\\bthe|and|of|to|a|i|it|in|or|is)".r.findAllIn(_)).map(_.toLowerCase).foldLeft(Map[String, Int]())((c,w)=>c+(w->(c.getOrElse(w,0)+1))).toList.sort((a,b)=>a._2>b._2).take(22);println(" "+"_"*(76-l.head._1.length));l.foreach(t=>println("|"+"_"*Math.round((t._2*1.0/l.head._2)*(76-l.head._1.length)).toInt+"| "+t._1))}}

Sesi konsol terlihat seperti ini:

$ scalac a.scala 
$ scala A aliceinwonderland.txt
 _________________________________________________________________________
|_________________________________________________________________________| she
|_______________________________________________________________| you
|_____________________________________________________________| said
|_____________________________________________________| alice
|_______________________________________________| was
|____________________________________________| that
|____________________________________| as
|_________________________________| her
|______________________________| at
|______________________________| with
|_____________________________| s
|_____________________________| t
|___________________________| on
|__________________________| all
|_______________________| had
|_______________________| but
|______________________| be
|______________________| not
|____________________| they
|____________________| so
|___________________| very
|___________________| what

Saya yakin seorang ahli Scala bisa melakukan lebih baik.

Pembaruan: Dalam komentar, Thomas memberikan versi yang lebih pendek, yaitu 368 karakter:

object A{def main(a:Array[String]){val t=(Map[String, Int]()/:(for(x<-io.Source.fromFile(a(0)).getLines;y<-"(?i)\\w+\\b(?<!\\bthe|and|of|to|a|i|it|in|or|is)".r findAllIn x) yield y.toLowerCase).toList)((c,x)=>c+(x->(c.getOrElse(x,0)+1))).toList.sortBy(_._2).reverse.take(22);val w=76-t.head._1.length;print(" "+"_"*w);t map (s=>"\n|"+"_"*(s._2*w/t.head._2)+"| "+s._1) foreach print}}

Jelas, pada 375 karakter:

object Alice {
  def main(a:Array[String]) {
    val t = (Map[String, Int]() /: (
      for (
        x <- io.Source.fromFile(a(0)).getLines
        y <- "(?i)\\w+\\b(?<!\\bthe|and|of|to|a|i|it|in|or|is)".r.findAllIn(x)
      ) yield y.toLowerCase
    ).toList)((c, x) => c + (x -> (c.getOrElse(x, 0) + 1))).toList.sortBy(_._2).reverse.take(22)
    val w = 76 - t.head._1.length
    print (" "+"_"*w)
    t.map(s => "\n|" + "_" * (s._2 * w / t.head._2) + "| " + s._1).foreach(print)
  }
}
pr1001
sumber
383 karakter:object A{def main(a:Array[String]){val t=(Map[String, Int]()/:(for(x<-io.Source.fromFile(a(0)).getLines;y<-"(?i)\\w+\\b(?<!\\bthe|and|of|to|a|i|it|in|or|is)".r findAllIn x) yield y.toLowerCase).toList)((c,x)=>c+(x->(c.getOrElse(x,0)+1))).toList.sortBy(_._2).reverse.take(22);val w=76-t.head._1.length;print(" "+"_"*w);t map (s=>"\n|"+"_"*(s._2*w/t.head._2)+"| "+s._1) foreach print}}
Thomas Jung
Tentu saja, yang paling berguna untuk pemahaman! Bagus!
pr1001
3

Java - 896 karakter

931 karakter

1233 karakter yang dibuat tidak dapat dibaca

Karakter 1977 "tidak terkompresi"


Pembaruan: Saya telah secara agresif mengurangi jumlah karakter. Hapus kata satu huruf per spec yang diperbarui.

Saya sangat iri pada C # dan LINQ.

import java.util.*;import java.io.*;import static java.util.regex.Pattern.*;class g{public static void main(String[] a)throws Exception{PrintStream o=System.out;Map<String,Integer> w=new HashMap();Scanner s=new Scanner(new File(a[0])).useDelimiter(compile("[^a-z]+|\\b(the|and|of|to|.|it|in|or|is)\\b",2));while(s.hasNext()){String z=s.next().trim().toLowerCase();if(z.equals(""))continue;w.put(z,(w.get(z)==null?0:w.get(z))+1);}List<Integer> v=new Vector(w.values());Collections.sort(v);List<String> q=new Vector();int i,m;i=m=v.size()-1;while(q.size()<22){for(String t:w.keySet())if(!q.contains(t)&&w.get(t).equals(v.get(i)))q.add(t);i--;}int r=80-q.get(0).length()-4;String l=String.format("%1$0"+r+"d",0).replace("0","_");o.println(" "+l);o.println("|"+l+"| "+q.get(0)+" ");for(i=m-1;i>m-22;i--){o.println("|"+l.substring(0,(int)Math.round(r*(v.get(i)*1.0)/v.get(m)))+"| "+q.get(m-i)+" ");}}}

"Dapat dibaca":

import java.util.*;
import java.io.*;
import static java.util.regex.Pattern.*;
class g
{
   public static void main(String[] a)throws Exception
      {
      PrintStream o = System.out;
      Map<String,Integer> w = new HashMap();
      Scanner s = new Scanner(new File(a[0]))
         .useDelimiter(compile("[^a-z]+|\\b(the|and|of|to|.|it|in|or|is)\\b",2));
      while(s.hasNext())
      {
         String z = s.next().trim().toLowerCase();
         if(z.equals(""))
            continue;
         w.put(z,(w.get(z) == null?0:w.get(z))+1);
      }
      List<Integer> v = new Vector(w.values());
      Collections.sort(v);
      List<String> q = new Vector();
      int i,m;
      i = m = v.size()-1;
      while(q.size()<22)
      {
         for(String t:w.keySet())
            if(!q.contains(t)&&w.get(t).equals(v.get(i)))
               q.add(t);
         i--;
      }
      int r = 80-q.get(0).length()-4;
      String l = String.format("%1$0"+r+"d",0).replace("0","_");
      o.println(" "+l);
      o.println("|"+l+"| "+q.get(0)+" ");
      for(i = m-1; i > m-22; i--)
      {
         o.println("|"+l.substring(0,(int)Math.round(r*(v.get(i)*1.0)/v.get(m)))+"| "+q.get(m-i)+" ");
      }
   }
}

Output dari Alice:

 _________________________________________________________________________
|_________________________________________________________________________| she
|_______________________________________________________________| you
|_____________________________________________________________| said
|_____________________________________________________| alice
|_______________________________________________| was
|____________________________________________| that
|____________________________________| as
|_________________________________| her
|______________________________| with
|______________________________| at
|___________________________| on
|__________________________| all
|________________________| this
|________________________| for
|_______________________| had
|_______________________| but
|______________________| be
|______________________| not
|____________________| they
|____________________| so
|___________________| very
|___________________| what

Output dari Don Quixote (juga dari Gutenberg):

 ________________________________________________________________________
|________________________________________________________________________| that
|________________________________________________________| he
|______________________________________________| for
|__________________________________________| his
|________________________________________| as
|__________________________________| with
|_________________________________| not
|_________________________________| was
|________________________________| him
|______________________________| be
|___________________________| don
|_________________________| my
|_________________________| this
|_________________________| all
|_________________________| they
|________________________| said
|_______________________| have
|_______________________| me
|______________________| on
|______________________| so
|_____________________| you
|_____________________| quixote
Jonathon
sumber
8
Secara keseluruhan, apakah benar-benar tidak ada cara untuk membuatnya lebih pendek di Jawa? Saya harap kalian dibayar dengan jumlah karakter dan bukan dengan fungsionalitas :-)
Nas Banov