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


Meydan okuma:

Belirli bir metinde en sık kullanılan sözcüklerin bir ASCII grafiğini oluşturun.

Kurallar:

  • Sadece kabul a-z ve A-Z Bir kelimenin bir parçası olarak (alfabetik karakterler).
  • Muhafazayı yoksay (She == she bizim amacımız için).
  • Aşağıdaki kelimeleri görmezden gel (oldukça sağlam, biliyorum): the, and, of, to, a, i, it, in, or, is
  • Açıklama: dikkate alınarak don't: Bu aralıklarda 2 farklı 'kelime' olarak alınacak a-z ve A-Z: (don ve t).

  • İsteğe bağlı olarak (şu anda şartnameyi resmi olarak değiştirmek için çok geç) Mayıs ayı Tüm tek harfli 'kelimeleri' bırakmayı seçin (bu, potansiyel olarak ihmal listesinin kısalmasını sağlayabilir).

Verilen bir ayrıştırma text (komut satırı argümanları ile belirtilen bir dosyayı okuyun veya içine pipetleyin; us-ascii) ve bizi bir word frequency chart aşağıdaki özelliklere sahip:

  • En yaygın 22 kelime için grafiği (aşağıdaki örneğe bakınız) (azalan frekansa göre sıralı).
  • Çubuk width kelimenin orantı sayısını (frekans) temsil eder (orantılı). Bir boşluk ekleyin ve kelimeyi yazdırın.
  • Bu çubukların (boşluk-kelime-boşluk) daima olduğundan emin olun uygun: bar + [space] + word + [space] her zaman olmalı <= 80 karakterleri (olası farklı bar ve kelime uzunluklarını dikkate aldığınızdan emin olun: örn .: en yaygın ikinci kelime, daha sonra frekansta çok fazla farklılık göstermeyen ilk önce çok daha uzun olabilir). maksimuma çıkarmak Bu kısıtlar dahilinde çubuk genişliğini ve çubukları uygun şekilde ölçeklendirin (temsil ettikleri frekanslara göre).

Bir örnek:

Örnek için metin burada bulunabilir (Harikalar Diyarında Alice'in Maceraları, Lewis Carroll).

Bu özel metin aşağıdaki tabloyu verecektir:

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


Bilgileriniz için: Bunlar yukarıdaki grafiğin üzerine kurulduğu frekanslardır:

[('o, 553), (' sen ', 481), (' dedi ', 462), (' alice ', 403), (' idi ', 358),'
', 330), (' as ', 274), (' onun ', 248), (' ile ', 227), (' at ', 227'), ('s', 219), ('t')
, 218), ('on', 204), ('hepsi', 200), ('bu', 181), ('için', 179), ('vardı', 178), ('
ama ', 175),' ',' '(167), (' değil ', 166), (' onlar ', 155), (' öylesine ', 152)]

İkinci bir örnek (tam özellikleri uygulayıp uygulamadığınızı kontrol etmek için): Her durumunu değiştir you bağlantılı olarak Alice Harikalar Diyarında ile dosya 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 başına, dil başına). İyi eğlenceler!


Düzenle: Şimdiye kadarki sonuçları özetleyen tablo (2012-02-15) (aslen Nas Banov tarafından eklenmiştir):

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

Sayılar, belirli bir dilde en kısa çözümün uzunluğunu temsil eder. "Sıkı", spesifikasyonları tamamen uygulayan bir çözümü ifade eder (çizer) |____| çubukları, üstüne ilk çubuğu kapatır ____ satır, yüksek frekans vb. ile uzun kelimelerin olasılığını hesaplar. "Rahat", çözüm için kısaltmak için bazı özgürlüklerin alındığı anlamına gelir.

Sadece daha kısa çözümler daha sonra 500 karakter dahil edilmiştir. Dil listesi 'katı' çözümün uzunluğuna göre sıralanır. 'Unix Toolchain', geleneksel * nix kabuğunu kullanan çeşitli çözümleri belirtmek için kullanılır artı araçların bir karışımı (grep, tr, sort, uniq, head, perl, awk gibi).


156


Menşei


Peki, 'en uzun çubuk' + kelime = 80 ikinci en yaygın kelime çok daha uzun bir kelime ise 80 cols içinde sığmayabilir. Sanırım 'maksimum kısıtlama' arıyorum. - Brian
Muhafazayı normalleştirir miyiz? 'O' = 'o'? - Brian
Bunu gerçekleştiren IMO, hem yürütme süresi hem de bellek kullanımı açısından karakter sayısından daha ilginç bir meydan okuma gibi görünüyor. - Frank Farmer
Favori sözlerimi gördüğüme sevindim s ve t temsil edilir. - indiv
@indiv, @Nas Banov - aptalca çok basit tokenizer, {didn, t} ve "she's" olarak "yapmadı" ifadesini okur. - hobbs


Cevaplar:


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

Fili musluğa öğretmek asla güzel değildir. Ben, ah, karakter sayımı atlayacağım.

labVIEW code

results

Program soldan sağa doğru akar:

labVIEW code explained


123



Değmez
LabVIEW, donanım kontrolü ve ölçüm nişlerinde çok mutlu, ancak dize manipülasyonu için gerçekten oldukça korkunç. - Joe Zoller
Henüz 3D yok mu? ...: D - Dr. belisarius
Gördüğüm en iyi kod golf cevap. Kutunun dışında düşünmek için +1! - Blair Holloway
Bizim için öğeleri saymalıyız ... ekrana sürüklemek zorunda kaldığınız her kutu ve widget. - dmckee


Ruby 1.9, 185 karakter

(ağırlıklı olarak 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ı kullanmak yerine, dosya adını argüman olarak iletebilirsiniz. (Yani ruby1.9 wordfrequency.rb Alice.txt)

Buradaki karakter-literalleri kullandığım için, bu çözüm sadece Ruby 1.9'da çalışıyor.

Düzenleme: "okunabilirlik" için satır sonları ile değiştirilen noktalı virgüller. : P

Düzenleme 2: Shtééf işaret etti, firar alanı unuttum - bunu düzeltdim.

Düzenleme 3: İz alanı tekrar kaldırıldı;)


42



Her kelimeden sonra izleyen boşluğu kaçırıyor. - Stéphan Kochen
Aww çek, bunu dikkate almayın. Golfün yeni güncellendiği gibi görünüyor, artık gerekli alan yok. :) - Stéphan Kochen
'Superlongstringstring' için 2. veya daha sonraki pozisyonlarda yer almıyor mu? (sorun açıklamasına bakınız) - Nas Banov
Bu gerçekten bakılabilir görünüyor. - Zombies


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 kayıtlarında görünür çıktı.


39



GolfScript hakkında: golfscript.com/golfscript - Assaf Lavie
Doğru değil, eğer ikinci kelime gerçekten uzunsa, sonraki satıra sarılacaktır. - Gabe
Rakamlar golfscript kazandı: P - RCIX
"sıfıra böl" ... GolfScript buna izin veriyor mu? - JAB
Açıklamayu beğendim! - Marek


206

kabuk, grep, tr, grep, sırala, uniq, sırala, 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, yukarıda görüldüğü gibi: sort -nr -> sort -n ve sonra head -> tail => 208 :)
update2: erm, tabiki yukarıdaki gibi aptalca, o zaman tersine çevrilecek. Yani 209.
update3: dışlama regexp'ini 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ğlence için, burada sadece bir 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



Etkileyici golf! - ChristopheD
Gerçekten çok etkileyici. - Camilo Martin


Transact SQL set 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ı yararlı öneriler için Gabe'e teşekkürler.

Not: Kaydırma çubuklarından kaçınmak için eklenen satır sonları sadece son satır sonu gerektirir.

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 versiyonu

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 dize ile

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

35



Sana bir +1 verdim çünkü bunu T-SQL'de yaptın ve Team America'yı alıntılamak için - "Topların var. Topları severim."
Bu kod bana bağırıyor! :O - Joey
Tasarruf etmenin iyi bir yolu değişerek 0.000 sadece 0, sonra kullanarak -C yerine 1.0/C. Ve yapmak FLOAT içine REAL bir felç de kaydeder. Ancak en büyük şey, çok fazla varmış gibi görünüyor. AS isteğe bağlı olması gereken örnekler. - Gabe
Tamam, ne dersin SELECT [ ] FROM (SELECT $0 O, ' '+REPLICATE('_', MAX(C)*@F)+' ' [ ] FROM # UNION SELECT $1/C, '|'+REPLICATE('_',C*@F)+'| '+W FROM #)X ORDER BY O? - Gabe
HA! Bunu al, Java! - Gabe


yakut 207  213  211  210  207  203  201 200 karakter

Rufustan öneri içeren Anurag üzerinde bir gelişme. Ayrıca sıralama ve diğer birkaç küçük golf için argüman 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} "}

Yürüt:

ruby GolfedWordFrequencies.rb < Alice.txt

Düzenleme: 'koyar' yerine koy, çıktıda alıntı yapmaktan kaçınmak için orada olmanız gerekir.
Edit2: Değiştirilmiş Dosya-> IO
Düzenleme3: kaldırıldı / i
Edit4: Etraftaki parantezler kaldırıldı (f * 1.0), yeniden sayıldı
Düzenleme 5: İlk satır için dize eklemeyi kullanın; genişletmek s Yerinde.
Edit6: Made m float, 1.0 kaldırıldı. DÜZENLEME: Çalışmıyor, uzunlukları değiştiriyor. DÜZENLEME: Öncekinden daha kötü değil
Düzenleme7: Kullan STDIN.read.


34



+1 - sıralama parçasını sev, çok zeki :) - Anurag
Hey, küçük optimizasyon, ilk etapta onunla gelmekle kıyaslandığında. :) - archgoon
Güzel! Anurag'ın versiyonunda da yaptığım iki değişiklik eklendi. Başka 4 tıraş var. - Stéphan Kochen
Çözüm orijinal çıktıdan saptı, ben de nereye gideceğimi anlamaya gidiyorum. - archgoon
Bundan daha kısa bir varyant daha var. - archgoon


Mathematica (297  284  248  244  242 199 karakter) Saf İşlevsel

  ve Zipf Yasası Testi

Bak Mamma ... hayır var, el yok, .. başı yok

Düzenleme 1> tanımlanmış bazı shorthand'ler (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ı

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

Mathematica, golf için çok uygun değildir ve bu sadece uzun, tanımlayıcı işlev isimleri nedeniyle. "RegularExpression []" veya "StringSplit []" gibi işlevler sadece beni sob :(.

Zipf Kanunu Testi

Zipf yasası doğal bir dil metni için Giriş (Sıra) vs Giriş (olaylar) Arsa bir izler doğrusal ilişkisi.

Kanun, kriptografi ve veri sıkıştırma için algoritmaların geliştirilmesinde kullanılır. (Ama LZW algoritmasında "Z" DEĞİL).

Bizim metnimizde, aşağıdaki ile 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)

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

 Düzenleme 6> (242 Karakter)

Regex'in yeniden düzenlenmesi (artık Select işlevi yok)
1 char kelimeyi bırakarak
"F" işlevi için daha verimli tanımlama

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 f ile Transpose ve Slot (#1/#2) argümanlar.
  • Stinkin 'parantezlerine ihtiyacımız yok f@x yerine f[x] nerede mumkunse)


28



"RegularExpression" un kötü olduğunu mu düşünüyorsun? Objective-C kodunu görene kadar C # sürümüne "System.Text.RegularExpressions.Regex.Split" yazdığımda ağladım: "stringWithContentsOfFile", "enumerateSubstringsInRange", "NSStringEnumerationByWords", "sıralanmışArrayUsingComparator", vb. . - Gabe
@Gabe Teşekkürler ... Şimdi daha iyi hissediyorum. İspanyolcada "mal de muchos, consuelo de tontos" deriz .. "Birçok sorunlu, aptallar rahatlamış" gibi bir şey: D - Dr. belisarius
|i| regex'inizde gereksizdir çünkü zaten var .|. - Gabe
Ben İspanyolca'yı seviyorum. İngilizce olarak düşünebileceğim en yakın şey "sefalet şirketi seviyor". İşte benim çeviri girişimi: "Acı çekerken, aynı durumda başkalarını düşünmek için teselli eden bir aptal." Mathematica uygulamasında inanılmaz çalışma, btw. - dreeves
199'a indirdi ... - Michael Pilat


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

O kadar kısa değil ama şimdi muhtemelen doğru! Not, önceki sürüm, çubukların ilk satırını göstermedi, çubukları doğru şekilde ölçeklendirmedi, dosyayı stdin'den almak yerine indirdi ve gerekli tüm C # boşluğunu içermedi. C # 'nin fazladan saçmalıklara ihtiyaç duymaması halinde birçok vuruş kolayca traş 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));
    }
}

422 karakter ile lendivisor Aşağıdaki formda satır içi (22 kez daha yavaş yapar) (seçili boşluklar için kullanılan satırsonları):

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

27



Zeki olan bu. Bunu sevdim. - Arve Systad
Dosyayı inline indiren smart-ass için +1. :) - sarnold
Matt'in cevabından kısa URL'yi çal. - indiv
Spesifikasyonlar, dosyanın boru olarak girilmesi veya bir geçit olarak geçirilmesi gerektiğini söyledi. Eğer args [0] 'un yerel dosya ismini içerdiğini varsayıyor olsaydınız, (new WebClient ()) yerine args [0]' u kullanarak onu önemli ölçüde kısaltabilirsiniz. DownloadString (@ "gutenberg.org/files/11/11.txt") -> size yaklaşık 70 karakter kazandıracak - thorkia
Burada WebClient çağrısını args 0 ile değiştirme, StreamReader çağrısı ve birkaç ekstra boşluk kaldırarak. 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 String (' _ ', xc * (80-mwLength-4) / mc) + "|" + xw)); - thorkia


Perl, 237  229 209 karakter

(Ruby versiyonunu daha kirli golf hileleriyle yenmek için tekrar güncellendi, değiştirildi split/[^a-z/,lc ile lc=~/[a-z]+/gve boş bir dizgiyi başka bir yerde kontrol etmeyi ortadan kaldırır. Bunlar Ruby versiyonundan ilham aldılar, bu nedenle kredinin vadesi gereken kredi.)

Güncelleme: Perl 5.10 ile şimdi! değiştirmek print ile say, ve kullan ~~ önlemek için map. Bu, komut satırında şu şekilde çağrılmalıdır: perl -E '<one-liner>' alice.txt. Komut dizisinin tamamı bir satırda olduğundan, tek liner olarak yazılması herhangi bir zorluk göstermemelidir :).

 @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 versiyonun durum için normal olduğunu unutmayın. Bu, çözümü kaldırdığı için çözümü kısaltmaz. ,lc (alt kasa için) eklemenizi gerektirir A-Z bölünmüş regex için, bu yüzden bir yıkama.

Eğer bir satırsonunun bir karakter ve iki olmayan bir sistem üzerindeyseniz, bunu yerine başka bir iki karakterle kısaltın. \n. Ancak, yukarıdaki örneği bu şekilde yazmadım, çünkü "daha net" (ha!) Bu şekilde.


İşte çoğunlukla doğru, ama yeterince kısa değil, 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 elde edilebilecek 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;

25



Şu anda birkaç hata var; sabitleme ve kısaltma. - JSBձոգչ
Bu, ikinci kelime ilkinden çok daha uzun olduğunda durumu kapsamaz, değil mi? - Joey
Her ikisi de foreach s olarak yazılabilir for s. Bu 8 karakter aşağı. O zaman sende grep{!($_~~@s)}map{lc=~/[a-z]+/g}<>olarak yazılabileceğine inanıyorum grep{!(/$_/i~~@s)}<>=~/[a-z]+/g 4 daha aşağı gitmek için. Değiştirin " " ile $" ve sen 1 daha iniyorsun ... - Zaid
sort{$c{$b}-$c{$a}}... iki tane daha kaydetmek için. Ayrıca sadece geçebilirsiniz %c yerine keys %c göre sort işlev ve dört daha kaydedin. - mob


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

(Mevcut kod ve test dosyalarım mevcut SVN veri havuzumda. Umarım test vakalarım en sık karşılaştığım hataları yakalar (çubuk uzunluğu, normal ifadeler ile ilgili problemler ve birkaçı).

Varsayımlar:

  • ABD ASCII girişi. Muhtemelen Unicode ile garipleşiyor.
  • En azından iki metinde durmayan kelimeler

Tarihçe

Rahat sürümü (137), şu an itibariyle ayrı ayrı sayıldığı için, görünüşe göre:

($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 kapatmıyor
  • ilk olmayan kelimenin kelime uzunluğunu hesaba katmaz

Bir karakterin çubuk uzunluklarının diğer çözümlerle karşılaştırılması, kayan nokta sayılarını tam sayılara dönüştürürken, kesim yerine yuvarlatmayı kullanan PowerShell'e bağlıdır. Görev yalnızca orantılı çubuk uzunluğuna ihtiyaç duyduğundan, bunun iyi olması gerekir.

Diğer çözümlerle kıyaslandığında, en uzun çubuk uzunluğunun belirlenmesinde, çizginin 80 karakterden daha uzun olmadığı durumlarda, en yüksek uzunlukta denemeler yaparak, biraz farklı bir yaklaşım benimsedim.

Açıklanmış eski bir sürüm bulunabilir İşte.


20



Etkileyici, Powershell golf için uygun bir ortam gibi görünüyor. Çubuk uzunluğunu dikkate alan yaklaşımınız, tam olarak tarif etmek istediğim şeydir (o kadar da zekice değil, itiraf etmekteyim). - ChristopheD
@ChristopheD: Deneyimimde (Anarchy Golf, bazı Project Euler görevleri ve sadece eğlenmek için bazı görevler), PowerShell genellikle Ruby'den biraz daha kötüdür ve sıklıkla Perl ve Python'dan daha iyi veya daha iyidir. Yine de GolfScript ile eşleşme yok. Ama görebildiğim kadarıyla, bu, çubuk uzunluklarını doğru olarak hesaplayan en kısa çözüm olabilir ;-) - Joey
Görünüşe göre haklıymışım. Güç kalkanı kutu daha iyi - daha iyi! Lütfen yorumlarla 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
Çıkış dizesini enterpolasyon yapmayı unutma: "|$('_'*($w*$_.count/$x[0].count))| $($_.name) " (veya otomatik olarak olduğu gibi son boşluğu ortadan kaldırır). Ve sen kullanabilirsiniz -split("(?:\b(?:the|and|of|to|a|i[tns]?|or)\b|[^a-z])+") boşluk içermeyen birkaç tane daha kaydetme (veya kullanma [-2..-23]). - Gabe


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

1. güncelleme: hurra! Bu bir kravat JS Patlama' çözüm. Daha fazla kesmek için bir yol düşünemiyorum :)

güncelleme 2: Kirli bir golf oyunu oynadım. değişmiş each için map 1 karakteri kurtarmak için :)

güncelleme 3: Değiştirildi File.read için IO.read 2. Array.group_by çok verimli değildi, değişti reduce 6. Alt kasadan sonra büyük / küçük harf duyarlı kontrol gerekli değildir. downcase regex +1. Alçalma sırasına göre sıralama, +6 değerini negatif olarak kolayca yapılabilir. Toplam tasarruf +15

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

5. güncelleme: genişletme değişkeni l yerinde, +1. Değişkeni genişlet s yerinde, +2. (@ Shtééf)

6. güncelleme: İlk satır için enterpolasyon yerine dizgi eklemesi 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} "}

7. güncelleme: İlk yinelemeyi algılamak için bir sürü hoopla gittim içeride Örnek değişkenleri kullanarak döngü. Elimdeki tek şey +1, belki de potansiyel var. Önceki sürümü korumak, çünkü bunun bir 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 versiyonu

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 

19



Whoa, Ruby Perl'i dövüyor. - Grant Paul
"P", "koyar" için bir kısayol değil mi? Bu birkaç traş olabilir. - rfusca
Güzel. Kullanımınız scan, yine de, bana daha iyi bir fikir verdi, bu yüzden tekrar var :). - JSBձոգչ
Çubukları, en uzun kelime artı çubuğunun 80 karaktere sığması için ölçeklendirmeniz gerekir. Brian'ın önerdiği gibi, uzun bir ikinci kelime programınızı kıracaktır. - Gabe
Bunun neden hala oy toplamak olduğunu merak ediyorum. Çözüm yanlıştır (genel durumda) ve iki şekilde daha kısa Ruby çözümleri şu anda burada. - Joey