特定のテキストで最もよく使用される単語のASCIIチャートを作成する[終了]


156

挑戦:

特定のテキストで最も一般的に使用される単語のASCIIチャートを作成します。

ルール:

  • a-zおよびA-Z(アルファベット文字)のみを単語の一部として受け入れます。
  • 大文字と小文字を区別しません(She==ここsheでは目的)。
  • 次の単語は無視してください(かなり自由自在です)。 the, and, of, to, a, i, it, in, or, is
  • 明確化:考慮don't:これは、2つの異なる範囲の言葉」として取られるだろうa-zA-Z(:dont)。

  • 必要に応じて(正式に仕様を変更するのは遅すぎます)、1文字の「単語」をすべて削除することもできます(これにより、無視リストも短くなる可能性があります)。

与えられたものを解析しtext(コマンドライン引数で指定されたファイルまたはパイプで読み込まれたファイルを読み取り、presume us-asciiword frequency chart、次の特性を持つを構築します。

  • 最も頻度の高い22の単語(頻度の降順)のグラフを表示します(以下の例も参照)。
  • バーwidthは、単語の出現回数(頻度)を(比例的に)表します。スペースを1つ追加して、単語を印刷します。
  • これらのバー(およびスペース-ワード-スペース)が常にフィットすることを確認してください:bar+ [space]+ word+ [space]は常に<= 80文字でなければなりません(可能な異なるバーとワードの長さを考慮に入れてください:例:2番目に最も一般的なワードはそれよりずっと長い可能性があります最初の頻度はそれほど変わらない)。これらの制約内でバーの幅を最大化し、バーを適切にスケーリングします(バーが表す頻度に従って)。

例:

例のテキストはここにありますルイス・キャロルによる不思議の国のアリスの冒険)。

この特定のテキストは、次のチャートをもたらします:

 _________________________________________________________________________
| _________________________________________________________________________ | 彼女
| _______________________________________________________________ | 君は
| ____________________________________________________________ | 前記
| ____________________________________________________ | アリス
| ______________________________________________ | だった
| __________________________________________ | それ
| ___________________________________ | なので
| _______________________________ | 彼女
| ____________________________ | と
| ____________________________ | で
| ___________________________ | s
| ___________________________ | t
| _________________________ | オン
| _________________________ | すべて
| ______________________ | この
| ______________________ | ために
| ______________________ | 持っていました
| _____________________ | だが
| ____________________ | なる
| ____________________ | ない
| ___________________ | 彼ら
| __________________ | そう


参考までに:これらは、上記のチャートが基づいている頻度です:

[( 'she'、553)、( 'you'、481)、( 'said'、462)、( 'alice'、403)、( 'was'、358)、( 'that
'、330)、(' as '、274)、(' her '、248)、(' with '、227)、(' at '、227)、(' s '、219)、(' t '
、218)、( 'on'、204)、( 'all'、200)、( 'this'、181)、( 'for'、179)、( 'had'、178)、( '
しかし、 '、175)、(' be '、167)、(' not '、166)、(' they '、155)、(' so '、152)]

2番目の例(完全な仕様を実装したかどうかを確認するため):youリンクされたAlice in Wonderlandファイル内の すべてのを次のように置き換えますsuperlongstringstring

 ________________________________________________________________
| ________________________________________________________________ | 彼女
| _______________________________________________________ | スーパーロングストリング
| _____________________________________________________ | 前記
| ______________________________________________ | アリス
| ________________________________________ | だった
| _____________________________________ | それ
| ______________________________ | なので
| ___________________________ | 彼女
| _________________________ | と
| _________________________ | で
| ________________________ | s
| ________________________ | t
| ______________________ | オン
| _____________________ | すべて
| ___________________ | この
| ___________________ | ために
| ___________________ | 持っていました
| __________________ | だが
| _________________ | なる
| _________________ | ない
| ________________ | 彼ら
| ________________ | そう

勝者:

最短のソリューション(言語ごとの文字数による)。楽しんで!


編集:これまでの結果をまとめた表(2012-02-15)(ユーザーNas Banovが最初に追加):

言語リラックス厳格
========= ======= ======
GolfScript 130143
Perl 185
Windows PowerShell 148 199
Mathematica 199
ルビー185205
Unixツールチェーン194228
Python 183 243
Clojure 282
Scala 311
ハスケル333
Awk 336
R 298
Javascript 304 354
グルーヴィー321
Matlab 404
C#422
Smalltalk 386
PHP 450
F#452
TSQL 483 507

数値は、特定の言語での最短のソリューションの長さを表しています。「厳密」とは、仕様を完全に実装するソリューションを指し|____|ます(バーを描画し、最初のバーを線で閉じ、____頻度の高い長い単語の可能性を考慮します)。「リラックス」とは、いくつかの自由が解決まで短縮されたという意味です。

500文字未満のソリューションのみが含まれます。言語のリストは、「厳密な」ソリューションの長さによってソートされます。'Unix Toolchain'は、従来の* nixシェルに加えてツールの組み合わせ(grep、tr、sort、uniq、head、perl、awkなど)を使用するさまざまなソリューションを示すために使用されます。


4
さて、2番目に一般的な単語がはるかに長い単語である場合、「最長のバー」+ word = 80は80カラム内に収まらない可能性があります。私は推測する「最大制約」を探しています。
Brian

1
ケーシングを正規化しますか?「彼女」=「彼女」?
Brian

2
実行時間とメモリ使用量の両方の面でこれを実行するIMOは、文字数よりも興味深い課題のようです。
フランクファーマー

81
私は私の好きな言葉を見てくれてうれしいst表現されます。
個人2010

8
@ indiv、@ Nas Banov-愚かなあまりにも単純なトークナイザーは、「did n't」を{didn、t}として読み取り、「she's」を{she、s}として読み取ります:)
ホッブズ

回答:


123

LabVIEW 51ノード、5構造、10ダイアグラム

象にタップダンスを教えることは決して美しくありません。ああ、文字数をスキップします。

labVIEW code

results

プログラムは左から右に流れます:

labVIEW code explained


10
それは価値がない

4
LabVIEWは、ハードウェアの制御と測定のニッチで非常に満足していますが、文字列操作にはかなりひどいものです。
Joe Z

19
私が見た中で最高のコードゴルフの答え。ボックスの外側で考えるための+1!
ブレアホロウェイ2010

1
お奨めの要素をカウントしてください。画面にドラッグする必要があるすべてのボックスとウィジェットがカウントされます。
dmckee ---元モデレーターの子猫2010

1
それらのチャートのより大きなバージョンへのリンクを追加することは可能でしょうか?
Svish

42

Ruby 1.9、185文字

(主に他のRubyソリューションに基づいています)

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

他のソリューションのようにコマンドラインスイッチを使用する代わりに、単にファイル名を引数として渡すことができます。(つまりruby1.9 wordfrequency.rb Alice.txt

ここでは文字リテラルを使用しているため、このソリューションはRuby 1.9でのみ機能します。

編集:「読みやすさ」のためにセミコロンを改行に置き換えました。:P

編集2:Shtééfが末尾のスペースを忘れたと指摘しました-修正しました。

編集3:末尾のスペースを再度削除しました;)


各単語の後に、末尾のスペースがありません。
ステファンKochen

Awwシュート、それを無視して。ゴルフが更新されたばかりのようで、トレーリングスペースは不要になりました。:)
ステファンKochen

2番目以降の「superlongstringstring」に対応していないようですか?(問題の説明を参照)
Nas Banov

2
それは本当に保守可能に見えます。
ゾンビ

39

GolfScript、177 175 173 167 164 163 144 131 130文字

遅い-サンプルテキストの場合は3分(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*'| '@}/

説明:

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

「正しい」(うまくいけば)。(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*'| '@}/

遅い-30分。(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*'| '@}/

リビジョンログに表示される出力。


2
GolfScriptについて:golfscript.com/golfscript
Assaf Lavie

2
不正解です。2番目の単語が本当に長い場合、次の行に折り返されます。
Gabe

5
「ゼロで除算」... GolfScriptはそれを許可しますか?
JAB、2010

35

206

シェル、grep、tr、grep、sort、uniq、sort、head、perl

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

hm、上で見たところ:sort -nr-> sort -nそしてhead-> tail=> 208 :)
update2:ええと、もちろん上記はばかげています。したがって、
209。update3:除外正規化を最適化-> 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$_"'



楽しみのために、これはperlのみのバージョンです(はるかに高速です):

~ % 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セットベースのソリューション(SQL Server 2005)1063 892 873 853 827 820 783 683 647 644 630文字

文字数を減らすためのいくつかの有用な提案をしてくれたGabeに感謝します。

注意:スクロールバーを回避するために追加された改行は、最後の改行のみが必要です。

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 @

読み取り可能なバージョン

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 @

出力

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

そして長い紐で

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

12
T-SQLで行ったので、+ 1を与えました。チームアメリカを引用すると、「ボールがあります。ボールが好きです。」

私はいくつかのスペースを改行に自由に変換して読みやすくしました。うまくいけば、私は物事を台無しにしていない。もう少し小さくしました。
Gabe

3
そのコードは私に叫んでいます!:O
Joey

1
保存するための1つの良い方法は、0.000単に0に変更してから、の-C代わりに使用することです1.0/C。そして作るFLOATにはREALあまりにもストロークを保存します。ただし、最大のものは、ASオプションにする必要のあるインスタンスが多数あるように見えることです。
Gabe

1
OK、どう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

ルビー207 213 211 210 207の 203 201 200文字

rfuscaからの提案を組み込んだ、Anuragの改善。また、並べ替えの引数やその他のいくつかのマイナーなゴルフを削除します。

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

次として実行:

ruby GolfedWordFrequencies.rb < Alice.txt

編集: 'puts'を元に戻します。出力に引用符が含まれないようにする必要があります。
Edit2:変更されたファイル-> IO
Edit3:削除された/ i
Edit4:(f * 1.0)の周りの括弧が削除され
ました。sインプレースで展開します。
Edit6:mをfloatにし、1.0を削除。編集:機能せず、長さを変更します。編集:以前より悪くない
Edit7:を使用しSTDIN.readます。


+
1-

そもそも、その大部分を思いつくのに比べて、ちょっとした最適化です。:)
archgoon

いいね!Anuragのバージョンで行った2つの変更を追加しました。別4.オフ剃る
ステファンKochen

ソリューションが元の出力から逸脱しているので、それがどこで起こったのかを試してみます。
大砲

1
さらに下に、これの短いバリアントがあります。
大砲

28

Mathematica(297 284 248 244 242 199文字)Pure Functional

およびZipfの法則テスト

マンマを見て... vars、no手、..頭なし

編集1>いくつかの省略形を定義(284文字)

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]

いくつかの説明

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)

出力

代替テキストhttp://i49.tinypic.com/2n8mrer.jpg

Mathematicaはゴルフにはあまり適していませんが、それは関数名が長くてわかりやすいためです。「RegularExpression []」や「StringSplit []」のような関数は、私にすすり泣かせます:(。

Zipfの法則テスト

ジップの法則は、自然言語テキストのために、と予測しているログ(ランク)ログ(発生)プロットは、以下の線形関係を。

この法則は、暗号化とデータ圧縮のためのアルゴリズムの開発に使用されます。(ただし、LZWアルゴリズムの「Z」ではありません)。

私たちのテキストでは、次のようにテストできます

 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]

結果は(かなりよく線形です)

代替テキストhttp://i46.tinypic.com/33fcmdk.jpg

編集6>(242文字)

正規
表現のリファクタリング(選択機能なし)1文字の単語の削除
関数 "f"のより効率的な定義

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

7→199文字の編集

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]
  • 置き換えfTransposeし、Slot#1/ #2)の引数。
  • 臭いブラケットは必要ありません(可能な場合はf@x代わりに使用してくださいf[x]


9
あなたは「RegularExpression」が悪いと思いますか?Objective-Cコードが見つかるまで、「System.Text.RegularExpressions.Regex.Split」をC#バージョンに入力すると、「stringWithContentsOfFile」、「enumerateSubstringsInRange」、「NSStringEnumerationByWords」、「sortedArrayUsingComparator」などが表示されました。 。
Gabe

2
@Gabeありがとう...気分が良くなりました。スペイン語では「mal de muchos、consuelo de tontos」と言います..「多くの困った、愚か者は安心した」のようなもの:D
ベリサリウス博士10

1
|i|あなたが既に持っているので、あなたの正規表現では冗長です.|
Gabe

1
私はそのスペイン語の言葉が好きです。私が英語で考えることができる最も近いものは、「ミセリーは会社を愛する」です。私の翻訳の試みは次のとおりです。「苦しんでいるとき、同じ状況にいる他の人たちのことを考えて落ち着くのはばかです。」Mathematicaの実装に関する驚くべき作業です。
10

@dreeves愚かさは言語の壁を簡単に超えます...私の小さなMathematicaプログラムのようにあなたに会えてうれしいです、私はちょうど言語を学び始めています
Dr. belisarius

26

C#-510 451 436 446 434 426 422文字(縮小)

短くはありませんが、おそらく今は正しいです!以前のバージョンでは、バーの最初の行が表示されず、バーが正しくスケーリングされず、stdinから取得する代わりにファイルがダウンロードされ、必要なC#の詳細度がすべて含まれていませんでした。C#がそれほど余分ながらくたを必要としない場合、簡単に多くのストロークを剃ることができます。たぶん、Powershellの方がうまくいくでしょう。

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

以下の形式でlendivisorがインライン化された422文字(22倍遅くなります)(選択スペースに改行が使用されます):

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

スマート尻がファイルをインラインでダウンロードする場合は+1。:)
sarnold、2010

1
マットの回答から短いURLを盗みます。
個人

2
仕様によると、ファイルはパイプで渡すか、引数として渡す必要があります。args [0]にローカルファイル名が含まれていると想定する場合は、(new WebClient())。DownloadString(@ " gutenberg.org/files/11/11の代わりにargs [0]を使用することで、ファイル名を大幅に短縮できます。 txt ")->約70文字節約できます
トールキア

1
これは、WebClient呼び出しをargs 0に置き換え、StreamReaderを呼び出し、いくつかの余分なスペースを削除したバージョンです。合計文字数= 413 var a = Regex.Replace((new StreamReader(args [0]))。ReadToEnd()、 "[^ a-zA-Z]"、 "").ToLower()。Split( '' ).Where(x =>!(new [] {"the"、 "and"、 "of"、 "to"、 "a"、 "i"、 "it"、 "in"、 "or"、 " is "})。Contains(x))。GroupBy(x => x).Select(g => new {w = g.Key、c = g.Count()})。OrderByDescending(x => xc)です。 Skip(1).Take(22).ToList(); var m = a.OrderByDescending(x => xc).First(); a.ForEach(x => Console.WriteLine( "|" + new String( ' _ '、xc *(80-mwLength-4)/ mc)+ "|" + xw));
トールキア

「使用」なしの「新しいStreamReader」はダーティです。File.ReadAllText(args [0])またはConsole.In.ReadToEnd()の方がはるかに優れています。後者の場合、Main()から引数を削除することもできます。:)
Rotsor

25

Perl、237 229 209文字

(置き換え、より汚いゴルフトリックとRubyのバージョンを打つことを再度更新split/[^a-z/,lcしてlc=~/[a-z]+/g、別の場所に空の文字列のチェックを排除する。Rubyのバージョンに触発されたこれらの、クレジットので、クレジットが原因です。)

更新:Perl 5.10になりました!に置き換えprint、を回避するためにsay使用~~mapます。これは、コマンドラインでとして呼び出す必要がありますperl -E '<one-liner>' alice.txt。スクリプト全体が1行で記述されているため、1行で記述しても問題はありません。

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

このバージョンでは大文字と小文字が区別されることに注意してください。削除,lc(小文字の場合)を行うA-Zには分割正規表現に追加する必要があるため、これはソリューションを短くするものではありません。

改行が2文字ではなく1文字であるシステムを使用している場合は、の代わりにリテラル改行を使用することで、これをさらに2文字短縮できます\n。ただし、上記のサンプルは「より明確」(ha!)なので、そのように記述していません。


これはほとんど正しいが、十分に短いperlソリューションではありません。

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

以下は、比較的読みやすいままにできる限り短いものです。(392文字)。

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

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

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

現在、いくつかのバグがあります。固定と短縮。
JSBձոգչ2010

4
これは、2番目の単語が最初の単語よりはるかに長い場合をカバーしていませんよね?
Joey

1
両方ともforeachsと書くことができますfor。それは8文字です。次に、あなたが持っているgrep{!($_~~@s)}map{lc=~/[a-z]+/g}<>と私は書くことができたと考えていたが、 grep{!(/$_/i~~@s)}<>=~/[a-z]+/g4より下に行きます。交換する" "$"、あなたは1より...ダウンしている
ザイド

sort{$c{$b}-$c{$a}}...さらに2つを保存します。関数の%c代わりに渡すだけでkeys %csortさらに4つを保存することもできます。
mob 2010

20

Windows PowerShell、199文字

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

(最後の改行は必要ありませんが、読みやすくするためにここに含まれています。)

(現在のコードと私のSVNリポジトリで使用可能なテストファイル。テストケースで最も一般的なエラー(バーの長さ、正規表現の一致に関する問題、その他いくつかのエラー)が検出されることを願っています

仮定:

  • 入力としてのUS ASCII。おそらくUnicodeで奇妙になります。
  • テキストに少なくとも2つのノンストップワード

歴史

ゆるやかなバージョン(137)、それは今では別に数えられるので、どうやら:

($x=$input-split'\P{L}'-notmatch'^(the|and|of|to|.?|i[tns]|or)$'|group|sort *)[-1..-22]|%{"|$('_'*(76*$_.Count/$x[-1].Count))| "+$_.Name}
  • 最初のバーを閉じません
  • 最初以外の単語の語長を考慮しない

他のソリューションと比較した1文字のバーの長さのばらつきは、浮動小数点数を整数に変換するときに切り捨ての代わりに丸めを使用するPowerShellが原因です。ただし、タスクには比例バーの長さのみが必要なので、これで十分です。

他のソリューションと比較して、行が80文字を超えない最大の長さを試してみることによって、バーの最長の長さを決定する際に少し異なるアプローチをとりました。

説明されている古いバージョンはここにあります


印象的な、Powershellはゴルフに適した環境のようです。バーの長さを考慮したあなたのアプローチは、仕様で私が説明しようとしたものです(見事にではありませんが、認めます)。
ChristopheD

1
@ChristopheD:私の経験では(Anarchy Golf、Project Eulerのいくつかのタスク、およびそれを楽しむためのいくつかのタスク)、PowerShellは通常、Rubyよりもわずかに劣っており、PerlおよびPythonよりも優れています。ただし、GolfScriptには一致しません。しかし、私が見る限り、これはバーの長さを正しく説明する最も短いソリューションかもしれません;-)
Joey

どうやら私は正しかった。PowerShellはできもっと良い-非常に良いです!コメント付きの拡張バージョンを提供してください。
Gabe

ヨハネス:やってみました-split("\b(?:the|and|of|to|a|i[tns]?|or)\b|[^a-z]")か?わたしにはできる。
Gabe

出力文字列を補間することを忘れないでください"|$('_'*($w*$_.count/$x[0].count))| $($_.name) "(または、自動のように最後のスペースを削除します)。また-split("(?:\b(?:the|and|of|to|a|i[tns]?|or)\b|[^a-z])+")、空白を含めないことで(またはを使用して[-2..-23])、さらにいくつかを保存できます。
Gabe

19

Ruby、215、 216218221224236237の文字

更新1:ばんざーい!これはJS Bangsソリューションとのつながりです。これ以上削減する方法は考えられません:)

更新2:汚れたゴルフトリックをプレイしました。1文字を保存eachするmapように変更:)

更新3:+2に変更さFile.readれましたIO.read。+6 Array.group_byに変更されましたreducedowncase正規表現+1で大文字と小文字を区別した後、大文字と小文字を区別しないチェックは必要ありません。降順での並べ替えは、値+6を否定することで簡単に行えます。総節約+15

更新4:[0]ではなく.first、+ 3。(@Shtééf)

更新5:変数lをインプレースで展開し、+ 1。変数sをインプレースで拡張します。+ 2。(@Shtééf)

更新6:最初の行+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:インスタンス変数を使用して、ループの最初の反復を検出するためにたくさんのフープラを調べました。可能性はあるかもしれませんが、私が得たのは+1です。これは黒魔術だと思うので、以前のバージョンを保持します。(@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} "}

読みやすいバージョン

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

使用するには:

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

出力:

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

3
「p」は「puts」のショートカットではありませんか?それはいくつかを剃る可能性があります。
rfusca

1
いいね。scanただし、を使用すると、より良いアイデアが得られたので、また先に進みました:)。
JSBձոգչ2010

2
最長の単語とそのバーが80文字に収まるようにバーをスケーリングする必要があります。ブライアンが示唆したように、長い2番目の単語はプログラムを壊します。
Gabe

3
なぜこれがまだ票を集めているのかしら。ソリューションは(一般的なケースでは)正しくなく、双方向の短いRubyソリューションがここにあります。
ジョーイ

1
今、私が間違っている場合は修正してくださいが、「ダウンケース」を使用する代わりに、6〜7バイトを節約するREGEXPの大文字と小文字を区別しないフラグを使用してみませんか?
st0le

19

Python 2.x、ラテン系のアプローチ= 227 183文字

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

実装の自由を考慮して、除外(the, and, of, to, a, i, it, in, or, is)のために要求されたすべての単語を含む文字列連結を作成しました-さらに、2つの悪名高い "単語" st例からも除外しました-を無料で除外しましたan, for, he。アリス、ジェームズ王の聖書、およびJargonファイルからの単語のコーパスに対してこれらの単語をすべて連結して、文字列によって誤って除外される単語がないかどうかを確認しました。そして、それは私が2つの除外文字列で終わった方法です:itheandtoforinisandithetoforinis

PS。コードを短縮するために他のソリューションから借りました。

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

暴れる

無視する単語については、英語で最も使用されている単語のリストから取得されると考えられます。そのリストは、使用されるテキストコーパスによって異なります。最も人気のあるリストの1(パーhttp://en.wikipedia.org/wiki/Most_common_words_in_Englishhttp://www.english-for-students.com/Frequently-Used-Words.htmlのhttp:// WWW。 sporcle.com/games/common_english_words.php)、上位10ワードは次のとおりです。the be(am/are/is/was/were) to of and a in that have I

不思議の国のアリスのテキストの上位10語は the and to a of it she i you said
の上位10ワードは、用語集ファイル(v4.4.7)の上位10ワードです。the a of to and in is that or for

だから問題はなぜor問題の無視リストに含まれていたのかということです。that(8番目に使用頻度が高い)が含まれていないのに位までです。など、したがって、私は無視リストを動的に提供する必要があると思います(または省略できます)。

別のアイデアは、結果から上位10ワードを単にスキップすることです。これにより、実際にソリューションが短縮されます(基本-11番目から32番目のエントリのみを表示する必要があります)。


Pythonの2.xの、堅苦しいアプローチ= 277の 243文字

上記のコードで描かれたグラフは簡略化されています(棒に1文字のみを使用)。問題の説明からチャートを正確に再現したい場合(これは必須ではありませんでした)、このコードはそれを行います:

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

除外する10ワードのややランダムな選択に問題があるthe, and, of, to, a, i, it, in, or, isので、次のようにコマンドラインパラメーターとして渡されます。
python WordFrequencyChart.py the and of to a i it in or is <"Alice's Adventures in Wonderland.txt"

コマンドラインで渡された「元の」無視リストを考慮すると、これは213文字+ 30です= 243

PS。2番目のコードもすべての上位ワードの長さを「調整」するため、縮退した場合にオーバーフローすることはありません。

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

これまでのところ、「無視リスト」という単語は実装されておらず(現在)、バーは少し初歩的なものですが、素晴らしい解決策です。
ChristopheD

@ChristopheD:ありましたが、「ユーザーガイド」はありませんでした。束のテキストを追加しました
Nas Banov 2010

言語とソリューションのリストについて:分割に従って\W使用\bするか、正規表現で使用するソリューションを探してください。これらは仕様に従っていない可能性が高いため、数字で分割されないか_、文字列からストップワードが削除されない可能性がありますなどthe_foo_or123bar。それらはテストテキストに表示されない場合がありますが、その場合の仕様はかなり明確です。
Joey、

すばらしい仕事でした。私は午後にこれを最適化しようと試みましたが、改善点は1つだけでした。あなたは除去することによって、239個の文字にそれを減らすことができますsys.argvハックをして使用して:re.findall(r'\b(?!(?:the|and|.|of|to|i[tns]|or)\b)\w+',sys.stdin.read().lower())
intgr

12

ハスケル- 366の 351 344 337 333文字

main読みやすくするために改行が1つ追加されており、最後の行の終わりに改行は必要ありません。)

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

それがどのように機能するかは、interact逆方向の引数を読むことで最もよくわかります。

  • map f 英字を小文字にし、その他すべてをスペースに置き換えます。
  • words 単語のリストを作成し、分離空白を削除します。
  • filter (notElem words "the and of to a i it in or is")は、禁止された単語を含むすべてのエントリを破棄します。
  • group . sort 単語をソートし、同じものをリストにグループ化します。
  • map h 同一の単語の各リストをフォームのタプルにマップします (-frequency, word)
  • take 22 . sort タプルを頻度の降順(最初のタプルエントリ)で並べ替え、最初の22タプルのみを保持します。
  • b タプルをバーにマップします(以下を参照)。
  • a 一番下のバーを完成させるために、アンダースコアの最初の行を付加します。
  • unlines これらすべての行を改行で結合します。

難しいのは、バーの長さを正しくすることです。アンダースコアのみがバーの長さに対してカウントされると仮定したので||、バーの長さはゼロになります。関数がbマップさc xを超えるx場合には、xヒストグラムのリストです。リスト全体がに渡されるcため、を呼び出すたびに、を呼び出しcて自身のスケールファクタを計算できますu。このようにして、変換関数とインポートが多くの文字を消費する浮動小数点演算や有理数の使用を避けます。

を使用するトリックに注意してください-frequency。これにより、並べ替え(昇順)では頻度が最も高い単語が最初に配置さreverseれるsortため、必要性がなくなり-frequencyます。その後、関数でuで2つの-frequency値が乗算され、否定がキャンセルされます。


非常に良い仕事です(賛成票を投じますが、このスレッドでのすべての素晴らしい回答により、今日の投票はありませんでした)。
ChristopheD

これは、説明することさえ考えるのが面倒な方法で私の目を傷つけますが、私はそれを読みやすいコードにリバースエンジニアリングすることによって多くのHaskellを学びました。よくできました。:-)
オーウェンS.

実際には効率的ではありませんが、実際にはかなり慣用的なHaskellです。短い名前は実際よりもはるかに悪く見えます。
トーマス

@トーマス:もう一度言ってください。:-)
オーウェンS.

1
div実際には移動できません!試してみてください-出力が間違っています。その理由は、精度を失うdiv前に行うこと*です。
MtnViewMark 2010

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

残念ながら、for([k,v]in z)RhinoバージョンはSpiderMonkeyで動作したくないようです。readFile()、使用するよりも少し簡単ですreadline()が、1.8に移動すると、関数クロージャーを使用してさらに数行をカットできます...

読みやすくするために空白を追加する:

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

使用法: js golf.js < input.txt

出力:

 _________________________________________________________________________ 
| _________________________________________________________________________ | 彼女
| _______________________________________________________________ | 君は
| ____________________________________________________________ | 前記
| ____________________________________________________ | アリス
| ______________________________________________ | だった
| ___________________________________________ | それ
| ___________________________________ | なので
| ________________________________ | 彼女
| _____________________________ | で
| _____________________________ | と
| ____________________________ | s
| ____________________________ | t
| __________________________ | オン
| _________________________ | すべて
| _______________________ | この
| ______________________ | ために
| ______________________ | 持っていました
| ______________________ | だが
| _____________________ | なる
| _____________________ | ない
| ___________________ | 彼ら
| ___________________ | そう

(基本バージョン-バーの幅を正しく処理しません)

JavaScript(サイ)- 405 395 387 377 368 343 304文字

私のソートロジックはオフになっていると思いますが、..わかりません。 Brainfartを修正しました。

縮小(乱用\n;時々解釈される):

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

ああ、先生。私はこれがあなたのガントレットだと思います。2つ目は私のものに話してもらいます。
dmckee ---元モデレーターの子猫2010

2
ところで-私はi[tns]?ビットが好きです。とても卑劣です。
dmckee ---元モデレーターの子猫2010

@dmckee-よく演奏された、私はあなたの336に勝てるとは思わない、あなたの当然の賛成投票を楽しむ:)
Matt

あなたは間違いなく336を倒すことができます... 23文字のカットが利用可能です- .replace(/[^\w ]/g, e).split(/\s+/).map(置き換えて.replace(/\w+/g,、以前と同じ機能を使用できます.map...また、Rhinoがfunction(a,b)b.c-a.cソート機能の代わりにサポートされているかどうか(spidermonkeyがサポートしています)はわかりませんが、ひげをそる{return }... b.c-a.cは、それよりも優れたソートですa.c<b.c...これらの変更を加えた下部のSpidermonkeyバージョンの編集
gnarf

SpiderMonkeyのバージョンは、バーの幅の制約に準拠しているため、一番上に移動しました...また、否定的な先読み正規表現を使用して、単一のreplace()を許可する単語を拒否することにより、元のバージョンの文字をいくつか切り捨てました。それから?:仕事をするのに最適なベースでいくつかのifsをゴルフしました!
gnarf

11

PHP CLIバージョン(450文字)

この解決策は、ほとんどの純粋主義者が好都合に無視することを選択した最後の要件を考慮に入れています。170文字かかった!

使用法: php.exe <this.php> <file.txt>

縮小:

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

人間が読める:

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

?>

出力:

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

長い単語がある場合、バーは適切に調整されます。

|--------------------------------------------------------| 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を使用することは一種の不正行為だと思います:)約1週間前にそれについて読んだので、これがどのように機能するかを確認する絶好の機会でした。

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

プリントアウト:

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

コードの一部は、AKXのソリューションから「借用」されました。


最初の行がありません。そして、バーの長さが正しくありません。
ジョーイ

あなたのコードではopen('!')標準入力から読み取るようです-それはどのバージョン/ OSですか?または、ファイルに「!」という名前を付ける必要がありますか?
Nas Banov

ファイルに「!」という名前を付けます :)すみません、それはかなり不明確でした、そして私はそれを述べるべきでした。
Sam Dolan 2010

11

perl、205 191 189文字/ 205文字(完全に実装)

一部の部分は以前のperl / ruby​​の提出に触発されたものであり、いくつかの同様のアイデアが独立して到達したものと、他の部分はオリジナルのものです。短いバージョンには、他の提出物から見た/学んだいくつかのものが組み込まれています。

元の:

$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文字までの最新バージョン

/^(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文字までの最新バージョン:

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

このバージョン(205文字)では、後で見つかるよりも長い単語の行が考慮されます。

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

パール:203 202 201 198 195 208 231分の203文字

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

セカンダリワードが人気があり、80文字を超えるのに十分長い(この実装は231文字です)病理学的な場合の指定された動作(グローバルバースキッシン​​グ)を含む代替の完全な実装:

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

仕様には、これがSTDOUTに移動する必要があると記載されていなかったため、printではなくperlのwarn()を使用しました-4文字がそこに保存されました。foreachの代わりにマップを使用しましたが、split(join())でさらに節約できる可能性があるように感じます。それでも、それを203まで下げました-その上で寝るかもしれません。少なくともPerlは現在「shell、grep、tr、grep、sort、uniq、sort、head、perl」の文字数の下にあります;)

PS:Redditは「こんにちは」と言います;)

更新:代入と暗黙のスカラー変換結合を優先して、join()を削除しました。202まで。また、オプションの「1文字の単語を無視する」ルールを利用して2文字を削ったことにも注意してください。頻度のカウントにはこれが反映されることに注意してください。

更新2:$ /を強制終了するための割り当てと暗黙の結合を交換し、最初に<>を使用してファイルを一気に取得します。サイズは同じですが、よりかっこいいです。$(| $ y){}を$ y || {} &&に交換し、さらに1文字節約=> 201。

更新3:lcをマップブロックの外に移動して、小文字(lc <>)を早く制御できるようにしました-両方の正規表現をスワップアウトして、不要になった/ iオプションを使用しなくなりました。従来のperlgolfの明示的な条件付きx?y:z構成を入れ替えました|| 暗黙の条件付き構成-/^...$/ i ?1:$x { $ } ++ for /^...$/||$x{$ } ++ 3文字を保存しました!=> 198、200の障壁を破った。もうすぐ寝るかも…。

更新4:睡眠不足は私を正気にさせませんでした。上手。もっと気が狂ってる。これは通常のハッピーテキストファイルを解析するだけでよいと考え、nullにヒットした場合はあきらめました。2つの文字を保存しました。"長さ"を1文字短い(そしてもっとゴルフっぽい)y /// cに置き換えました-聞こえます、GolfScript ?? 私はあなたのために来ています!!!すすり泣く

更新5:Sleep depにより、22行の制限と後続の行の制限を忘れてしまいました。それらを処理した状態で208までバックアップします。悪くないですが、13文字で処理することは世界の終わりではありません。perlの正規表現のインラインevalをいじってみましたが、動作し文字保存するのに苦労しています...笑 現在の出力に一致するように例を更新しました。

更新6:(...)forを保護する不要な中括弧を削除しました。Chasからの入力に感謝します。Owens(私の疲れた脳を思い出させる)は、そこにキャラクタークラスi [tns]ソリューションを取得しました。203に戻ります。

更新7:2番目の作業、仕様の完全な実装を追加しました(病理学的な例のない元の仕様に基づいて、ほとんどの人が行っている切り捨ての代わりに、セカンダリロングワードの完全なバースキッシン​​グ動作を含む)

例:

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

病理学的事例の代替実装:

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

あなたは崩壊によってストップワードのための正規表現を短縮することが可能is|in|it|ii[snt]?-して、オプションのルールとの違いはもうありません。(うーん、Perlの人にRegex:Dを行う方法を教えることについて考えたことはありませんでした)–今だけ問題:私は自分のソリューションから3バイトをどのように削って、Perlよりも優れているかを確認する必要があります:-|
ジョーイ

さて、先ほど言ったことの一部は無視してください。1文字の単語を無視することは、実際にそれを行わないよりも1バイト短いです。
ジョーイ

すべてのバイトがカウントされます;)改行のトリックを実行することを検討しましたが、印刷可能な文字が少なくても、実際には同じバイト数であると考えました。さらに縮小できるかどうか確認する作業を続けています:)
Syntaera 2010

ええと、ケースの正規化によって209に戻りました。他に何をカットできるかわかりません。PowerShell Perlよりも短い場合があります。;-)
Joey

出力を上位22ワードに制限する場所も、長い2番目のワードが折り返されないようにする場所もわかりません。
Gabe

9

F#、452文字

正解:a単語数のペアのシーケンスを取得し、列あたりの最適な単語数の乗数を見つけて、k結果を出力します。

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

例(私はあなたとは異なるfreqカウントを持っていますが、理由はわかりません):

% 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

私自身の解決策は確かに少しずれていた(少し異なる仕様のため)、解決策は現在対応しています;-)
ChristopheD

これまでの唯一の正しいバースケーリング実装の+1
Rotsor

2
(@Rotsor:皮肉なことに、私のものは最も古い解決策です。)
Brian

split、map、filterステージをマージすることで、かなり短縮できると思います。また、それほど多くfloatのが必要ないことも期待します。
Gabe

ネスト関数は通常、パイプライン演算子を使用するよりも短くありません|>か?
ジョーイ

8

Python 2.6、347文字

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

出力:

 _________________________________________________________________________
|_________________________________________________________________________| 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を1回だけ使用しているため、行を失う可能性があります(次の行を作成し、U=lambda n:"_"*int(n*(76.-len(W[0][0]))/W[0][1])5文字を削ります。また、コードゴルフで2文字の変数名を使用するのはなぜですか?;-)
ChristopheD

最後の行では、印刷後のスペースは必要ありません。1文字
ChristopheD

1
2番目に多い単語が非常に長い場合を考慮しませんか?
ジョーイ

@ChristopheD:私がそのコードを見ているのが長すぎるためです。:P良いキャッチ。@ヨハネス:それも修正されるかもしれません、はい。私がこれを書いたときに、他のすべての実装がそれを行ったかどうかはわかりません。
AKX 2010

7

* sh(+カール)、部分

これは不完全ですが、地獄のために、問題の半分を192バイトで数える単語頻度は次のとおりです。

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

ガウク-336(元は507)文字

(出力のフォーマットを修正した後、縮小の問題を修正しました;微調整;再度微調整します;まったく不要なソート手順を削除します;もう一度微調整します;そしてもう一度(これはフォーマットを壊しました);さらに微調整します;マットの挑戦を取り上げます私は必死に微調整しましたそれ以上;いくつかを節約するために別の場所を見つけましたが、バーの長さのバグを修正するために2つを返しました)

へへへへ![Matt's JavaScript] [1]ソリューションカウンターチャレンジに 一歩先を行っています;)および [AKXのpython] [2]。

問題は、ネイティブの連想配列を実装する言語を呼び出すように思われるので、もちろん、その上ひどく欠けている演算子のセットを持つ言語を選択しました。特に、awkがハッシュマップの要素を提供する順序を制御することはできないため、繰り返し全体をスキャンします、現在最も多くのアイテムを見つけ、印刷して配列から削除します。

それはすべてひどく非効率的であり、私が作成したすべてのゴルフ場もかなりひどいものになっています。

縮小:

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

明確にするためだけに改行します。これらは必要ではないので、カウントしないでください。


出力:

$ 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

読みやすい; 633文字(元は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]
    }
}

いい仕事、インデント/コメント付きのバージョンを含めてよかった;-)
ChristopheD

7

一般的なLISP、670文字

私はLISPの初心者です。これは、カウントにハッシュテーブルを使用する試みです(おそらく最もコンパクトな方法ではありません)。

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

たとえばで実行できます cat alice.txt | clisp -C golf.lisp

読みやすい形で

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

カスタムリーダーマクロをインストールして、いくつかの入力サイズを削減しようとしましたか?
アーロン

@Aaronは、実際にこれを機能させるだけでも、それほど簡単ではありませんでした... :-)実際のゴルフのパートでは、1文字の変数を使用しただけで、それですべてです。とにかく、この問題の規模に対してCLに固有のいくぶん高い冗長性に加えて( "concatenate 'string"、 "setf"または "gethash"はキラーです... Pythonでは "+"、 "="、 "[]"です)それでも私はこれを論理的なレベルでさえ予想していたよりもずっと悪いと感じました。ある意味私はlispは大丈夫だと感じていますが、一般的なlispはまあまあであり、これはネーミングを超えています(CLでの経験がゼロに近いため、非常に不公平なコメントを読み直しています)。
6502

本当。スキームは、単一の名前空間でゴルフを少し簡単にします。あちこちに文字列を追加する代わりに、(letrec((a string-append)(b gethash))...(a "x" "yz")...)
Aaron

6

C(828)

難読化されたコードのように見え、文字列、リスト、ハッシュにglibを使用します。Char wc -m828とカウントします。単一文字の単語は考慮されません。バーの最大長を計算するために、最初の22だけでなく、すべての中で最も長い単語が考慮されます。これは仕様からの逸脱ですか?

障害を処理せず、使用済みメモリを解放しません。

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

改行は文字としてカウントされますが、プリプロセッサ命令ではない行から削除することができます。ゴルフの場合、私は記憶を解放することを悪い習慣と考えていません。
ステファンKochen

わかりました...すべてを1行に入れ(preprocマクロを期待)、memを解放せずにversを指定します(他の2つのスペースを削除します...)「難読化」を少し改善すると、たとえば*v=*v*(77-lw)/m929になります。 ..でも、もっと短くする方法を見つけなければ、大丈夫だと思います)
ShinTakezou

私はあなたが、少なくとも移動することができると思うint cmain宣言とmain暗黙的であるint(任意の型なし引数が私の知る限り、あるとして): main(c){...}。おそらくの0代わりに書くこともできNULLます。
ジョーイ

それを行う...もちろん、-Wallまたは-std=c99フラグをオンにしていくつかの警告をトリガーします...しかし、これはコードゴルフにとって無意味だと思いますよね?
真武蔵2010

uff、短いギャップの時間の編集は申し訳ありません...私はWithout freeing memory stuff, it reaches 866 (removed some other unuseful space)他の何かに変更して、フリーメモリバージョンとの違いがすべてであると人々に思わせないようにする必要があります:現在、非フリーメモリバージョンにはたくさんありますより多くの「改善」。
真武蔵2010

6

Perl、185文字

200(わずかに壊れている) 199 197 195 193 187 185文字。最後の2つの改行は重要です。仕様に準拠しています。

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

最初の行は有効な単語の数をロードします %Xます。

2行目は、すべての出力行が80文字以下になるように最小スケーリング係数を計算します。

3行目(2つの改行文字を含む)は出力を生成します。


これは、「foo_the_bar」などの文字列からストップワードを削除しません。行の長さも長すぎます(仕様を再確認してください:「バー+スペース+ワード+スペース <= 80文字」)
Joey

5

Java- 886 865 756 744 742 744 752 742 714 680文字

  • 最初の742以前の更新:正規表現の改善、余分なパラメーター化された型の削除、余分な空白の削除。

  • アップデート742> 744文字:固定長のハックを修正しました。それは最初の単語にのみ依存しており、他の単語には依存していません(まだ)。コードを短縮するためのいくつかの場所が見つかりました(\\s正規表現ではに置き換えられ 、にArrayList置き換えられましたVector)。Commons IOの依存関係を削除してstdinから読み取るための簡単な方法を探しています。

  • アップデート744> 752文字:コモンズの依存関係を削除しました。現在はstdinから読み取られます。stdinにテキストを貼り付け、ヒットCtrl+Zして結果を取得します。

  • 更新752> 742文字publicスペースを削除して、クラス名を2ではなく1文字にしたところ、1文字の単語が無視されるようになりました。

  • 更新742> 714の文字:カールのコメントに従って更新:除去冗長割り当て(742> 730)が、置換m.containsKey(k)によりm.get(k)!=null(> 728 730)、(> 714 728)ラインのsubstringing導入しました。

  • 714を更新> 680文字:Rotsorのコメントに従って更新:不要なキャストを削除するためにバーサイズの計算を改善split()し、不要を削除するために改善しました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);}}

より読みやすいバージョン:

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

出力:

 _________________________________________________________________________
| _________________________________________________________________________ | 彼女
| _______________________________________________________________ | 君は
| ____________________________________________________________ | 前記
| _____________________________________________________ | アリス
| _______________________________________________ | だった
| ___________________________________________ | それ
| ____________________________________ | なので
| ________________________________ | 彼女
| _____________________________ | と
| _____________________________ | で
| __________________________ | オン
| __________________________ | すべて
| _______________________ | この
| _______________________ | ために
| _______________________ | 持っていました
| _______________________ | だが
| ______________________ | なる
| _____________________ | ない
| ____________________ | 彼ら
| ____________________ | そう
| ___________________ | 非常に
| __________________ | 何

Javaには(まだ)クロージャString#join()ありません。

Rotsorによる編集:

ソリューションにいくつかの変更を加えました。

  • リストをString []に置き換えました
  • 独自の文字列配列を宣言する代わりに、「args」引数を再利用しました。.ToArray()の引数としても使用されます
  • StringBufferをStringに置き換えました(はい、はい、ひどいパフォーマンス)
  • Javaソートを早期停止の選択ソートに置き換えました(最初の22エレメントのみを見つける必要があります)
  • いくつかのint宣言を単一のステートメントに集約しました
  • 非チートアルゴリズムを実装して、最も限定的な出力ラインを見つけます。FPなしで実装しました。
  • テキストに含まれる単語が22個未満の場合にプログラムがクラッシュする問題を修正しました
  • 入力を読み取る新しいアルゴリズムを実装しました。高速で、遅いものよりも9文字だけ長くなります。

圧縮されたコードは、688 711 684文字です。

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

高速バージョン(720 693文字)

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

より読みやすいバージョン:

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

動作が改善されていないバージョンは615文字です。

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インポートする代わりに使用することはできませんか?私が見る限り、とにかく一度だけ使用しています。
ジョーイ

5
最長のバーが正確に75文字であると想定して、ごまかしのようなものです。bar + wordが80文字を超えないようにする必要があります。
Gabe

単語の後にスペースがありません。;)
st0le 2010

私は自分の答えを減らしていたので、私はBalusCの提出に勝つことを望んでいました。まだ200文字残っていますね Commons IOと75文字の仮定がない場合、これはどのくらいの期間になるのでしょうか。
Jonathon Faust

1
bStringBufferの代わりにStringを作成することで、一部の文字を剃ることができるように見えます。ただし、パフォーマンスがどうなるかは考えたくありません(特に、一度に1文字ずつ追加するため)。
マイケルマイヤーズ

4

Scala 2.8、311 314 320 330 332 336 341 375文字

長い単語の調整を含みます。他のソリューションから借りたアイデア。

スクリプトとして(a.scala):

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

で実行

scala -howtorun:script a.scala alice.txt

ところで、314から311文字の編集では、実際には1文字しか削除されません。以前に誰かがカウントを間違っていました(Windows CR?)。


4

Clojure 282 strict

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

やや読みやすい:

(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文字

まず、592文字の判読可能なバージョン:

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

コンソール出力は次のようになります。

$ 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

積極的な縮小を行って、415文字まで減らすことができます。

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

コンソールセッションは次のようになります。

$ 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

Scalaのエキスパートがもっと上手くできると私は確信しています。

更新:コメントで、トーマスはさらに短いバージョンを368文字で提供しました:

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

読みやすく、375文字:

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文字: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

もちろん、理解するのにこれまでにない重宝です!いいね!
pr1001 2010

3

Java-896文字

931文字

1233文字が読めなくなった

1977文字 "非圧縮"


更新:文字数を積極的に減らしました。更新された仕様ごとに1文字の単語を省略します。

C#とLINQはとてもうらやましいです。

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

「読み取り可能」:

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

アリスの出力:

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

Don Quixoteの出力(Gutenbergからも):

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

8
完全に鯉、Javaで短くする方法は本当にありませんか?機能ではなく文字数で支払いを受けてもらいたいです:-)
Nas Banov
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.