Belirli bir metinde en sık kullanılan kelimelerin ASCII grafiğini oluşturma [kapalı]


156

Meydan okuma:

Belirli bir metinde en sık kullanılan kelimelerin ASCII grafiğini oluşturun.

Kurallar:

  • Yalnızca bir sözcüğün parçası olarak a-zve A-Z(alfabetik karakterler) kabul edin .
  • Muhafazayı yoksay ( amacımız için She== she).
  • Aşağıdaki kelimeleri görmezden gelin (oldukça arbitary, biliyorum): the, and, of, to, a, i, it, in, or, is
  • Açıklama: dikkate alındığında don't: bu, aralıklarda 2 farklı 'kelime' olarak alınır a-zve A-Z: ( donve t).

  • İsteğe bağlı olarak (çok geç resmen şimdi özelliklere değişiyor gibi) Eğer olabilir (bu potansiyel çok liste görmezden kısalmasıyla için yapabiliriz) tüm tek-Mektubun 'sözlerini' düşmesi seçin.

Belirli bir öğeyi ayrıştırın text(komut satırı bağımsız değişkenleri ile belirtilen veya içerilen bir dosyayı okuyun; varsayalım us-ascii) ve bize word frequency chartaşağıdaki özelliklere sahip bir a derleyin :

  • En sık kullanılan 22 kelime (azalan sıklığa göre sıralanmıştır) için grafiği görüntüleyin (aşağıdaki örneğe de bakın).
  • Çubuk width, sözcüğün gerçekleşme sayısını (sıklığını) (orantılı olarak) gösterir. Bir boşluk ekleyin ve kelimeyi yazdırın.
  • Bu çubukların (artı boşluk-kelime-boşluk) her zaman uygun olduğundan emin olun : bar+ [space]+ word+ [space]her zaman <= 80karakter olmalıdır (olası farklı çubuk ve kelime uzunluklarını hesaba kattığınızdan emin olun: örneğin: ikinci en yaygın kelime çok daha uzun olabilir. ilk olarak frekansta çok fazla farklılık göstermez). Bu sınırlamalar dahilinde çubuk genişliğini en üst düzeye çıkarın ve çubukları uygun şekilde ölçeklendirin (temsil ettikleri frekanslara göre).

Bir örnek:

Örneğin metni burada bulunabilir ( Alice Harikalar Diyarındaki Maceraları, Lewis Carroll tarafından ).

Bu özel metin aşağıdaki çizelgeyi verir:

 _________________________________________________________________________
| _________________________________________________________________________ | o
| _______________________________________________________________ | sen
| ____________________________________________________________ | dedim
| ____________________________________________________ | alice
| ______________________________________________ | oldu
| __________________________________________ | o
| ___________________________________ | gibi
| _______________________________ | ona
| ____________________________ | ile
| ____________________________ | en
| ___________________________ | s
| ___________________________ | t
| _________________________ | üzerinde
| _________________________ | herşey
| ______________________ | bu
| ______________________ | için
| ______________________ | vardı
| _____________________ | fakat
| ____________________ | olmak
| ____________________ | değil
| ___________________ | onlar
| __________________ | yani


Bilginiz için: bunlar yukarıdaki grafiğin üzerine kurulu frekanslardır:

[('o', 553), ('sen', 481), ('dedi', 462), ('alice', 403), ('oldu', 358), ('bu
', 330), (' as ', 274), (' her ', 248), (' ile ', 227), (' at ', 227), (' s ', 219), (' t '
, 218), ('açık', 204), ('hepsi', 200), ('bu', 181), ('için', 179), ('vardı', 178), ('
ancak ', 175), (' be ', 167), (' not ', 166), (' onlar ', 155), (' so ', 152)]

İkinci bir örnek (tam spesifikasyonu uygulayıp uygulamadığınızı kontrol etmek için):you Bağlantılı Alice Harikalar Diyarında dosyasındaki her oluşumunu aşağıdaki ile değiştirin superlongstringstring:

 ________________________________________________________________
| ________________________________________________________________ | o
| _______________________________________________________ | superlongstringstring
| _____________________________________________________ | dedim
| ______________________________________________ | alice
| ________________________________________ | oldu
| _____________________________________ | o
| ______________________________ | gibi
| ___________________________ | ona
| _________________________ | ile
| _________________________ | en
| ________________________ | s
| ________________________ | t
| ______________________ | üzerinde
| _____________________ | herşey
| ___________________ | bu
| ___________________ | için
| ___________________ | vardı
| __________________ | fakat
| _________________ | olmak
| _________________ | değil
| ________________ | onlar
| ________________ | yani

Kazanan:

En kısa çözüm (karakter sayısına göre, dil başına). İyi eğlenceler!


Düzenleme : Şimdiye kadar sonuçları özetleyen tablo (2012-02-15) (başlangıçta Nas Banov kullanıcısı tarafından eklenmiştir):

Dil Rahatlığı Sıkı
========= ======= ======
GolfScript 130143
Perl 185
Windows PowerShell 148199
Mathematica 199
Ruby 185 205
Unix Alet Zinciri 194228
Python 183243
Clojure 282
Scala 311
Haskell 333
Awk 336
R 298
Javascript 304354
Harika 321
Matlab 404
C # 422
Smalltalk 386
PHP 450
F # 452
TSQL 483507

Sayılar, belirli bir dildeki en kısa çözümün uzunluğunu temsil eder. "Katı", spesifikasyonu tamamen uygulayan bir çözümü ifade eder ( |____|çubukları çizer , ilk çubuğu bir ____çizgiyle kapatır, yüksek frekanslı uzun kelimelerin olasılığını açıklar vb.). "Rahat", çözüme kısalmak için bazı özgürlüklerin alındığı anlamına gelir.

Yalnızca 500 karakterden kısa çözümler dahildir. Dil listesi 'katı' çözümün uzunluğuna göre sıralanmıştır. 'Unix Toolchain', geleneksel * nix kabuğu ve bir takım araçlar (grep, tr, sort, uniq, head, perl, awk gibi) kullanan çeşitli çözümleri belirtmek için kullanılır .


4
En uzun ikinci kelime çok daha uzun bir kelime ise, 'en uzun çubuk' + kelime = 80, 80 sütun içine sığmayabilir. Sanırım 'maksimum kısıtlama' arıyorum.
Brian

1
Muhafazayı normalleştiriyor muyuz? 'O' = 'o'?
Brian

2
IMO'nun bunu hem yürütme süresi hem de bellek kullanımı açısından gerçekleştirmesi, karakter sayısından daha ilginç bir zorluk gibi görünüyor.
Frank Farmer

81
Bu benim favori kelimeleri görmek için memnunum sve ttemsil edilir.
indiv

8
@indiv, @Nas Banov - aptal çok-basit tokenizer {yapmadım, t} olarak "Etmedim" ve {o, s} olarak "diye yönettiği" :) okur
hobbs

Yanıtlar:


123

LabVIEW 51 düğüm, 5 yapı, 10 diyagram

Filin dans-dans etmesini öğretmek asla hoş değildir. Ben, ah, karakter sayısını atlayacağım.

labVIEW kodu

Sonuçlar

Program soldan sağa akar:

labVIEW kodu açıklandı


10
Buna değmez

4
LabVIEW, donanım kontrol ve ölçüm nişinde çok mutlu, ancak dize manipülasyonu için oldukça korkunç.
Joe Z

19
Gördüğüm en iyi kod golf cevabı. Kutunun dışında düşünmek için +1!
Blair Holloway

1
Bizim için öğeleri saymalıyız ... Ekrana sürüklemek zorunda kaldığınız her kutu ve widget.
dmckee --- eski moderatör yavru kedi

1
Bu grafiklerin daha büyük bir sürümüne bağlantı eklemek mümkün müdür?
Svish

42

Yakut 1.9, 185 karakter

(diğer Ruby çözümlerine dayanmaktadır)

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

Diğer çözümler gibi herhangi bir komut satırı anahtarı kullanmak yerine, dosya adını bağımsız değişken olarak iletebilirsiniz. (yani ruby1.9 wordfrequency.rb Alice.txt)

Burada karakter değişmezleri kullandığım için, bu çözüm yalnızca Ruby 1.9'da çalışır.

Düzenleme: "Okunabilirlik" için noktalı virgüllerin satır sonlarıyla değiştirildi. : P

Edit 2: Shtééf, sondaki boşluğu unuttuğumu belirtti - bunu düzeltti.

Edit 3: Sondaki boşluk tekrar kaldırıldı;)


Her kelimeden sonra sondaki boşluk eksik.
Stéphan Kochen

Vurun, bunu dikkate almayın. Görünüşe göre golf sadece güncellendi, sondaki boşluk artık gerekli. :)
Stéphan Kochen

'Superlongstringstring' için 2. veya daha sonraki bir pozisyonda yer almıyor gibi görünüyor mu? (sorun açıklamasına bakın)
Nas Banov

2
Gerçekten bakımlı görünüyor.
Zombies

39

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

Yavaş - örnek metin için 3 dakika (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*'| '@}/

Açıklama:

{           #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
}/

"Doğru" (umarım). (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*'| '@}/

Daha az yavaş - yarım dakika. (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*'| '@}/

Revizyon günlüklerinde çıktı görünür.


2
GolfScript hakkında: golfscript.com/golfscript
Assaf Lavie

2
Doğru değil, çünkü ikinci kelime gerçekten uzunsa sonraki satıra sarılır.
Gabe

5
"sıfıra böl" ... GolfScript buna izin veriyor mu?
JAB

35

206

kabuk, grep, tr, grep, sıralama, uniq, sıralama, kafa, 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, sadece yukarıda görüldü: sort -nr-> sort -nve sonra head-> tail=> 208 :)
update2: erm, elbette yukarıdaki aptalca, o zaman tersine çevrilecek. Yani, 209.
güncelleme3: hariç tutma normal ifadesini optimize etti -> 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$_"'



eğlenmek için, sadece perl sürümü (çok daha hızlı):

~ % 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

35

Transact SQL seti tabanlı çözüm (SQL Server 2005) 1063 892 873 853 827 820 783 683 647 644 630 karakter

Karakter sayısını azaltmak için bazı faydalı öneriler için Gabe'ye teşekkürler.

Not: Kaydırma çubuklarından kaçınmak için satır sonları eklenir, yalnızca son satır sonu gerekir.

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 @

Okunabilir Sürüm

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 @

Çıktı

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

Ve uzun iplerle

 _______________________________________________________________ 
|_______________________________________________________________| she
|_______________________________________________________| superlongstringstring
|____________________________________________________| said
|______________________________________________| Alice
|________________________________________| was
|_____________________________________| that
|_______________________________| as
|____________________________| her
|_________________________| at
|_________________________| with
|_______________________| on
|______________________| all
|____________________| This
|____________________| for
|____________________| had
|____________________| but
|___________________| be
|__________________| not
|_________________| they
|_________________| So
|________________| very
|________________| what

12
Sana bir +1 verdim çünkü T-SQL'de yaptın ve Team America - "Topların var. Topları severim."

Bazı alanları daha okunaklı hale getirmek için yeni satırlara dönüştürme özgürlüğünü aldım. Umarım bir şeyleri berbat etmedim. Ayrıca biraz daha küçülttüm.
Gabe

3
Bu kod bana çığlık atıyor! : O
Joey

1
Tasarruf etmenin iyi bir yolu 0.000sadece yerine 0geçip -Cyerine kullanmaktır 1.0/C. Ve FLOATiçine girmek REALde bir vuruş kaydeder. En büyük şey, ASisteğe bağlı olması gereken çok sayıda örneğiniz var gibi görünüyor .
Gabe

1
Tamam, nasıl 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

Yakut 207 213 211 210 207 203 201 200 karakter

Anurag'da rfusca'dan gelen öneriyi içeren bir gelişme. Ayrıca sıralama argümanı ve birkaç küçük golf kaldırır.

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} "}

Şu şekilde çalıştır:

ruby GolfedWordFrequencies.rb < Alice.txt

Düzenleme: 'koyar' koymak, çıktı tırnak önlemek için orada olması gerekir.
Edit2: Değişen Dosya-> IO
Edit3: kaldırıldı / i
Edit4: (f * 1.0) etrafında parantez kaldırıldı, yeniden
sayıldı Edit5: İlk satır için dize ekleme kullanın; syerinde genişletin .
Edit6: m float yapılmış, 1.0 kaldırıldı. EDIT: Çalışmıyor, uzunlukları değiştiriyor. EDIT:
Edit7: Use öncekinden daha kötü değil STDIN.read.


+1 - sıralama bölümünü seviyorum, çok zeki :)
Anurag

Hey, ilk etapta onunla karşılaştırıldığında küçük bir optimizasyon. :)
takımada

Güzel! Anurag'ın versiyonunda da yaptığım değişikliklerden ikisi eklendi. Shaves off another 4.
Stéphan Kochen

Çözüm orijinal çıktıdan saptı, denedim ve bunun nerede olduğunu anlayacağım.
archgoon

1
Bunun daha kısa bir çeşidi daha var.
archgoon

28

Mathematica ( 297 284 Derslikler 248 244 242 199 karakter) Fonksiyonel Saf

ve Zipf Yasası Testi

Bak anne ... çeşit yok, el yok, .. kafa yok

Düzenle 1> bazı kısayollar tanımlandı (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]

Bazı açıklamalar

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)

Çıktı

alternatif metin http://i49.tinypic.com/2n8mrer.jpg

Mathematica golf oynamak için pek uygun değildir ve bu sadece uzun, açıklayıcı işlev isimleri yüzünden olur. "RegularExpression []" veya "StringSplit []" gibi işlevler beni hıçkırtıyor :(.

Zipf Yasası Testi

Zipf yasası bir doğal dil metin için, tahmin Günlüğü (Sıralama) vs Günlüğü (oluşum) Plot bir takip doğrusal bir ilişki.

Yasa, kriptografi ve veri sıkıştırma için algoritmalar geliştirmede kullanılır. (Ama LZW algoritmasındaki "Z" DEĞİLDİR).

Metnimizde, aşağıdakileri test edebiliriz

 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]

Sonuç (oldukça iyi doğrusal)

alternatif metin http://i46.tinypic.com/33fcmdk.jpg

Düzen 6> (242 Karakter)

Normal İfade Yeniden Düzenleme (artık Seçim işlevi yok)
1 karakter kelimesini bırakma
"f" işlevi için daha verimli tanım

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]

7 → 199 karakteri düzenle

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]
  • Değiştirilen file Transposeve Slot( #1/ #2) bağımsız değişkenler.
  • Sızdırmaz köşebentlere ihtiyacımız yok ( mümkün f@xolan f[x]yerlerde kullanmak )


9
"RegularExpression" kötü mü düşünüyorsunuz? Objective-C kodu: "stringWithContentsOfFile", "enumerateSubstringsInRange", "NSStringEnumerationByWords", "sortArrayUsingComparator" ve benzeri .
Gabe

2
@Gabe Teşekkürler ... Kendimi daha iyi hissediyorum. İspanyolca "mal de muchos, consuelo de tontos" diyoruz .. "Çok sıkıntılı, aptallar rahatladı" gibi bir şey: D
Dr. belisarius

1
|i|Zaten sahip çünkü regex gereksiz .|.
Gabe

1
İspanyolca söylemeyi seviyorum. İngilizce düşünebildiğim en yakın şey "sefalet aşk şirketi" dir. İşte benim çeviri girişimim: "Acı çektiğinde, aynı durumda başkalarını düşünmek için teselli eden bir aptal." Mathematica uygulaması üzerinde inanılmaz çalışma, btw.
dreeves

@dreeves Aptallık dil engelini kolayca aşar ... Seni küçük Mathematica programım gibi gördüğüme sevindim, sadece dili öğrenmeye
başladım

26

C # - 510 451 436 446 434 426 422 karakter (küçültülmüş)

O kadar kısa değil, ama şimdi muhtemelen doğru! Önceki sürüm, çubukların ilk satırını göstermedi, çubukları doğru bir şekilde ölçeklemedi, dosyayı stdin'den almak yerine indirdi ve gerekli tüm C # ayrıntı düzeyini içermedi. C # çok fazla bok gerekmiyorsa kolayca birçok vuruş tıraş olabilir. Belki Powershell daha iyisini yapabilirdi.

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));
    }
}

Aşağıdaki biçimde (belirli alanlar için kullanılan satırlar) lendivisör ile 422 karakter (22 kat daha yavaş yapar):

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));}}

Satır içi dosyayı indirmek için akıllı göt için +1. :)
sarnold

1
Matt'in cevabından kısa URL'yi çal.
indiv

2
Spesifikasyon, dosyanın içeri aktarılması veya bir argüman olarak iletilmesi gerektiğini söyledi. Arg [0] öğesinin yerel dosya adını içerdiğini varsayarsanız, (yeni WebClient ()) yerine args [0] kullanarak önemli ölçüde kısaltabilirsiniz. DownloadString (@ " gutenberg.org/files/11/11. txt " ) -> size yaklaşık 70 karakter kazandırır
thorkia

1
Burada WebClient çağrısını args 0 ile değiştiren bir sürüm, StreamReader çağrısı ve fazladan birkaç boşluk kaldırma. Toplam karakter sayısı = 413 var a = Regex.Replace ((yeni StreamReader (args [0])). ReadToEnd (), "[^ a-zA-Z]", "") .ToLower (). Split ('' ) .Where (x =>! (yeni [] { "" "ve" "in", "to", "a", "i", "o", "in" "ya da"," bir "}). içerir (x)). GroupBy (x => x) .Select (g => yeni {w = g.Key, c = g.Count ()}). OrderByDescending (x => xc). Atla (1) .Take (22) .ToList (); var m = a.OrderByDescending (x => xc) .First (); a.ForEach (x => Console.WriteLine ("|" + yeni Dize (' _ ', xc * (80-mw Uzunluk-4) / mc) + "|" + xw));
thorkia

"Yeni" olmadan "yeni StreamReader" kirli. File.ReadAllText (args [0]) veya Console.In.ReadToEnd () çok daha iyi. İkinci durumda, argümanınızı Main () öğenizden bile kaldırabilirsiniz. :)
Rotsor

25

Perl, 237 229 209 karakter

(Yerine daha kirli golf hileler ile Yakut sürümünü yenmek için tekrar Güncelleme split/[^a-z/,lcile lc=~/[a-z]+/gve başka bir yerde boş bir dize için bir çek ortadan kaldırarak. Yakut sürümü esinlenmiş Bunlar, kredi böylece kredi vadesi nerede.)

Güncelleme: şimdi Perl 5.10 ile! Değiştir printile sayve kullanımı ~~bir önlemek için map. Bu komut satırında olarak çağrılmalıdır perl -E '<one-liner>' alice.txt. Komut dosyasının tamamı tek bir satırda olduğundan, tek satırlık olarak yazmak herhangi bir zorluk yaratmamalıdır :).

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

Bu sürümün durum için normalleştiğini unutmayın. Bu, çözümü kısaltmaz, çünkü çıkarma ,lc(daha düşük kasa için) A-Zbölünmüş normal ifadeye eklemenizi gerektirir , bu yüzden bir yıkamadır.

Bir satırsonunun iki değil, bir karakter olduğu bir sistemdeyseniz, yerine gerçek bir satırsonu kullanarak bunu iki karakterle kısaltabilirsiniz \n. Ancak, yukarıdaki örneği bu şekilde yazmadım, çünkü bu "daha net" (ha!) Bu şekilde.


İşte çoğunlukla doğru, ancak yeterince kısa olmayan bir perl çözümü:

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

Aşağıdakiler nispeten okunabilir kalırken alabilecekleri kadar kısadır. (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;

Şu anda birkaç hata var; sabitleme ve kısaltma.
JSB ձոգչ

4
İkinci kelimenin birinciden çok daha uzun olduğu durumlar bu değil, değil mi?
Joey

1
Her iki foreachs de s olarak yazılabilir for. 8 karakter aşağı. Sonra 4 daha aşağı gitmek grep{!($_~~@s)}map{lc=~/[a-z]+/g}<>için yazılabilir inanıyorum var grep{!(/$_/i~~@s)}<>=~/[a-z]+/g. Değiştir " "ile $"... ve daha 1 aşağı konum
Zeyd

sort{$c{$b}-$c{$a}}...iki tasarruf daha. Ayrıca, sadece geçebilir %cyerine keys %cgöre sortişlev ve daha dört tasarruf.
mafya

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]

(Son satır sonu gerekli değildir, ancak okunabilirlik için buraya dahil edilmiştir.)

(Şu anki kod ve test dosyalarım SVN veri havuzumda mevcut . Umarım test vakalarım en yaygın hataları yakalar (çubuk uzunluğu, normal ifade eşleştirmeyle ilgili sorunlar ve birkaç diğerleri)

Varsayımlar:

  • Giriş olarak ABD ASCII. Muhtemelen Unicode ile garipleşiyor.
  • Metinde en az iki kesintisiz kelime

Tarih

Rahat versiyon (137), çünkü görünüşe göre ayrı ayrı sayılıyor:

($x=$input-split'\P{L}'-notmatch'^(the|and|of|to|.?|i[tns]|or)$'|group|sort *)[-1..-22]|%{"|$('_'*(76*$_.Count/$x[-1].Count))| "+$_.Name}
  • ilk çubuğu kapatmaz
  • ilk olmayan kelimenin kelime uzunluğunu hesaba katmaz

Bir karakterin çubuk uzunluklarının diğer çözümlere kıyasla varyasyonları, kayan nokta sayılarını tamsayılara dönüştürürken kesme yerine yuvarlama kullanan PowerShell'den kaynaklanmaktadır. Görev sadece orantılı çubuk uzunluğu gerektirdiğinden, bu iyi olmalıdır.

Diğer çözümlerle karşılaştırıldığında, sadece denemek ve hiçbir satırın 80 karakterden daha uzun olmadığı en uzun çubuğu almak suretiyle en uzun çubuk uzunluğunu belirlemede biraz farklı bir yaklaşım izledim.

Açıklanan daha eski bir sürümü burada bulabilirsiniz .


Etkileyici, Powershell golf için uygun bir ortam gibi görünüyor. Bar uzunluğu göz önünde bulundurarak yaklaşım tam olarak ne tarif etmeye çalıştım (çok parlak değil, itiraf) spec.
ChristopheD

1
@ChristopheD: Deneyimlerime göre (Anarchy Golf, bazı Project Euler görevleri ve sadece eğlenmek için biraz daha fazla görev), PowerShell genellikle Ruby'den biraz daha kötüdür ve genellikle Perl ve Python ile bağlanır veya daha iyidir. Yine de GolfScript ile eşleşmiyor. Ama görebildiğim kadarıyla, bu bar uzunluklarını doğru bir şekilde açıklayan en kısa çözüm olabilir ;-)
Joey

Görünüşe göre haklıydım. Powershell daha iyisini yapabilir - çok daha iyi! Lütfen yorumlarla birlikte genişletilmiş bir sürüm sağlayın.
Gabe

Johannes: Denedin mi -split("\b(?:the|and|of|to|a|i[tns]?|or)\b|[^a-z]")? Benim için çalışıyor.
Gabe

Çıktı dizesini enterpole etmeyi unutmayın: "|$('_'*($w*$_.count/$x[0].count))| $($_.name) "(veya bir tür otomatik olduğu için son alanı ortadan kaldırın). Ve -split("(?:\b(?:the|and|of|to|a|i[tns]?|or)\b|[^a-z])+")boşlukları dahil etmeden (veya kullan [-2..-23]) birkaç tasarruf etmek için kullanabilirsiniz .
Gabe

19

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

güncelleme 1: Yaşasın ! Bu bir kravat JS Bangs ' çözümü . Daha fazla kısmak için bir yol düşünemiyorum :)

güncelleme 2: Kirli bir golf hile oynadı. 1 karakteri kaydetmek eachiçin değiştirildi map:)

Güncelleme 3: Değiştirildi File.readiçin IO.read+2. Array.group_byçok verimli değildi, reduce+6 olarak değiştirildi . downcaseRegex +1 ile alt kasadan sonra büyük / küçük harfe duyarlı olmayan kontrol gerekmez . Azalan düzende sıralama +6 değeri reddedilerek kolayca yapılabilir. Toplam tasarruf +15

güncelleme 4: +3 [0]yerine .first. (@ Shtééf)

güncelleme 5: lYerinde değişkeni genişletin , +1. Değişkeyi syerinde genişletin , +2. (@ Shtééf)

6 güncellemesi: İlk satır için enterpolasyon yerine dize eklemeyi kullanın, +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} "}

güncelleme 7: Döngü içindeki ilk yinelemeyi algılamak için örnek değişkenleri kullanarak bir sürü çemberden geçtim . Elimde olan tek şey +1, ama belki de potansiyel var. Önceki sürümü koruyarak, bunun kara büyü olduğuna inanıyorum. (@ 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} "}

Okunabilir versiyon

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

Kullanmak:

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

Çıktı:

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

3
"P", "koyar" için bir kısayol değil mi? Bu birkaç tıraş olabilir.
rfusca

1
Güzel. scanBununla birlikte, kullanımınız bana daha iyi bir fikir verdi, bu yüzden tekrar ilerledim :).
JSB ձոգչ

2
Çubukları, en uzun kelime artı çubuğu 80 karaktere sığacak şekilde ölçeklendirmeniz gerekir. Brian'ın önerdiği gibi, uzun bir ikinci kelime programınızı kıracak.
Gabe

3
Bunun neden hala oy topladığını merak ediyorum. Çözüm yanlış (genel durumda) ve şu ana kadar iki yönlü daha kısa Ruby çözümleri burada.
Joey

1
Şimdi, yanılıyorsam düzelt ama "küçük harf" kullanmak yerine, neden 6-7 bayt tasarruf REGEXP büyük / küçük harf duyarsız bayrak kullanmıyorsun, değil mi?
st0le

19

Python 2.x, enlem yaklaşımı = 227183 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

Uygulamada özgürlüğe izin vermek için, dışlama ( the, and, of, to, a, i, it, in, or, is) için istenen tüm kelimeleri içeren bir dize birleşimi oluşturdum - ayrıca iki rezil "kelimeyi" sve törneği hariç tutuyor - ve dışlama için ücretsiz olarak attım an, for, he. Bu kelimelerin bütün birleşimlerini Alice, Kral James'in İncil'i ve Jargon dosyasındaki kelimelerin cesedine karşı dizede yanlış hariç tutulacak herhangi bir kelime olup olmadığını görmek için denedim. Ve iki dışlama dizesiyle böyle bitirdim: itheandtoforinisve andithetoforinis.

PS. kodu kısaltmak için diğer çözümlerden ödünç alındı.

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

farfaralık

Göz ardı edilecek kelimelerle ilgili olarak, bunların İngilizce'de en çok kullanılan kelimeler listesinden alınacağı düşünülebilir. Bu liste kullanılan metin grubuna bağlıdır . En popüler listelerden biri başına ( http://en.wikipedia.org/wiki/Most_common_words_in_İngilizce , http://www.english-for-students.com/Frequent-Used-Words.html , http: // www. sporcle.com/games/common_english_words.php ), ilk 10 kelime:the be(am/are/is/was/were) to of and a in that have I

Alice Harikalar Diyarında metninden the and to a of it she i you said
en iyi 10 kelime Jargon Dosyasından en iyi 10 kelime (v4.4.7)the a of to and in is that or for

Yani soru neden orsorunun görmezden gelme listesine dahil edildi, burada kelime that(en çok kullanılan 8.) olmadığında ~ 30. popülerlik . Bu nedenle yoksay listesinin dinamik olarak sağlanması gerektiğine (veya atlanabileceğine) inanıyorum.

Alternatif fikir basitçe sonuçtan ilk 10 kelimeyi atlamak olacaktır - ki bu aslında çözümü kısaltır (temel - sadece 11. ila 32. girişleri göstermek zorundadır).


Python 2.x, titiz bir yaklaşım = 277 243 karakter

Yukarıdaki kodda çizilen grafik basitleştirilmiştir (çubuklar için sadece bir karakter kullanılarak). Birisi problem tanımından tam olarak grafiği oluşturmak istiyorsa (ki bu gerekli değildi), bu kod bunu yapacaktır:

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

Bu the, and, of, to, a, i, it, in, or, isgibi komut satırı parametreleri olarak geçirilecek şekilde hariç tutmak için 10 kelime biraz rastgele seçim ile ilgili bir sorun alırsınız :
python WordFrequencyChart.py the and of to a i it in or is <"Alice's Adventures in Wonderland.txt"

Komut satırına iletilen "orijinal" yoksayma listesini hesaba katarsak, bu 213 karakter + 30'dur = 243

PS. İkinci kod ayrıca tüm üst kelimelerin uzunlukları için "ayarlama" yapar, bu nedenle bunların hiçbiri dejenere durumda taşmaz.

 _______________________________________________________________
|_______________________________________________________________| she
|_______________________________________________________| superlongstringstring
|_____________________________________________________| said
|______________________________________________| alice
|_________________________________________| was
|______________________________________| that
|_______________________________| as
|____________________________| her
|__________________________| at
|__________________________| with
|_________________________| s
|_________________________| t
|_______________________| on
|_______________________| all
|____________________| this
|____________________| for
|____________________| had
|____________________| but
|___________________| be
|___________________| not
|_________________| they
|_________________| so

Kelime yoksayma listesi henüz uygulanmamış olmasına rağmen şimdiye kadar güzel bir çözüm ve çubuklar şu anda biraz ilkel.
ChristopheD

@ChristopheD: oradaydı, ama "kullanım kılavuzu" yoktu. Demet metni eklendi
Nas Banov

Dil ve çözüm listenizle ilgili olarak: Lütfen birlikte bölme \Wveya \bbir normal ifadede kullanma çözümlerini arayın, çünkü bunlar spesifikasyonlara göre büyük olasılıkla değildir , yani rakamlara bölünmeyecek veya _dizelerden durdurma sözcüklerini kaldırmayabilir gibi the_foo_or123bar. Test metninde görünmeyebilirler, ancak şartname bu durumda oldukça açıktır.
Joey

Şaşırtıcı iş Nas, öğleden sonra bunu optimize etmeye çalıştım ve sadece bir gelişme buldum. sys.argvre.findall(r'\b(?!(?:the|and|.|of|to|i[tns]|or)\b)\w+',sys.stdin.read().lower())
Kesmeyi

12

Haskell - 366 351 344 337 333 karakter

( mainOkunabilirlik için bir satır sonu eklendi ve son satırın sonunda satır sonu gerekmez.)

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

En iyi nasıl çalıştığı, argümanı interactgeriye doğru okuyarak görülür :

  • map f küçük harflerle alfabetik, diğer her şeyi boşluklarla değiştirir.
  • words ayırma boşluk bırakarak bir kelime listesi üretir.
  • filter (notElem words "the and of to a i it in or is")tüm kelimeleri yasak sözcüklerle birlikte atar.
  • group . sort kelimeleri sıralar ve özdeş olanları listeler halinde gruplandırır.
  • map hher özdeş kelime listesini formun bir demetiyle eşleştirir (-frequency, word).
  • take 22 . sort tuplleri azalan frekansa (ilk tuple girişi) göre sıralar ve sadece ilk 22 tupülü tutar.
  • b tuplleri çubuklarla eşler (aşağıya bakın).
  • a en üstteki çubuğu tamamlamak için alt çizgi çizgisinin ilk satırını ekler.
  • unlines tüm bu satırları yeni satırlarla birleştirir.

Zor bit çubuk uzunluğunu doğru alıyor. Sadece alt çizgilerin çubuğun uzunluğuna doğru sayıldığını ||, sıfır uzunlukta bir çubuk olacağını varsaydım . İşlev, bharita c xüzerinde x, xhistogramların listesi. Tüm liste iletilir c, böylece her çağırma işlemi çağrı cfaktörünü kendisi için ölçek faktörünü hesaplayabilir u. Bu şekilde, dönüşüm fonksiyonları ve ithalatı birçok karakter yiyebilecek kayan nokta matematiği veya rasyonelleri kullanmaktan kaçınırım.

Kullanma hilesine dikkat edin -frequency. Bu ihtiyacını ortadan kaldırır sıralama (artan) beri ilk büyük frekans ile yerlerdir kelimeler olacak. Daha sonra, işlevde , olumsuzlamayı iptal edecek iki değer çarpılır.reversesort-frequencyu-frequency


Çok güzel bir çalışma (bu oyunda tüm büyük cevaplar ile oy, ancak bugün oy tükendi).
ChristopheD

Bu, gözlerimi tarif etmeyi düşünmek bile acı verici bir şekilde acıtıyor, ama çok fazla Haskell'i okunaklı bir kod haline geri döndürerek öğrendim. Aferin efendim. :-)
Owen S.

Aslında gerçekten verimli olmasa da oldukça deyimsel Haskell. Kısa isimler, gerçekte olduğundan çok daha kötü görünmesini sağlar.
Thomas

@Thomas: Bunu tekrar söyleyebilirsin. :-)
Owen

1
divAslında hareket edemiyorum ! Deneyin - çıkış yanlış. Sebebi neden duruyor divönce *azalma sergiler hassas.
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)}

Ne yazık ki, for([k,v]in z)Rhino sürümünden SpiderMonkey'de çalışmak istemiyor gibi görünüyor ve readFile()kullanmaktan biraz daha kolay readline()ama 1.8'e kadar hareket etmek birkaç satır daha kesmek için işlev kapanışlarını kullanmamıza izin veriyor ....

Okunabilirlik için boşluk ekleme:

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

Kullanımı: js golf.js < input.txt

Çıktı:

 _________________________________________________________________________ 
| _________________________________________________________________________ | o
| _______________________________________________________________ | sen
| ____________________________________________________________ | dedim
| ____________________________________________________ | alice
| ______________________________________________ | oldu
| ___________________________________________ | o
| ___________________________________ | gibi
| ________________________________ | ona
| _____________________________ | en
| _____________________________ | ile
| ____________________________ | s
| ____________________________ | t
| __________________________ | üzerinde
| _________________________ | herşey
| _______________________ | bu
| ______________________ | için
| ______________________ | vardı
| ______________________ | fakat
| _____________________ | olmak
| _____________________ | değil
| ___________________ | onlar
| ___________________ | yani

(temel sürüm - çubuk genişliklerini doğru işlemez)

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

Sanırım sıralama mantığım kapalı, ama .. Ben duno. Brainfart düzeltildi.

Minimize (istismarın bazen \nyorumlandığı ;):

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

Ah, efendim. Bunun senin davanız olduğuna inanıyorum. Yourkincisi benimkinden konuţsun.
dmckee --- eski moderatör yavru kedi

2
BTW-- Biraz beğendim i[tns]?. Çok sinsi.
dmckee --- eski moderatör yavru kedi

@dmckee - iyi oynanan, 336'nızı yenebileceğimi, çok hak ettiğiniz upvote'un keyfini çıkarabileceğimi sanmıyorum :)
Matt

Kesinlikle 336 yenebilir ... 23 karakterli bir kesim var - .replace(/[^\w ]/g, e).split(/\s+/).map(değiştirilebilir .replace(/\w+/g,ve .mapyaptığınız aynı işlevi kullanabilirsiniz ... Ayrıca Rhino function(a,b)b.c-a.csıralama işlevi yerine (spidermonkey yapar) destekliyor mu emin değilim, ama bu olacak tıraş {return }... btw b.c-a.cdaha iyi bir sıralama a.c<b.c... Bu değişikliklerle altta bir Spidermonkey sürümünü düzenleme
gnarf

Çubuk genişliği kısıtlamasına uygun olduğu için SpiderMonkey sürümümü en üste taşıdım ... Ayrıca, tek bir değiştirmeye izin veren kelimeleri reddetmek için negatif bir ileri dönüş regexp kullanarak orijinal sürümünüzde birkaç karakter daha kesmeyi başardım (), ve ?:olsa çalışmak için büyük üssü birkaç ifs golf !
gnarf

11

PHP CLI sürümü (450 karakter)

Bu çözüm, çoğu puristin göz ardı etmek için ikna edici olarak seçtiği son şartı dikkate alır. Bu 170 karaktere mal oldu!

Kullanımı: php.exe <this.php> <file.txt>

minified:

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

İnsan tarafından okunabilir:

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

?>

Çıktı:

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

Uzun bir kelime olduğunda, çubuklar düzgün bir şekilde ayarlanır:

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

11

Python 3.1 - 245 229 charaters

Counter kullanmak biraz hile olduğunu sanırım :) Ben sadece bir hafta önce hakkında okudum, bu yüzden nasıl çalıştığını görmek için mükemmel bir şans oldu.

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

Çıktılar:

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

Kodun bir kısmı AKX'in çözümünden "ödünç alındı".


İlk satır eksik. Ve çubuk uzunluğu doğru değil.
Joey

kodunuzu open('!')stdin okur gibi görünüyor - hangi sürümü / işletim sistemi açıktır? veya '!' dosyasına bir ad vermeniz mi gerekiyor?
Nas Banov

Dosyaya "!" :) Üzgünüm, bu oldukça belirsizdi ve bundan bahsetmeliydim.
Sam Dolan

11

Perl, 205 191 189 karakter / 205 karakter (tam olarak uygulamaya)

Bazı bölümler daha önceki perl / ruby ​​gönderilerinden ilham aldı, birkaç benzer fikir bağımsız olarak geldi, diğerleri orijinaldi. Daha kısa versiyonda diğer gönderilerde gördüğüm / öğrendiğim bazı şeyler var.

Orijinal:

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

191 karaktere kadar son sürüm :

/^(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]

189 karaktere kadar son sürüm:

/^(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]

Bu sürüm (205 karakter), daha sonra bulunacak kelimelerden daha uzun kelimelere sahip satırları açıklar.

/^(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]

10

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

$/=\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]

İkincil kelimenin hem popüler hem de 80'den fazla karakterle birleştirilebilecek kadar uzun olduğu patolojik durum için belirtilen davranışı (küresel bar-squishing) içeren alternatif, tam uygulama ( bu uygulama 231 karakterdir ):

$/=\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"}

Spesifikasyon, bunun STDOUT'a gitmek zorunda olduğu herhangi bir yeri belirtmedi, bu yüzden baskı yerine perl's warn () kullandım - orada dört karakter kaydedildi. Foreach yerine harita kullanıldı, ancak bölünmede (join ()) daha fazla tasarruf olabileceğini hissediyorum. Yine de, 203'e düştü - üzerinde uyuyabilir. En azından Perl şu an için "shell, grep, tr, grep, sort, uniq, sort, head, perl" char count for now;)

Not: Reddit "Merhaba" diyor;)

Güncelleme: Atama ve örtük skaler dönüşüm birleştirme lehine join () kaldırıldı. 202'ye kadar. Ayrıca, 2 karakteri tıraş etmek için isteğe bağlı "1 harfli kelimeleri yoksay" kuralından yararlandığımı unutmayın, bu nedenle sıklık sayısının bunu yansıtacağını unutmayın.

Güncelleme 2: İlk etapta <> kullanarak bir tanede dosya almak için $ / öldürmek için ödev değiştirildi ve örtülü birleştirme. Aynı boyutta, ama daha nazik. (! $ Y) {} $ y || {} && için değiştirildiyse, 1 karakter daha = = 201 kaydetti.

Güncelleme 3: LC'yi harita bloğunun dışına taşıyarak küçük harflerin erken kontrolünü (lc <>) aldı - Artık gerekmediği için her iki ifadeyi de artık / i seçeneğine kullanmaz. Geleneksel perlgolf için değiştirilmiş açık koşullu x? Y: z yapı || örtük koşullu yapı - /^...$/i?1:$x{$ } ++ için /^...$/||$x{$ } ++ Üç karakter kaydetti! => 198, 200 bariyeri kırdı. Yakında uyuyabilir ... belki.

Güncelleme 4: Uyku yoksunluğu beni delirtti. İyi. Daha çılgın. Bunun sadece normal mutlu metin dosyalarını ayrıştırması gerektiğini düşünerek, bir null değerine çarptığında vazgeçtim. İki karakter kaydedildi. "Uzunluk" yerine 1 karakter daha kısa (ve çok daha golfçü) y /// c - beni duyuyor, GolfScript ?? Senin için geliyorum!!! hıçkırık

Güncelleme 5: Uyku deposu bana 22row sınırını ve sonraki satır sınırlamasını unutturdu. Kullandıklarınızla 208'e kadar geri dönün. Çok kötü değil, başa çıkmak için 13 karakter dünyanın sonu değil. Perl en düzenli ifade inline eval etrafında oynanan, ancak sorun yaşıyor hem işe onu almak ve lol ... karakter kaydet. Örneği, güncel çıktıyla eşleşecek şekilde güncellendi.

Güncelleme 6: Sözdizimsel şeker ++ onu mutlu bir şekilde karşı itmeye izin verdiği için, koruyan gereksiz parantez kaldırıldı (...). Chas'ın girişi sayesinde. Owens (yorgun beynimi hatırlatıyor), karakter sınıfı i [tns] çözümünü içeri aldı. 203'e geri dönün.

Güncelleme 7: Spesifikasyonların tam olarak uygulanması için ikinci iş parçası eklendi (patolojik örnek vakası olmadan orijinal spesifikasyona dayanarak, çoğu insanın yaptığı kesme yerine ikincil uzun kelimeler için tam bar-squishing davranışı dahil)

Örnekler:

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

Patolojik vaka örneğinde alternatif uygulama:

 _______________________________________________________________
|_______________________________________________________________| she
|_______________________________________________________| superlongstringstring
|____________________________________________________| said
|______________________________________________| alice
|________________________________________| was
|_____________________________________| that
|_______________________________| as
|____________________________| her
|_________________________| with
|_________________________| at
|_______________________| on
|______________________| all
|____________________| this
|____________________| for
|____________________| had
|____________________| but
|___________________| be
|__________________| not
|_________________| they
|_________________| so
|________________| very
|________________| what

Sen çöken stop sözcükleri için regex kısaltabilir is|in|it|iiçine i[snt]?- ve sonra artık opsiyonel kural ile hiçbir fark yoktur. (Hm, bir Perl adama nasıl Regex: D yapmasını söylemeyi asla düşünmezdim) - şimdi tek sorun: Perl'den daha iyi olmak için kendi çözümümden nasıl üç bayt tıraş edebileceğime bakmalıyım: - |
Joey

Tamam, daha önce söylediğim şeyin bir kısmını göz ardı et. Tek harfli kelimeleri görmezden gelmek aslında yapmamaktan daha kısa bir bayttır.
Joey

Her bayt önemlidir;) Newline hile yapmayı düşündüm, ancak daha az yazdırılabilir karakter olsa bile aslında aynı sayıda bayt olduğunu düşündüm. Hala biraz daha
daraltıp azaltamayacağımı

Ah, dava normalizasyonu beni 209'a geri götürdü. Başka ne kesebileceğimi göremiyorum. PowerShell rağmen yapabilirsiniz Perl daha kısa. ;-)
Joey

Çıktıyı en üstteki 22 kelimeyle sınırlandırdığınızı veya uzun bir ikinci kelimenin sarılmadığından emin olmadığınız bir yer görmüyorum.
Gabe

9

F #, 452 karakter

Strightforward: bir dizi akelime sayımı çifti elde edin, sütun başına en iyi kelime sayısı çarpanını bulun ve ksonuçları yazdırın.

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

Örnek (Senden farklı frek sayımları var, neden olduğundan emin değilim):

% 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

kendi çözümüm aslında biraz farklıydı (biraz farklı özellik nedeniyle), çözümler şimdi karşılık geliyor ;-)
ChristopheD

Şimdiye kadarki tek doğru ölçeklendirme uygulaması için +1
Rotsor

2
(@Rotsor: Ironic, benimki en eski çözümdür.)
Brian

Bahse girerim, bölme, harita ve filtre aşamalarını birleştirerek biraz kısaltabilirsiniz. Ayrıca bu kadar çok şeye ihtiyacınız olmayacağını da beklerdim float.
Gabe

Yerleştirme işlevleri genellikle boru hattı işlecini kullanmaktan daha kısa değil |>mi?
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))

Çıktı:

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

1
bm=(76.-len(W[0][0]))/W[0][1]Bm'yi yalnızca bir kez kullandığınız için satırı kaybedebilirsiniz (sonraki satırı yapın U=lambda n:"_"*int(n*(76.-len(W[0][0]))/W[0][1]), 5 karakteri tıraş eder. Ayrıca: kod golfünde neden 2 karakterli bir değişken adı kullanasınız? ;-)
ChristopheD

Son satırda baskı sonrası boşluk gerekli değildir, bir karakteri tıraş eder
ChristopheD

1
İkinci en sık kullanılan kelimenin çok uzun olduğu durumu dikkate almıyor, değil mi?
Joey

@ChristopheD: Çünkü biraz uzun süredir bu koda bakıyordum. : P İyi yakaladın. @Johannes: Bu da düzeltilebilir, evet. Bunu yazarken diğer tüm uygulamaların bunu yaptığından emin değilim.
AKX

7

* sh (+ kıvrılma), kısmi çözelti

Bu tamamlanmadı, ancak cehennem için, sorunun 192 baytta yarısının kelime frekansını sayması:

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

7

Gawk - 336 (aslen 507) karakter

(çıktı biçimlendirmesini düzelttikten sonra; kasılma olayını düzelttikten sonra; tweaking; tekrar tweaking; tamamen gereksiz bir sıralama adımını kaldırmak; yine tweaking; ve tekrar (oops biçimlendirmeyi kırdı); biraz daha fazla tweak; Matt'in meydan okumasını çaresizce değiştirdim çok daha fazlası; birkaçını kurtarmak için başka bir yer buldu, ancak çubuğu uzunluk hatasını düzeltmek için iki geri verdi)

Heh heh! Ben anlık olarak [Matt'in JavaScript] [1] çözüm sayacı meydan okuma ilerisinde ! ;) ve [AKX'in pitonu] [2].

Sorun, yerel ilişkilendirilebilir dizileri uygulayan bir dili çağırıyor gibi görünüyor, bu yüzden elbette üzerlerinde korkunç derecede eksik operatörler içeren bir dil seçtim. Özellikle, awk'nin bir karma haritasının öğelerini sunduğu sırayı kontrol edemezsiniz, bu yüzden şu anda en çok sayıda öğeyi bulmak, yazdırmak ve diziden silmek için sürekli olarak tüm haritayı tarıyorum.

Her şey çok verimsiz, yaptığım tüm golfifcations ile oldukça korkunç olmaya başladı.

minified:

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

satır yalnızca netlik için kesilir: gerekli değildir ve sayılmamalıdır.


Çıktı:

$ 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

Okunabilir; 633 karakter (başlangıçta 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]
    }
}

İyi iş, iyi girintili / yorumlu bir sürüm dahil ;-)
ChristopheD

7

Ortak LISP, 670 karakter

Ben bir LISP acemi, ve bu sayım için bir karma tablo kullanarak bir girişimdir (bu yüzden muhtemelen en kompakt yöntem değil).

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

ile çalıştırılabilir cat alice.txt | clisp -C golf.lisp.

Okunabilir formda

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

bazı giriş boyutlarını tıraş etmek için özel bir okuyucu makrosu yüklemeyi denediniz mi?
Aaron

@Aaron aslında benim için sadece bu çalışma almak için önemsiz değildi ... :-) gerçek golf bölümü için ben sadece bir harfli değişkenler kullandım ve hepsi bu. Her neyse, bu sorun ölçeği için CL'de içkin olan biraz yüksek ayrıntıların yanı sıra ("dizeyi birleştirmek", "setf" veya "gethash" katillerdir ... python'da "+", "=", "[]" ) bunu mantıklı bir seviyede bile beklediğimden çok daha kötü hissettim. Bir anlamda lisp'in iyi olduğunu hissediyorum, ama ortak lisp so-so ve bu isimlendirmenin ötesinde (CL ile olan deneyimim sıfıra yakın olduğu için çok haksız bir yorumu yeniden okumak).
6502

doğru. düzeni tek isim alanı ile golf biraz daha kolay olacaktır. her yerde dize-ekleme yerine, (letrec ((bir dize-ekleme) (b gethash)) ... (bir "x" "yz") ...)
Aaron

6

C (828)

Gizlenmiş kod gibi görünüyor ve dize, liste ve karma için glib kullanıyor. Char sayısı 828wc -m diyor . Tek karakterlik kelimeleri dikkate almaz. Çubuğun maksimum uzunluğunu hesaplamak için, sadece ilk 22'yi değil, hepsi arasında mümkün olan en uzun kelimeyi dikkate alır. Bu, spesifikasyondan sapma mıdır?

Arızaları işlemez ve kullanılmış belleği serbest bırakmaz.

#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);}

Yeni satırlar karakter olarak sayılır, ancak önişlemci talimatı olmayan satırlardan herhangi birini çıkarabilirsiniz. Bir golf için, hafızayı serbest bırakmamayı kötü bir uygulama olarak görmezdim.
Stéphan Kochen

tamam ... hepsini bir satıra koy (preproc makrolarını bekle) ve mem serbest bırakmadan bir vers ver (ve diğer iki boşluk kaldırılmış ... "biraz" iyileştirme "yapılabilir, örneğin *v=*v*(77-lw)/m929 verecektir. .. ama çok daha kısa yapmanın bir yolunu bulamadığım sürece sorun olmadığını düşünüyorum)
ShinTakezou

Sana en azından taşıyabilirsiniz düşünüyorum int ciçine mainbeyanı ve mainörtülü olduğu int(gibi herhangi Türlenmemiş argümanlar afaik vardır): main(c){...}. Muhtemelen sadece yazmak 0yerine yazabilirsiniz NULL.
Joey

Bunu yapmak ... tabii ki üzerinde -Wallveya -std=c99bayrağı ile bazı uyarılar tetikler ... ama sanırım bu bir kod golf için anlamsız, değil mi?
ShinTakezou

uff, kısa aralıklı zaman düzenlemeleri için özür dilerim, ... Without freeing memory stuff, it reaches 866 (removed some other unuseful space)İnsanlara, boş bellek sürümündeki farkın hepsinde olduğunu düşünmemek için başka bir şeye geçmeliyim: şimdi boş bellek sürümü çok şey var daha fazla "iyileştirme".
ShinTakezou

6

Perl, 185 karakter

200 (hafif kırık) 199 197 195 193 187 185 karakter. Son iki yeni satır önemlidir. Şartnameye uygundur.

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

İlk satır, içine geçerli kelime sayısını yükler %X.

İkinci satır minimum ölçeklendirme faktörünü hesaplar, böylece tüm çıkış satırları <= 80 karakter olur.

Üçüncü satır (iki yeni satır karakteri içerir) çıktıyı üretir.


Bu, "foo_the_bar" gibi dizelerden durdurma sözcüklerini kaldırmaz. Satır uzunluğu da çok uzun (spesifikasyonu yeniden okuyun: "bar + boşluk + kelime + boşluk <= 80 karakter")
Joey

5

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

  • İlk 742 öncesi güncellemeler : iyileştirilmiş normal ifade, gereksiz parametreli türler kaldırıldı, gereksiz boşluk kaldırıldı.

  • 742> 744 karakterlerini güncelleyin : sabit uzunluklu kesmek düzeltildi. Sadece 1. kelimeye bağlıdır, diğer kelimelere değil (henüz). Kodu kısaltmak için birkaç yer bulundu ( \\snormal ifadeyle değiştirildi ve ArrayListdeğiştirildi Vector). Şimdi Commons IO bağımlılığını ve okumayı stdin'den çıkarmanın kısa bir yolunu arıyorum.

  • 744> 752 karakterlerini güncelle : Müşterek bağımlılığını kaldırdım. Şimdi stdin'den okuyor. Metni stdin'e yapıştırın ve Ctrl+Zsonuç almak için tuşuna basın.

  • Güncelleme 752> 742 karakter : Kaldırdım publicve bir boşluk, 2 yerine sınıf 1 karakter yaptı ve şimdi tek harfli kelimeleri görmezden geliyor.

  • Güncelleme 742> 714 karakter Carl Yorumlar başı itibarıyla güncellendi: değiştirilmiştir kaldırıldı gereksiz atama (> 730 742), m.containsKey(k)tarafından m.get(k)!=null(730> 728), (> 714 728) hattın substringing tanıtıldı.

  • 714> 680 karakter güncelleyin Rotsor yorumlarına göre Güncelleme: İyileştirilmiş çubuk boyutu hesaplama gereksiz dökümü kaldırmak ve geliştirilmiş split()gereksiz kaldırmak 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);}}

Daha okunabilir versiyon:

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);
 }
}

Çıktı:

 _________________________________________________________________________
| _________________________________________________________________________ | o
| _______________________________________________________________ | sen
| ____________________________________________________________ | dedim
| _____________________________________________________ | alice
| _______________________________________________ | oldu
| ___________________________________________ | o
| ____________________________________ | gibi
| ________________________________ | ona
| _____________________________ | ile
| _____________________________ | en
| __________________________ | üzerinde
| __________________________ | herşey
| _______________________ | bu
| _______________________ | için
| _______________________ | vardı
| _______________________ | fakat
| ______________________ | olmak
| _____________________ | değil
| ____________________ | onlar
| ____________________ | yani
| ___________________ | çok
| __________________ | ne

Java'nın (henüz) sahip olmadığı String#join()ve kapanmadığı oldukça berbat .

Rotsor tarafından düzenle:

Çözümünüzde birkaç değişiklik yaptım:

  • Dize ile Değiştirilen Liste []
  • Kendi String dizimi bildirmek yerine 'args' argümanını yeniden kullandım. Ayrıca .ToArray () öğesine argüman olarak da kullanılır
  • StringBuffer bir String ile değiştirildi (evet, evet, korkunç performans)
  • Java sıralama, erken durdurma ile bir seçim sıralama ile değiştirildi (yalnızca ilk 22 öğenin bulunması gerekir)
  • Bazı int bildirimlerini tek bir ifadede topladı
  • En sınırlayıcı çıktı hattını bulan hile yapmayan algoritmayı uyguladı. FP olmadan uygulandı.
  • Metinde 22'den az farklı kelime olduğunda programın çökme sorunu düzeltildi
  • Hızlı ve yavaş olandan sadece 9 karakter uzunluğunda yeni bir okuma girişi algoritması uygulandı.

Yoğunlaştırılmış kod 688 711 684 karakter uzunluğundadır:

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);}}}

Hızlı sürüm ( 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);}}}

Daha okunabilir versiyon:

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);}}
}

Davranış geliştirmeleri olmayan sürüm 615 karakterdir:

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);}}}

IOUtilsİçe aktarmak için tam adı kullanamaz mısınız? Gördüğüm kadarıyla sadece bir kez kullandığınızı görebiliyorum.
Joey

5
En uzun çubuğun tam olarak 75 karakter olacağını varsayarak kandırdın. Hiçbir bar + kelimesinin 80 karakterden uzun olmadığından emin olmalısınız.
Gabe

Kelimeden sonra bir boşluk eksik. ;)
st0le

Ben aşağı budamıyordu gibi benim cevap , ben BalusC gönderisini yendi umuyordum. Hala 200 karakterim var, ugh! Commons IO ve 75 char varsayımı olmadan bunun ne kadar süreceğini merak ediyorum.
Jonathon Faust

1
bStringBuffer yerine bir String oluşturarak bazı karakterleri tıraş edebileceğiniz anlaşılıyor. Yine de performansın ne olacağını düşünmek istemiyorum (özellikle bir kerede bir karakter eklediğiniz için).
Michael Myers

4

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

uzun kelime ayarı dahil. Fikirler diğer çözümlerden ödünç alındı.

Şimdi bir script ( a.scala) olarak:

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)

Şununla koş:

scala -howtorun:script a.scala alice.txt

BTW, 314 ile 311 karakter arasında yapılan düzenleme aslında sadece 1 karakteri kaldırır. Birisi sayımı daha önce yanlış yaptı (Windows CRs?).


4

Clojure 282 katı

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

Biraz daha okunaklı:

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

4

Scala, 368 karakter

İlk olarak, 592 karakterden oluşan okunaklı bir sürüm:

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

Konsol çıkışı şöyle görünür:

$ 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

Bazı agresif küçültme yapabilir ve 415 karaktere kadar indirebiliriz:

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

Konsol oturumu şöyle görünür:

$ 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

Eminim bir Scala uzmanı daha iyisini yapabilir.

Güncelleme: Yorumlarda Thomas daha kısa bir versiyon verdi, 368 karakterle:

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

Okunaklı, 375 karakterde:

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

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

Tabii ki, anlama için hiç kullanışlı! Güzel!
pr1001

3

Java - 896 karakter

931 karakter

1233 karakter okunamaz hale getirildi

1977 karakter "sıkıştırılmamış"


Güncelleme: Karakter sayısını agresif bir şekilde azalttım. Güncellenen özellik başına tek harfli kelimeleri atlar.

C # ve LINQ'yu çok kıskanıyorum.

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)+" ");}}}

"Okunabilir":

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)+" ");
      }
   }
}

Alice çıktı:

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

Don Kişot Çıkışı (Gutenberg'den de):

 ________________________________________________________________________
|________________________________________________________________________| that
|________________________________________________________| he
|______________________________________________| for
|__________________________________________| his
|________________________________________| as
|__________________________________| with
|_________________________________| not
|_________________________________| was
|________________________________| him
|______________________________| be
|___________________________| don
|_________________________| my
|_________________________| this
|_________________________| all
|_________________________| they
|________________________| said
|_______________________| have
|_______________________| me
|______________________| on
|______________________| so
|_____________________| you
|_____________________| quixote

8
Tamamen sazan, Java'da kısaltmanın bir yolu yok mu? Sizlerin karakterlerin sayısına göre ödenen değil :-) işlevselliği ile olsun umut
Nas Banov
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.