特定のテキストで最もよく使用される単語のASCIIチャートを作成します。
ルール:
a-z
およびA-Z
(アルファベット文字)のみを受け入れます。She
== she
)。the, and, of, to, a, i, it, in, or, is
明確化:don't
:を考慮すると、これはa-z
およびA-Z
:(don
およびt
)の範囲の2つの異なる「単語」と見なされます。
オプションで(現在仕様を正式に変更するには遅すぎます)あなたmayすべての1文字の「単語」を削除することを選択します(これにより、無視リストも短縮される可能性があります)。
与えられたtext
を解析し(コマンドライン引数で指定されたファイルを読み込むか、パイプで接続されます; us-ascii
と仮定)、次の特性を持つWord frequency chart
を構築します:
width
は、Wordの出現回数(頻度)を(比例的に)表します。スペースを1つ追加して、Wordを印刷します。bar
+ [space]
+ Word
+ [space]
は常に<= 80
文字(可能なバーとワードの長さの違いを考慮してください:例:2番目に一般的なWordは、頻度がそれほど変わらず、最初のワードよりもずっと長くなる可能性があります)。 最大化これらの制約内のバーの幅とバーが適切にスケーリングする(それらが表す頻度に応じて)。例:
例のテキスト ここにあります (不思議の国のアリスの冒険、ルイス・キャロルによる)。
この特定のテキストは、次のチャートを生成します。
_________________________________________________________________________ | _________________________________________________________________________ |彼女 | _______________________________________________________________ |あなた | ____________________________________________________________________________ |言った | ____________________________________________________ |アリス | ______________________________________________ | | __________________________________________ | | ___________________________________ | | _______________________________ |として彼女 | ____________________________ | | ____________________________ |と | ___________________________ |で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 )、( ' but'、175)、( 'be'、167)、( 'not'、166)、( 'they'、155)、( 'so'、152)]
2番目の例(完全な仕様を実装したかどうかを確認するため):リンクされたAlice inのyou
のすべての出現を置き換えますワンダーランドsuperlongstringstring
のファイル:
________________________________________________________________ | ________________________________________________________________________________ |彼女 | _______________________________________________________ || superlongstringstring | _____________________________________________________ |言った | ______________________________________________ |アリス | ________________________________________ | | _____________________________________ | | ______________________________ | | ______________________________ |として彼女 | _________________________ | | _________________________ | | ________________________ |でs | ________________________ | t | ______________________ | | ________________________ |すべて | ___________________ |この | ___________________ | | ___________________ |持っていた | __________________ |しかし | _________________ | | _________________ | | ________________ |ではありません彼ら | ________________ |そう
勝者:
最短のソリューション(言語ごとの文字数による)。楽しむ!
Edit:これまでの結果をまとめた表(2012-02-15)(元々ユーザーNas Banovによって追加された):
Language Relaxed Strict ========= ======= ====== GolfScript 130 143 Perl 185 Windows PowerShell 148 199 Mathematica 199 Ruby 185 205 Unixツールチェーン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
数字は、特定の言語での最短ソリューションの長さを表します。 「厳密」とは、仕様を完全に実装するソリューションを指します(|____|
バーを描画し、最初のバーを____
行で閉じ、高頻度の長い単語の可能性を考慮します)。 「緩和」とは、ソリューションに短縮するためにいくつかの自由が取られたことを意味します。
500文字より短いソリューションのみが含まれます。言語のリストは、「厳密な」ソリューションの長さでソートされます。 「Unix Toolchain」は、従来の* nix Shell plusツールの組み合わせ(grep、tr、sort、uniq、head、Perl、awkなど)を使用するさまざまなソリューションを示すために使用されます。
(他の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:シュテフは、私が末尾のスペースを忘れてしまったことを指摘した-それを修正した。
編集3:末尾のスペースを再び削除しました;)
遅い-サンプルテキストで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*'| '@}/
リビジョンログに表示される出力。
文字数を減らすための便利な提案をしてくれた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
~ % 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
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
編集:「プット」を戻します。出力に引用符が含まれないようにする必要があります。
Edit2:変更されたファイル-> IO
Edit3:削除された/ i
Edit4:括弧を削除(f * 1.0)、再集計
Edit5:最初の行に文字列の追加を使用します。 s
をインプレース展開します。
Edit6:m floatを作成、1.0を削除。編集:機能しません、長さを変更します。編集:以前より悪くない
Edit7:STDIN.read
を使用します。
マンマを見て... vars、no hands、no .. no head
編集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)
出力
alt text http://i49.tinypic.com/2n8mrer.jpg
Mathematicaはゴルフにはあまり適していませんが、それは単に関数名が長くて説明的だからです。 「RegularExpression []」や「StringSplit []」などの関数は、私をすすり泣かせます:(。
Zipfの法則 は、自然言語テキストの場合、Log(Rank)vsLog(発生)プロットはlinearの関係に従います。
この法律は、暗号化とデータ圧縮のためのアルゴリズムの開発に使用されます。 (ただし、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
正規表現のリファクタリング(選択機能はもうありません)
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]
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]
f
をTranspose
およびSlot
(#1
/#2
)引数。f@x
の代わりに f[x]
可能であれば)それほど短くはありませんが、今ではおそらく正しいでしょう!以前のバージョンでは、バーの最初の行が表示されず、バーが正しくスケーリングされず、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));}}
(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文字のシステムを使用している場合は、\n
の代わりにリテラル改行を使用して、これをさらに2文字短くすることができます。ただし、この方法は「より明確」(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;
$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リポジトリ内 。私のテストケースが最も一般的なエラー(バーの長さ、正規表現のマッチングの問題など)をキャッチすることを望みます)
仮定:
緩和されたバージョン(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文字を超える行がない最大長を試すだけで、バーの最大長を決定する際に少し異なるアプローチを使用しました。
説明されている古いバージョンは here にあります。
更新1:万歳! JS Bangs ' solution との結びつきです。これ以上削減する方法を考えることはできません:)
更新2:汚いゴルフトリックをしました。 each
をmap
に変更して1文字保存しました:)
更新3:変更File.read
からIO.read
+2。 Array.group_by
はあまり実りませんでしたが、reduce
+6に変更されました。正規表現+1でdowncase
を使用して小文字を変換した後、大文字と小文字を区別しないチェックは不要です。降順でのソートは、値+6を否定することで簡単に行えます。総貯蓄+15
更新4:[0]
のではなく .first
、+ 3。 (@Shtééf)
更新5:変数l
インプレース、+ 1を展開します。変数s
in-place、+ 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} "}
update 7:インスタンス変数を使用して、ループの最初の反復insideを検出するために、たくさんのhooplaを実行しました。おそらく潜在的な可能性はありますが、私が得たのは+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
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つの悪名高い「単語」s
とt
も除外しました。 an, for, he
の除外を無料でスローしました。アリス、キングジェームズの聖書、ジャーゴンファイルからの単語のコーパスに対してこれらの単語をすべて連結し、文字列によって誤って除外される単語があるかどうかを確認しました。それが、2つの除外文字列itheandtoforinis
とandithetoforinis
で終わる方法です。
PS。コードを短縮するために他のソリューションから借りました。
=========================================================================== she
================================================================= you
============================================================== said
====================================================== alice
================================================ was
============================================ that
===================================== as
================================= her
============================== at
============================== with
=========================== on
=========================== all
======================== this
======================== had
======================= but
====================== be
====================== not
===================== they
==================== so
=================== very
=================== what
================= little
無視する単語に関して、それらは英語で最も使用される単語のリストから取られると思うでしょう。そのリストは、使用される text corpus に依存します。最も人気のあるリストの1つ( http://en.wikipedia.org/wiki/Most_common_words_in_English 、 http://www.english-for-students.com/Frequently-Used -Words.html 、 http://www.sporcle.com/games/common_english_words.php )、上位10語は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
です
専門用語ファイル(v4.4.7)の上位10ワードはthe a of to and in is that or for
です
質問は、なぜor
が問題の無視リストに含まれていたのかということです。Wordthat
(8番目に使用頻度の高い)が含まれていない場合、人気は30番目です。などなど。したがって、無視リストは動的に提供する必要があります(または省略できます)。
代替案は、結果から上位10語を単にスキップすることです。これにより、実際にはソリューションが短縮されます(基本-11番目から32番目のエントリのみを表示する必要があります)。
上記のコードで描かれたチャートは単純化されています(バーに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
the, and, of, to, a, i, it, in, or, is
を除外するために、10個の単語をいくぶんランダムに選択すると問題が発生するため、コマンドラインパラメーターとして渡す必要があります。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
(読みやすさのために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 (
notElemwords "the and of to a i it in or is")
は、禁止された単語を含むすべてのエントリを破棄します。group . sort
は単語をソートし、同一の単語をリストにグループ化します。map h
は、同一の単語の各リストを(-frequency, Word)
形式のタプルにマップします。take 22 . sort
は、頻度の降順(最初のTupleエントリー)でタプルをソートし、最初の22個のタプルのみを保持します。b
は、タプルをバーにマップします(以下を参照)。a
は、アンダースコアの最初の行を先頭に追加して、一番上のバーを完成させます。unlines
は、これらすべての行を改行で結合します。難しいのは、バーの長さを正しくすることです。アンダースコアのみがバーの長さにカウントされるため、||
は長さゼロのバーになると想定しました。関数b
は、x
を介してc x
をマップします。ここで、x
はヒストグラムのリストです。リスト全体がc
に渡されるため、c
を呼び出すたびに、u
を呼び出すことで、それ自体のスケール係数を計算できます。このようにして、変換関数とインポートが多くの文字を消費する浮動小数点演算または有理数の使用を避けます。
-frequency
を使用するコツに注意してください。これにより、reverse
sort
が不要になります。並べ替え(昇順)-frequency
は、最も頻度の高い単語を最初に配置するためです。後で、関数u
で、2つの-frequency
値が乗算され、否定がキャンセルされます。
このソリューションでは、ほとんどの純粋主義者が無視することを都合よく選択した最後の要件を考慮します。 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
長いWordがある場合、バーは適切に調整されます。
|--------------------------------------------------------| she
|---------------------------------------------------| thisisareallylongwordhere
|-------------------------------------------------| you
|-----------------------------------------------| said
|-----------------------------------------| alice
|------------------------------------| was
|---------------------------------| that
|---------------------------| as
|-------------------------| her
|-----------------------| with
|-----------------------| at
|--------------------| on
|--------------------| all
|------------------| this
|------------------| for
|------------------| had
|-----------------| but
|-----------------| be
|----------------| not
|---------------| they
|---------------| so
|--------------| very
_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)}
_
悲しいことに、Rhinoバージョンのfor([k,v]in z)
は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
_
出力:
_________________________________________________________________________ | _________________________________________________________________________ ||彼女 | _______________________________________________________________ |あなた | ____________________________________________________________________________ |言った | ____________________________________________________ |アリス | ______________________________________________ | was | ___________________________________________ || that | ___________________________________ | as | ________________________________ |彼女 | _____________________________ | at | _____________________________ | with | ____________________________ | s | ____________________________ | t | __________________________ | on | _________________________ |すべて | _______________________ | this | ______________________ | for | ______________________ | had | ______________________ |しかし | _____________________ | be | _____________________ | not | ___________________ |彼ら | ___________________ |そう
(基本バージョン-バーの幅を正しく処理しません)
ソートロジックはオフになっていると思いますが、.. 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)}
_
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のソリューションから「借用」されました。
いくつかの部分は、以前の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]
$/=\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]
セカンダリWordが一般的であり、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に行かなければならないという記述はありませんでしたので、印刷の代わりにPerlのwarn()を使用しました-4文字が保存されています。 foreachの代わりにmapを使用しましたが、split(join())でさらに節約できると思います。それでも、それを203まで下げました-それで寝るかもしれません。少なくともPerlは、今のところ「シェル、grep、tr、grep、sort、uniq、sort、head、Perl」の文字カウントの下にあります;)
PS:Redditは「こんにちは」と言います;)
更新:割り当てと暗黙的なスカラー変換結合を支持して、join()を削除しました。 202まで。また、オプションの「1文字の単語を無視する」ルールを利用して2文字を削るので、頻度カウントがこれを反映することに注意してください。
更新2:割り当てをスワップアウトし、最初に<>を使用して1つのグループにファイルを取得するために$ /を削除するための暗黙的な結合。同じサイズですが、より厄介です。 if(!$ 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 ??私はあなたのために来ています!!! sob
更新5:スリープの深さにより、22行の制限とそれに続く行の制限を忘れました。それらを処理して208までバックアップします。悪くない、それを処理する13文字は世界の終わりではありません。 Perlの正規表現インラインevalをいじりましたが、との両方の文字を保存するのに問題があります...現在の出力と一致するように例を更新しました。
更新6:構文キャンディー++が幸福にそれを突き出すことができるので、(...)を保護する不要なブレースを削除しました。 Chasからの入力に感謝します。 Owens(私の疲れた脳を思い出させる)は、そこにキャラクタークラスi [tns]ソリューションを取得しました。 203に戻ります。
更新7:2番目の作業、仕様の完全な実装を追加(病理学的事例のない元の仕様に基づいて、ほとんどの人が行っている切り捨ての代わりに、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
Strightforward:単語カウントペアのシーケンス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
例(私はあなたとは異なる周波数カウントを持っていますが、理由はわかりません):
% 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
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
(出力フォーマットを修正した後、縮約物を修正した後、微調整し、再度調整し、完全に不要なソート手順を削除し、さらに微調整し、再度(これによりフォーマットが壊れました);いくつかの微調整もっと;マットの挑戦を引き受ける私は必死に微調整します;いくつかを保存する別の場所を見つけましたが、バーの長さのバグを修正するために2つを返しました)
Heh heh!私は[MattのJavaScript] [1]ソリューションの先を行っていますカウンターチャレンジ! ;) and[AKXのpython] [2]。
問題は、ネイティブ連想配列を実装する言語を呼び出すようですので、もちろん私はそれらに恐ろしく不十分な演算子のセットを持つものを選択しました。特に、awkがハッシュマップの要素を提供する順序を制御できないため、wholeマップを繰り返しスキャンして、現在最も多くの多数のアイテムを印刷し、配列から削除します。
それはすべて非常に非効率的であり、私が作ったすべてのゴルフは非常にひどいものになりました。
縮小:
{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]
}
}
これは不完全ですが、それについては、Word頻度が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
私は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)))))
200(わずかに破損)199197195193187 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つの改行文字を含む)が出力を生成します。
難読化されたコードによく似ており、文字列、リスト、ハッシュにglibを使用します。 wc -m
の文字数は828と言います。単一文字の単語は考慮されません。バーの最大長を計算するには、最初の22だけでなく、すべての中で可能な限り長いWordを考慮します。これは仕様からの逸脱ですか?
障害を処理せず、使用済みメモリを解放しません。
#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);}
最初の742より前の更新:正規表現の改善、余分なパラメーター化された型の削除、余分な空白の削除。
742> 744文字を更新:固定長のハックを修正しました。他の単語ではなく、1番目の単語にのみ依存しています(まだ)。コードを短縮する場所をいくつか見つけました(正規表現の\\s
はArrayList
でVector
に置き換えられています)。現在、Commons IO依存関係を削除し、stdinから読み取るための簡単な方法を探しています。
更新744> 752文字:コモンズの依存関係を削除しました。現在はstdinから読み取ります。テキストを標準入力に貼り付け、Ctrl+Z
を押して結果を取得します。
更新752> 742文字:public
とスペースを削除し、クラス名を2ではなく1文字にし、1文字の単語を無視しました。
742> 714文字の更新:Carlのコメントに従って更新:冗長な割り当てを削除(742> 730)、m.containsKey(k)
をm.get(k)!=null
(730> 728)、行のサブストリング化(728> 714)が導入されました。
更新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);
}
}
出力:
_________________________________________________________________________ | _________________________________________________________________________ |彼女 | _______________________________________________________________ |あなた | ____________________________________________________________________________ |言った | _____________________________________________________ |アリス | _______________________________________________ || was | ___________________________________________ || that | ____________________________________ | as | ________________________________ |彼女 | _____________________________ | with | _____________________________ | at | __________________________ | on | __________________________ |すべて | _______________________ | this | _______________________ | for | _______________________ | had | _______________________ |しかし | ______________________ | be | _____________________ | not | ____________________ |彼ら | ____________________ | so | ___________________ | very | __________________ |何
JavaにはString#join()
と closures (まだ)がありません。
ローターによる編集:
ソリューションにいくつかの変更を加えました。
圧縮コードはです688711 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);}}}
まず、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)
}
}
長い単語の調整を含む。他のソリューションから借りたアイデア。
スクリプトとして(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?)。
(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)))
私はC++を使用して高得点を獲得することを期待していませんが、決して気にしません。すべての要件を満たしていると確信しています。変数の宣言にC++ 0x auto
キーワードを使用したため、コードをテストすることにした場合は、コンパイラーを適切に調整してください。
最小バージョン
#include <iostream>
#include <cstring>
#include <map>
using namespace std;
#define C string
#define S(x)v=F/a,cout<<#x<<C(v,'_')
#define F t->first
#define G t->second
#define O &&F!=
#define L for(i=22;i-->0;--t)
int main(){map<C,int>f;char d[230];int i=1,v;for(;i<256;i++)d[i<123?i-1:i-27]=i;d[229]=0;char w[99];while(cin>>w){for(i=0;w[i];i++)w[i]=tolower(w[i]);char*p=strtok(w,d);while(p)++f[p],p=strtok(0,d);}multimap<int,C>c;for(auto t=f.end();--t!=f.begin();)if(F!="the"O"and"O"of"O"to"O"a"O"i"O"it"O"in"O"or"O"is")c.insert(pair<int,C>(G,F));auto t=--c.end();float a=0,A;L A=F/(76.0-G.length()),a=a>A?a:A;t=--c.end();S( );L S(\n|)<<"| "<<G;}
char[]
およびstring
ではなく、strtok
を使用することにより、より「C++」である2番目のバージョンがあります。 669(+22 vs上記)で少し大きくなっていますが、現時点では小さくすることができないので、とにかく投稿すると思いました。
#include <iostream>
#include <map>
using namespace std;
#define C string
#define S(x)v=F/a,cout<<#x<<C(v,'_')
#define F t->first
#define G t->second
#define O &&F!=
#define L for(i=22;i-->0;--t)
#define E e=w.find_first_of(d,g);g=w.find_first_not_of(d,e);
int main(){map<C,int>f;int i,v;C w,x,d="abcdefghijklmnopqrstuvwxyz";while(cin>>w){for(i=w.size();i-->0;)w[i]=tolower(w[i]);unsigned g=0,E while(g-e>0){x=w.substr(e,g-e),++f[x],E}}multimap<int,C>c;for(auto t=f.end();--t!=f.begin();)if(F!="the"O"and"O"of"O"to"O"a"O"i"O"it"O"in"O"or"O"is")c.insert(pair<int,C>(G,F));auto t=--c.end();float a=0,A;L A=F/(76.0-G.length()),a=a>A?a:A;t=--c.end();S( );L S(\n|)<<"| "<<G;}
フルバージョンを削除しました。これは、最小化バージョンへの微調整で更新を続けることに煩わされることがないためです。 (おそらく古い)ロングバージョンに興味がある場合は、編集履歴を参照してください。
更新:文字数を積極的に減らしました。更新された仕様ごとに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
この質問に完全に準拠している場合、これを信じています。リストを無視して、行の長さを完全にチェックします(テキストを5番目の項目を最も長い行にするAlice
をAliceinwonderlandbylewiscarroll
に置き換えた例を参照してください。 (ハードコーディングすると約10文字を削除します。)1つの欠点があります(ただし、質問には問題ないと思います)。整数除算器を計算して行を80文字より短くし、最長行を80文字より短く、正確に80 python 3.xバージョンには、この欠陥はありません(ただし、もっと長いです)。
また、読むことはそれほど難しくないと思います。
import sys,re
t=re.split("\W+(?:(?:the|and|o[fr]|to|a|i[tns]?)\W+)*",sys.stdin.read().lower())
b=sorted((-t.count(x),x)for x in set(t))[:22]
for l,w in b:print"|"+l/min(z/(78-len(e))for z,e in b)*'-'+"|",w
|----------------------------------------------------------------| she
|--------------------------------------------------------| you
|-----------------------------------------------------| said
|----------------------------------------------| aliceinwonderlandbylewiscarroll
|-----------------------------------------| was
|--------------------------------------| that
|-------------------------------| as
|----------------------------| her
|--------------------------| at
|--------------------------| with
|-------------------------| s
|-------------------------| t
|-----------------------| on
|-----------------------| all
|---------------------| this
|--------------------| for
|--------------------| had
|--------------------| but
|-------------------| be
|-------------------| not
|------------------| they
|-----------------| so
(サンプル出力のように)行に最大バーのみを印刷する必要があるかどうかは明らかではないためです。以下は別の方法ですが、232文字です。
import sys,re
t=re.split("\W+(?:(?:the|and|o[fr]|to|a|i[tns]?)\W+)*",sys.stdin.read().lower())
b=sorted((-t.count(x),x)for x in set(t))[:22]
f=min(z/(78-len(e))for z,e in b)
print"",b[0][0]/f*'-'
for y,w in b:print"|"+y/f*'-'+"|",w
python 3.xのCounterクラスを使用すると、(ここで必要なことはCounterがすべて行うので)短くすることを強く期待していました。 :
import sys,re,collections as c
b=c.Counter(re.split("\W+(?:(?:the|and|o[fr]|to|a|i[tns]?)\W+)*",
sys.stdin.read().lower())).most_common(22)
F=lambda p,x,w:print(p+'-'*int(x/max(z/(77.-len(e))for e,z in b))+w)
F(" ",b[0][1],"")
for w,y in b:F("|",y,"| "+w)
問題は、collections
とmost_common
は非常に長い単語であり、Counter
でさえ短くありません...実際、Counter
を使用しないと、コードは2文字だけ長くなります;-(
python 3.xは他の制約も導入します:2つの整数を分割することはもはや整数ではなく(したがってintにキャストする必要があります)、印刷は関数になります(括弧を追加する必要があります)などです。 python2.xバージョンですが、ずっと高速です。おそらくもっと実験されたpython 3.xコーダーはコードを短くするアイデアを持っているでしょう。
b=map.get(a)
をb=map[a]
に置き換え、splitをマッチャー/イテレーターに置き換えました
def r,s,m=[:],n=0;def p={println it};def w={"_".multiply it};(new URL(this.args[0]).text.toLowerCase()=~/\b\w+\b/).each{s=it;if(!(s==~/(the|and|of|to|a|i[tns]?|or)/))m[s]=m[s]==null?1:m[s]+1};m.keySet().sort{a,b->m[b]<=>m[a]}.subList(0,22).each{k->if(n++<1){r=(m[k]/(76-k.length()));p" "+w(m[k]/r)};p"|"+w(m[k]/r)+"|"+k}
(URLをcmd行引数としてgroovyスクリプトとして実行します。インポートは不要です!)
ここで読みやすいバージョン:
def r,s,m=[:],n=0;
def p={println it};
def w={"_".multiply it};
(new URL(this.args[0]).text.toLowerCase()
=~ /\b\w+\b/
).each{
s=it;
if (!(s ==~/(the|and|of|to|a|i[tns]?|or)/))
m[s] = m[s] == null ? 1 : m[s] + 1
};
m.keySet()
.sort{
a,b -> m[b] <=> m[a]
}
.subList(0,22).each{
k ->
if( n++ < 1 ){
r=(m[k]/(76-k.length()));
p " " + w(m[k]/r)
};
p "|" + w(m[k]/r) + "|" + k
}
夜遅くまでできる限り慣用的なClojureでコードを書いてみました。私はdraw-chart
関数、しかし、コードはClojureの簡潔さのボリュームを話すと思います。
(ns Word-freq
(:require [clojure.contrib.io :as io]))
(defn Word-freq
[f]
(take 22 (->> f
io/read-lines ;;; Slurp should work too, but I love map/red
(mapcat (fn [l] (map #(.toLowerCase %) (re-seq #"\w+" l))))
(remove #{"the" "and" "of" "to" "a" "i" "it" "in" "or" "is"})
(reduce #(assoc %1 %2 (inc (%1 %2 0))) {})
(sort-by (comp - val)))))
(defn draw-chart
[fs]
(let [[[w f] & _] fs]
(apply str
(interpose \newline
(map (fn [[k v]] (apply str (concat "|" (repeat (int (* (- 76 (count w)) (/ v f 1))) "_") "| " k " ")) ) fs)))))
;;; (println (draw-chart (Word-freq "/Users/ghoseb/Desktop/alice.txt")))
出力:
|_________________________________________________________________________| she
|_______________________________________________________________| you
|____________________________________________________________| said
|____________________________________________________| alice
|_______________________________________________| was
|___________________________________________| that
|____________________________________| as
|________________________________| her
|_____________________________| with
|_____________________________| at
|____________________________| t
|____________________________| s
|__________________________| on
|__________________________| all
|_______________________| for
|_______________________| had
|_______________________| this
|_______________________| but
|______________________| be
|_____________________| not
|____________________| they
|____________________| so
私は知っていますが、これは仕様に従っていませんが、ちょっと、これは非常にきれいなClojureコードで、すでにとても小さいです:)
[〜#〜] matlab [〜#〜] 335 404410バイト357バイト。390バイト。
更新されたコードは404ではなく335文字になり、両方の例でうまくいくようです。
元のメッセージ(404文字のコードの場合)
このバージョンは少し長くなりますが、ただし、とんでもないほど長いWordがある場合、バーの長さを適切にスケーリングします。列は80を超えます。
したがって、私のコードは再スケーリングなしで357バイト、再スケーリングで410バイトです。
A=textscan(fopen('11.txt'),'%s','delimiter',' 0123456789,.!?-_*^:;=+\\/(){}[]@&#$%~`|"''');
s=lower(A{1});s(cellfun('length', s)<2)=[];s(ismember(s,{'the','and','of','to','it','in','or','is'}))=[];
[w,~,i]=unique(s);N=hist(i,max(i)); [j,k]=sort(N,'descend'); b=k(1:22); n=cellfun('length',w(b));
q=80*N(b)'/N(k(1))+n; q=floor(q*78/max(q)-n); for i=1:22, fprintf('%s| %s\n',repmat('_',1,l(i)),w{k(i)});end
結果:
___________________________________________________________________________| she
_________________________________________________________________| you
______________________________________________________________| said
_______________________________________________________| alice
________________________________________________| was
____________________________________________| that
_____________________________________| as
_________________________________| her
______________________________| at
______________________________| with
____________________________| on
___________________________| all
_________________________| this
________________________| for
________________________| had
________________________| but
_______________________| be
_______________________| not
_____________________| they
____________________| so
___________________| very
___________________| what
たとえば、不思議の国のアリステキストの「あなた」のすべてのインスタンスを「superlongstringofridiculousness」に置き換えると、私のコードは結果を正しくスケーリングします。
____________________________________________________________________| she
_________________________________________________________| superlongstringstring
________________________________________________________| said
_________________________________________________| alice
____________________________________________| was
________________________________________| that
_________________________________| as
______________________________| her
___________________________| with
___________________________| at
_________________________| on
________________________| all
_____________________| this
_____________________| for
_____________________| had
_____________________| but
____________________| be
____________________| not
__________________| they
__________________| so
_________________| very
_________________| what
更新されたコードは、もう少し読みやすく書かれています。
A=textscan(fopen('t'),'%s','delimiter','':'@');
s=lower(A{1});
s(cellfun('length', s)<2|ismember(s,{'the','and','of','to','it','in','or','is'}))=[];
[w,~,i]=unique(s);
N=hist(i,max(i));
[j,k]=sort(N,'descend');
n=cellfun('length',w(k));
q=80*N(k)'/N(k(1))+n;
q=floor(q*78/max(q)-n);
for i=1:22,
fprintf('%s| %s\n',repmat('_',1,q(i)),w{k(i)});
end
@ seanizer のコードを取り、バグを修正し(彼は最初の出力行を省略しました)、コードをより「ゴルフイ」にするためにいくつかの改善を行いました。
import Java.util.*;
import Java.util.regex.*;
import org.Apache.commons.io.IOUtils;
public class WF{
public static void main(String[] a)throws Exception{
String t=IOUtils.toString(new Java.net.URL(a[0]).openStream());
class W implements Comparable<W> {
String w;int f=1;W(String W){w=W;}public int compareTo(W o){return o.f-f;}
String d(float r){char[]c=new char[(int)(f/r)];Arrays.fill(c,'_');return "|"+new String(c)+"| "+w;}
}
Map<String,W>M=new HashMap<String,W>();
Matcher m=Pattern.compile("\\b\\w+\\b").matcher(t.toLowerCase());
while(m.find()){String w=m.group();W W=M.get(w);if(W==null)M.put(w,new W(w));else W.f++;}
M.keySet().removeAll(Arrays.asList("the,and,of,to,a,i,it,in,or,is".split(",")));
List<W>L=new ArrayList<W>(M.values());Collections.sort(L);int l=76-L.get(0).w.length();
System.out.println(" "+new String(new char[l]).replace('\0','_'));
for(W w:L.subList(0,22))System.out.println(w.d((float)L.get(0).f/(float)l));
}
}
出力:
_________________________________________________________________________ | _________________________________________________________________________ |彼女 | _______________________________________________________________ |あなた | ____________________________________________________________________________ |言った | _____________________________________________________ |アリス | _______________________________________________ || was | ___________________________________________ || that | ____________________________________ | as | ________________________________ |彼女 | _____________________________ | with | _____________________________ | at | ____________________________ | s | ____________________________ | t | __________________________ | on | __________________________ |すべて | _______________________ | this | _______________________ | for | _______________________ | had | _______________________ |しかし | ______________________ | be | _____________________ | not | ____________________ |彼ら | ____________________ |そう
Scala、327文字
これはmkneisslの answer Pythonバージョンに触発されたものですが、より大きくなっています。
val f="\\w+\\b(?<!\\bthe|and|of|to|a|i[tns]?|or)".r.findAllIn(io.Source.fromFile("11.txt").mkString.toLowerCase).toSeq
val t=f.toSet[String].map(x=> -f.count(x==)->x).toSeq.sorted take 22
def b(p:Int)="_"*(-p/(for((c,w)<-t)yield-c/(76.0-w.size)).max).toInt
println(" "+b(t(0)._1))
for(p<-t)printf("|%s| %s \n",b(p._1),p._2)
tr A-Z a-z|tr -Cs a-z "\n"|sort|egrep -v "^(the|and|of|to|a|i|it|in|or|is)$" |uniq -c|sort -r|head -22>g
n=1
while :
do
awk '{printf "|%0*s| %s\n",$1*'$n'/1e3,"",$2;}' g|tr 0 _>o
egrep -q .{80} o&&break
n=$((n+1))
done
cat o
Printfの驚くべき機能を使用した人はいないようです。
cat 11-very.txt> golf.sh
|__________________________________________________________________________| she
|________________________________________________________________| you
|_____________________________________________________________| said
|______________________________________________________| alice
|_______________________________________________| was
|____________________________________________| that
|____________________________________| as
|_________________________________| her
|______________________________| with
|______________________________| at
|_____________________________| s
|_____________________________| t
|___________________________| on
|__________________________| all
|________________________| this
|_______________________| for
|_______________________| had
|_______________________| but
|______________________| be
|______________________| not
|____________________| they
|____________________| so
猫11 | golf.sh
|_________________________________________________________________| she
|_________________________________________________________| verylongstringstring
|______________________________________________________| said
|_______________________________________________| alice
|__________________________________________| was
|_______________________________________| that
|________________________________| as
|_____________________________| her
|___________________________| with
|___________________________| at
|__________________________| s
|_________________________| t
|________________________| on
|_______________________| all
|_____________________| this
|_____________________| for
|_____________________| had
|____________________| but
|___________________| be
|___________________| not
|__________________| they
|__________________| so
(編集:キャラクターシェービングの提案のためにクリストフに小道具)
import sys,re
t=re.findall('[a-z]+',"".join(sys.stdin).lower())
d=sorted((t.count(w),w)for w in set(t)-set("the and of to a i it in or is".split()))[:-23:-1]
r=min((78.-len(m[1]))/m[0]for m in d)
print'','_'*(int(d[0][0]*r-2))
for(a,b)in d:print"|"+"_"*(int(a*r-2))+"|",b
出力:
_________________________________________________________________________
|_________________________________________________________________________| she
|_______________________________________________________________| you
|____________________________________________________________| said
|____________________________________________________| alice
|______________________________________________| was
|__________________________________________| that
|___________________________________| as
|_______________________________| her
|____________________________| with
|____________________________| at
|___________________________| s
|___________________________| t
|_________________________| on
|_________________________| all
|______________________| this
|______________________| for
|______________________| had
|_____________________| but
|____________________| be
|____________________| not
|___________________| they
|__________________| so
おそらく短くなる可能性があります...
bar <- function(w, l)
{
b <- rep("-", l)
s <- rep(" ", l)
cat(" ", b, "\n|", s, "| ", w, "\n ", b, "\n", sep="")
}
f <- "alice.txt"
e <- c("the", "and", "of", "to", "a", "i", "it", "in", "or", "is", "")
w <- unlist(lapply(readLines(file(f)), strsplit, s=" "))
w <- tolower(w)
w <- unlist(lapply(w, gsub, pa="[^a-z]", r=""))
u <- unique(w[!w %in% e])
n <- unlist(lapply(u, function(x){length(w[w==x])}))
o <- rev(order(n))
n <- n[o]
m <- 77 - max(unlist(lapply(u[1:22], nchar)))
n <- floor(m*n/n[1])
u <- u[o]
for (i in 1:22)
bar(u[i], n[i])
import sys
i="the and of to a i it in or is".split()
d={}
for j in filter(lambda x:x not in i,sys.stdin.read().lower().split()):d[j]=d.get(j,0)+1
w=sorted(d.items(),key=lambda x:x[1])[:-23:-1]
m=sorted(dict(w).values())[-1]
print" %s\n"%("_"*(76-m)),"\n".join(map(lambda x:("|%s| "+x[0])%("_"*((76-m)*x[1]/w[0][1])),w))
少し短くすることができると思いますが、それでもどうすればいいかわかりません。
|q s f m|q:=Bag new. f:=FileStream stdin. m:=0.[f atEnd]whileFalse:[s:=f nextLine.(s notNil)ifTrue:[(s tokenize:'\W+')do:[:i|(((i size)>1)&({'the'.'and'.'of'.'to'.'it'.'in'.'or'.'is'}includes:i)not)ifTrue:[q add:(i asLowercase)]. m:=m max:(i size)]]].(q:=q sortedByCount)from:1to:22 do:[:i|'|'display.((i key)*(77-m)//(q first key))timesRepeat:['='display].('| %1'%{i value})displayNl]
Luaソリューション:478文字。
t,u={},{}for l in io.lines()do
for w in l:gmatch("%a+")do
w=w:lower()if not(" the and of to a i it in or is "):find(" "..w.." ")then
t[w]=1+(t[w]or 0)end
end
end
for k,v in next,t do
u[#u+1]={k,v}end
table.sort(u,function(a,b)return a[2]>b[2]end)m,n=u[1][2],math.min(#u,22)for w=80,1,-1 do
s=""for i=1,n do
a,b=u[i][1],w*u[i][2]/m
if b+#a>=78 then s=nil break end
s2=("_"):rep(b)if i==1 then
s=s.." " ..s2.."\n"end
s=s.."|"..s2.."| "..a.."\n"end
if s then print(s)break end end
読み取り可能なバージョン:
t,u={},{}
for line in io.lines() do
for w in line:gmatch("%a+") do
w = w:lower()
if not (" the and of to a i it in or is "):find(" "..w.." ") then
t[w] = 1 + (t[w] or 0)
end
end
end
for k, v in pairs(t) do
u[#u+1]={k, v}
end
table.sort(u, function(a, b)
return a[2] > b[2]
end)
local max = u[1][2]
local n = math.min(#u, 22)
for w = 80, 1, -1 do
s=""
for i = 1, n do
f = u[i][2]
Word = u[i][1]
width = w * f / max
if width + #Word >= 78 then
s=nil
break
end
s2=("_"):rep(width)
if i==1 then
s=s.." " .. s2 .."\n"
end
s=s.."|" .. s2 .. "| " .. Word.."\n"
end
if s then
print(s)
break
end
end
Martinのソリューション (min76-など)からいくつかのアイデアを借りた別のT-SQLソリューション。
declare @ varchar(max),@w real,@j int;select s=@ into[ ]set @=(select*
from openrowset(bulk'a',single_blob)a)while @>''begin set @=stuff(@,1,
patindex('%[a-z]%',@)-1,'')+'.'set @j=patindex('%[^a-z]%',@)if @j>2insert[ ]
select lower(left(@,@j-1))set @=stuff(@,1,@j,'')end;select top(22)s,count(*)
c into # from[ ]where',the,and,of,to,it,in,or,is,'not like'%,'+s+',%'
group by s order by 2desc;select @w=min((76.-len(s))/c),@=' '+replicate(
'_',max(c)*@w)from #;select @=@+'
|'+replicate('_',c*@w)+'| '+s+' 'from #;print @
ソリューション全体を2行(最初の7つを連結)にする必要がありますが、そのままカット、ペースト、実行できます。合計文字数=507(Unix形式で保存し、SQLCMDを使用して実行する場合、改行を1としてカウントします)
仮定:
#
はありません[ ]
という名前のテーブルはありませんC:\windows\system32\a
ソリューションのリスト(<500文字)を取得するために、483文字(垂直バーなし/トップバーなし/ Wordの後に後続スペースなし)
declare @ varchar(max),@w real,@j int;select s=@ into[ ]set @=(select*
from openrowset(bulk'b',single_blob)a)while @>''begin set @=stuff(@,1,
patindex('%[a-z]%',@)-1,'')+'.'set @j=patindex('%[^a-z]%',@)if @j>2insert[ ]
select lower(left(@,@j-1))set @=stuff(@,1,@j,'')end;select top(22)s,count(*)
c into # from[ ]where',the,and,of,to,it,in,or,is,'not like'%,'+s+',%'
group by s order by 2desc;select @w=min((78.-len(s))/c),@=''from #;select @=@+'
'+replicate('_',c*@w)+' '+s from #;print @
declare @ varchar(max), @w real, @j int
select s=@ into[ ] -- shortcut to create table; use defined variable to specify column type
-- openrowset reads an entire file
set @=(select * from openrowset(bulk'a',single_blob) a) -- a bit shorter than naming 'BulkColumn'
while @>'' begin -- loop until input is empty
set @=stuff(@,1,patindex('%[a-z]%',@)-1,'')+'.' -- remove lead up to first A-Z char *
set @j=patindex('%[^a-z]%',@) -- find first non A-Z char. The +'.' above makes sure there is one
if @j>2insert[ ] select lower(left(@,@j-1)) -- insert only words >1 char
set @=stuff(@,1,@j,'') -- remove Word and trailing non A-Z char
end;
select top(22)s,count(*)c
into #
from[ ]
where ',the,and,of,to,it,in,or,is,' not like '%,'+s+',%' -- exclude list
group by s
order by 2desc; -- highest occurence, assume no ties at 22!
-- 80 - 2 vertical bars - 2 spaces = 76
-- @w = weighted frequency
-- this produces a line equal to the length of the max occurence (max(c))
select @w=min((76.-len(s))/c),@=' '+replicate('_',max(c)*@w)
from #;
-- for each Word, append it as a new line. note: embedded newline
select @=@+'
|'+replicate('_',c*@w)+'| '+s+' 'from #;
-- note: 22 words in a table should always fit on an 8k page
-- the order of processing should always be the same as the insert-orderby
-- thereby producing the correct output
print @ -- output
Java、徐々に短くなります(1500135812411020913 890文字)
空白と変数名の長さをさらに削除しました。可能であればジェネリックを削除し、インラインクラスとtry/catchブロックを削除しすぎたため、900バージョンにバグがありました
import Java.net.*;import Java.util.*;import Java.util.regex.*;import org.Apache.commons.io.*;public class G{public static void main(String[]a)throws Exception{String text=IOUtils.toString(new URL(a[0]).openStream()).toLowerCase().replaceAll("\\b(the|and|of|to|a|i[tns]?|or)\\b","");final Map<String,Integer>p=new HashMap();Matcher m=Pattern.compile("\\b\\w+\\b").matcher(text);Integer b;while(m.find()){String w=m.group();b=p.get(w);p.put(w,b==null?1:b+1);}List<String>v=new Vector(p.keySet());Collections.sort(v,new Comparator(){public int compare(Object l,Object m){return p.get(m)-p.get(l);}});boolean t=true;float r=0;for(String w:v.subList(0,22)){if(t){t=false;r=p.get(w)/(float)(80-(w.length()+4));System.out.println(" "+new String(new char[(int)(p.get(w)/r)]).replace('\0','_'));}System.out.println("|"+new String(new char[(int)(((Integer)p.get(w))/r)]).replace('\0','_')+"|"+w);}}}
読み取り可能なバージョン:
import Java.net.*;
import Java.util.*;
import Java.util.regex.*;
import org.Apache.commons.io.*;
public class G{
public static void main(String[] a) throws Exception{
String text =
IOUtils.toString(new URL(a[0]).openStream())
.toLowerCase()
.replaceAll("\\b(the|and|of|to|a|i[tns]?|or)\\b", "");
final Map<String, Integer> p = new HashMap();
Matcher m = Pattern.compile("\\b\\w+\\b").matcher(text);
Integer b;
while(m.find()){
String w = m.group();
b = p.get(w);
p.put(w, b == null ? 1 : b + 1);
}
List<String> v = new Vector(p.keySet());
Collections.sort(v, new Comparator(){
public int compare(Object l, Object m){
return p.get(m) - p.get(l);
}
});
boolean t = true;
float r = 0;
for(String w : v.subList(0, 22)){
if(t){
t = false;
r = p.get(w) / (float) (80 - (w.length() + 4));
System.out.println(" "
+ new String(new char[(int) (p.get(w) / r)]).replace('\0',
'_'));
}
System.out.println("|"
+ new String(new char[(int) (((Integer) p.get(w)) / r)]).replace('\0',
'_') + "|" + w);
}
}
}
このRubyバージョンは「superlongstringstring」を処理します。(最初の2行は以前のRubyプログラム。)
この方法で実行する必要があります。
ルビー-n0777 golf.rb Alice.txt
W=($_.upcase.scan(/\w+/)-%w(THE AND OF TO A I IT
IN OR IS)).group_by{|x|x}.map{|k,v|[-v.size,k]}.sort[0,22]
u=proc{|m|"_"*(W.map{|n,s|(76.0-s.size)/n}.max*m)}
puts" "+u[W[0][0]],W.map{|n,s|"|%s| "%u[n]+s}
3行目は、正しくスケーリングされたアンダースコアの文字列を生成するクロージャーまたはラムダを作成します。
u = proc {| m | "_" * (W.map {| n、s |(76.0-s.size)/ n} .max * m ) }
数値が負であるため、.max
の代わりに.min
が使用されます。
Perl、188文字
上記のPerlバージョン(および正規表現分割ベースのバージョン)は、禁止語のリストを個別のリストとしてではなく、ネガティブな先読みアサーションとして含めることにより、数バイト短くすることができます。さらに、末尾のセミコロンは省略できます。
また、他のいくつかの提案(<=>の代わりに、for/foreach、「キー」を削除)を含めました。
$c{$_}++for grep{$_}map{lc=~/\b(?!(?:the|and|a|of|or|i[nts]?|to)\b)[a-z]+/g}<>;@s=sort{$c{$b}-$c{$a}}%c;$f=76-length$s[0];say$"."_"x$f;say"|"."_"x($c{$_}/$c{$s[0]}*$f)."| $_ "for@s[0..21]
Perlを知りませんが、(?!(?:...)\ b)が?:を失う可能性があると思います。
私が私のものを終えた後、私はマットからいくつかのアイデアを盗みました:3
t=Prompt().toLowerCase().replace(/\b(the|and|of|to|a|i[tns]?|or)\b/gm,'');r={};o=[];t.replace(/\b([a-z]+)\b/gm,function(a,w){r[w]?++r[w]:r[w]=1});for(i in r){o.Push([i,r[i]])}m=o[0][1];o=o.slice(0,22);o.sort(function(F,D){return D[1]-F[1]});for(B in o){F=o[B];L=new Array(~~(F[1]/m*(76-F[0].length))).join('_');print(' '+L+'\n|'+L+'| '+F[0]+' \n')}
printおよびPrompt関数のサポートが必要です。
いくつかの-iフラグを追加すると、過度に長いtr A-Z a-z |がドロップされる場合がありますステップ;仕様では、表示されるケースについては何も述べられておらず、uniq -ciは大文字と小文字の違いを取り除きます。
egrep -oi [a-z]+|egrep -wiv 'the|and|o[fr]|to|a|i[tns]?'|sort|uniq -ci|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$_"'
元の206文字と比較すると、trはマイナス11、-iは2です。
編集: \\ bの場合はマイナス3です。いずれにしても、パターンマッチングは境界で開始されるため、省略することができます。
sortは最初に小文字を返し、uniq -ciが最初に出現するため、出力の実際の変更は、Aliceが大文字の初期を保持することだけです。
大物が大好きだ... Objective-C(1070931 905文字)
#define S NSString
#define C countForObject
#define O objectAtIndex
#define U stringWithCString
main(int g,char**b){id c=[NSCountedSet set];S*d=[S stringWithContentsOfFile:[S U:b[1]]];id p=[NSPredicate predicateWithFormat:@"SELF MATCHES[cd]'(the|and|of|to|a|i[tns]?|or)|[^a-z]'"];[d enumerateSubstringsInRange:NSMakeRange(0,[d length])options:NSStringEnumerationByWords usingBlock:^(S*s,NSRange x,NSRange y,BOOL*z){if(![p evaluateWithObject:s])[c addObject:[s lowercaseString]];}];id s=[[c allObjects]sortedArrayUsingComparator:^(id a,id b){return(NSComparisonResult)([c C:b]-[c C:a]);}];g=[c C:[s O:0]];int j=76-[[s O:0]length];char*k=malloc(80);memset(k,'_',80);S*l=[S U:k length:80];printf(" %s\n",[[l substringToIndex:j]cString]),[[s subarrayWithRange:NSMakeRange(0,22)]enumerateObjectsUsingBlock:^(id a,NSUInteger x,BOOL*y){printf("|%s| %s\n",[[l substringToIndex:[c C:a]*j/g]cString],[a cString]);}];}
多数の減価償却APIの使用に切り替え、不要なメモリ管理を削除し、より積極的な空白削除を行いました
_________________________________________________________________________
|_________________________________________________________________________| she
|______________________________________________________________| said
|__________________________________________________________| you
|____________________________________________________| alice
|________________________________________________| was
|_______________________________________| that
|____________________________________| as
|_________________________________| her
|______________________________| with
|______________________________| at
|___________________________| on
|__________________________| all
|________________________| this
|________________________| for
|________________________| had
|_______________________| but
|______________________| be
|______________________| not
|____________________| so
|___________________| very
|__________________| what
|_________________| they
python(標準入力から読み取られたテキスト)の290文字
import sys,re
c={}
for w in re.findall("[a-z]+",sys.stdin.read().lower()):c[w]=c.get(w,0)+1-(","+w+","in",a,i,the,and,of,to,it,in,or,is,")
r=sorted((-v,k)for k,v in c.items())[:22]
sf=max((76.0-len(k))/v for v,k in r)
print" "+"_"*int(r[0][0]*sf)
for v,k in r:print"|"+"_"*int(v*sf)+"| "+k
しかし...他のソリューションを読んだ後、私は突然効率が要求ではないことに気付きました。したがって、これは別のより短く、はるかに遅いものです(255文字)
import sys,re
w=re.findall("\w+",sys.stdin.read().lower())
r=sorted((-w.count(x),x)for x in set(w)-set("the and of to a i it in or is".split()))[:22]
f=max((76.-len(k))/v for v,k in r)
print" "+"_"*int(f*r[0][0])
for v,k in r:print"|"+"_"*int(f*v)+"| "+k
そして、他のソリューションをさらに読んだ後...
import sys,re
w=re.findall("\w+",sys.stdin.read().lower())
r=sorted((-w.count(x),x)for x in set(w)-set("the and of to a i it in or is".split()))[:22]
f=max((76.-len(k))/v for v,k in r)
print"","_"*int(f*r[0][0])
for v,k in r:print"|"+"_"*int(f*v)+"|",k
そして今、この解決策はアスタチンの1つとほぼ同じバイトごとのバイトです:-D
f=scan("stdin","ch")
u=unlist
s=strsplit
a=u(s(u(s(tolower(f),"[^a-z]")),"^(the|and|of|to|it|in|or|is|.|)$"))
v=unique(a)
r=sort(sapply(v,function(i) sum(a==i)),T)[2:23] #the first item is an empty string, just skipping it
w=names(r)
q=(78-max(nchar(w)))*r/max(r)
cat(" ",rep("_",q[1])," \n",sep="")
for(i in 1:22){cat("|",rep("_",q[i]),"| ",w[i],"\n",sep="")}
出力は次のとおりです。
_________________________________________________________________________
|_________________________________________________________________________| she
|_______________________________________________________________| you
|____________________________________________________________| said
|_____________________________________________________| alice
|_______________________________________________| was
|___________________________________________| that
|____________________________________| as
|________________________________| her
|_____________________________| at
|_____________________________| with
|__________________________| on
|__________________________| all
|_______________________| this
|_______________________| for
|_______________________| had
|_______________________| but
|______________________| be
|_____________________| not
|____________________| they
|____________________| so
|___________________| very
|__________________| what
そして、「あなた」がもっと長いものに置き換えられた場合:
____________________________________________________________
|____________________________________________________________| she
|____________________________________________________| veryverylongstring
|__________________________________________________| said
|___________________________________________| alice
|______________________________________| was
|___________________________________| that
|_____________________________| as
|__________________________| her
|________________________| at
|________________________| with
|______________________| on
|_____________________| all
|___________________| this
|___________________| for
|___________________| had
|__________________| but
|__________________| be
|__________________| not
|________________| they
|________________| so
|_______________| very
|_______________| what
Go、613文字は、おそらくもっと小さくなります。
package main
import(r "regexp";. "bytes";. "io/ioutil";"os";st "strings";s "sort";. "container/vector")
type z struct{c int;w string}
func(e z)Less(o interface{})bool{return o.(z).c<e.c}
func main(){b,_:=ReadAll(os.Stdin);g:=r.MustCompile
c,m,x:=g("[A-Za-z]+").AllMatchesIter(b,0),map[string]int{},g("the|and|of|it|in|or|is|to")
for w:=range c{w=ToLower(w);if len(w)>1&&!x.Match(w){m[string(w)]++}}
o,y:=&Vector{},0
for k,v:=range m{o.Push(z{v,k});if v>y{y=v}}
s.Sort(o)
for i,v:=range *o{if i>21{break};x:=v.(z);c:=int(float(x.c)/float(y)*80)
u:=st.Repeat("_",c);if i<1{println(" "+u)};println("|"+u+"| "+x.w)}}
とても汚い。
foreach w [regexp -all -inline {[a-z]+} [string tolower [read stdin]]] {if {[lsearch {the and of to it in or is a i} $w]>=0} {continue};if {[catch {incr Ws($w)}]} {set Ws($w) 1}}
set T [lrange [lsort -decreasing -stride 2 -index 1 -integer [array get Ws]] 0 43]
foreach {w c} $T {lappend L [string length $w];lappend C $c}
set N [tcl::mathfunc::max {*}$L]
set C [lsort -integer $C]
set M [lindex $C end]
puts " [string repeat _ [expr {int((76-$N) * [lindex $T 1] / $M)}]] "
foreach {w c} $T {puts "|[string repeat _ [expr {int((76-$N) * $c / $M)}]]| $w"}
または、より読みやすく
foreach w [regexp -all -inline {[a-z]+} [string tolower [read stdin]]] {
if {[lsearch {the and of to a i it in or is} $w] >= 0} { continue }
if {[catch {incr words($w)}]} {
set words($w) 1
}
}
set topwords [lrange [lsort -decreasing -stride 2 -index 1 -integer [array get words]] 0 43]
foreach {Word count} $topwords {
lappend lengths [string length $Word]
lappend counts $count
}
set maxlength [lindex [lsort -integer $lengths] end]
set counts [lsort -integer $counts]
set mincount [lindex $counts 0].0
set maxcount [lindex $counts end].0
puts " [string repeat _ [expr {int((76-$maxlength) * [lindex $topwords 1] / $maxcount)}]] "
foreach {Word count} $topwords {
set barlength [expr {int((76-$maxlength) * $count / $maxcount)}]
puts "|[string repeat _ $barlength]| $Word"
}
以前に投稿されたシェルのバージョンを改善すると、213文字になります。
tr A-Z a-z|tr -Cs a-z \\n|sort|egrep -v '^(the|and|of|to|a|i|it|in|or|is)$'|uniq -c|sort -rn|sed 22q>g
n=1
>o
until egrep -q .{80} o
do
awk '{printf "|%0*d| %s\n",$1*'$n'/1e3,0,$2}' g|tr 0 _>o
((n++))
done
cat o
トップバーの上部のアウトラインを取得するには、240文字に拡張する必要がありました。
tr A-Z a-z|tr -Cs a-z \\n|sort|egrep -v "^(the|and|of|to|a|i|it|in|or|is)$"|uniq -c|sort -r|sed 1p\;22q>g
n=1
>o
until egrep -q .{80} o
do
awk '{printf "|%0*d| %s\n",$1*'$n'/1e3,0,NR==1?"":$2}' g|sed '1s,|, ,g'|tr 0 _>o
((n++))
done
cat o
Python、250文字
他のすべてから借りるPythonスニペット
import re,sys
t=re.findall("\w+","".join(sys.stdin).lower())
W=sorted((-t.count(w),w)for w in set(t)-set("the and of to a i it in or is".split()))[:22]
Z,U=W[0],lambda n:"_"*int(n*(76.-len(Z[1]))/Z[0])
print"",U(Z[0])
for(n,w)in W:print"|"+U(n)+"|",w
あなたが生意気で、引数として避けるために単語を置く場合、223 chars
import re,sys
t=re.findall("\w+","".join(sys.stdin).lower())
W=sorted((-t.count(w),w)for w in set(t)-set(sys.argv[1:]))[:22]
Z,U=W[0],lambda n:"_"*int(n*(76.-len(Z[1]))/Z[0])
print"",U(Z[0])
for(n,w)in W:print"|"+U(n)+"|",w
出力は次のとおりです。
$ python alice4.py the and of to a i it in or is < 11.txt _________________________________________________________________________ |_________________________________________________________________________| she |_______________________________________________________________| you |____________________________________________________________| said |_____________________________________________________| alice |_______________________________________________| was |___________________________________________| that |____________________________________| as |________________________________| her |_____________________________| at |_____________________________| with |____________________________| s |____________________________| t |__________________________| on |__________________________| all |_______________________| this |_______________________| for |_______________________| had |_______________________| but |______________________| be |_____________________| not |____________________| they |____________________| so
コード:
m=[:]
(new URL(args[0]).text.toLowerCase()=~/\w+/).each{it==~/(the|and|of|to|a|i[tns]?|or)/?:(m[it]=1+(m[it]?:0))}
k=m.keySet().sort{a,b->m[b]<=>m[a]}
b={d,c,b->println d+'_'*c+d+' '+b}
b' ',z=77-k[0].size(),''
k[0..21].each{b'|',m[it]*z/m[k[0]],it}
実行:
$ groovy wordcount.groovy http://www.gutenberg.org/files/11/11.txt
出力:
__________________________________________________________________________
|__________________________________________________________________________| she
|________________________________________________________________| you
|_____________________________________________________________| said
|_____________________________________________________| alice
|_______________________________________________| was
|____________________________________________| that
|____________________________________| as
|_________________________________| her
|______________________________| at
|______________________________| with
|_____________________________| s
|_____________________________| t
|___________________________| on
|__________________________| all
|________________________| this
|_______________________| for
|_______________________| had
|_______________________| but
|______________________| be
|______________________| not
|____________________| they
|____________________| so
N.B.これは、緩和されたルールre:long stringsに従います。
{t::y;{(-1')t#(.:)[b],'(!:)[b:"|",/:(((_)70*x%(*:)x)#\:"_"),\:"|"];}desc(#:')(=)($)(`$inter\:[(,/)" "vs'" "sv/:"'"vs'a(&)0<(#:')a:(_:')read0 -1!x;52#.Q.an])except`the`and`of`to`a`i`it`in`or`is`}
この関数は2つの引数を取ります。1つはテキストを含むファイルで、もう1つは表示するグラフの行数です
q){t::y;{(-1')t#(.:)[b],'(!:)[b:"|",/:(((_)70*x%(*:)x)#\:"_"),\:"|"];}desc(#:')(=)($)(`$inter\:[(,/)" "vs'" "sv/:"'"vs'a(&)0<(#:')a:(_:')read0 -1!x;52#.Q.an])except`the`and`of`to`a`i`it`in`or`is`}[`a.txt;20]
出力
|______________________________________________________________________|she
|____________________________________________________________|you
|__________________________________________________________|said
|___________________________________________________|alice
|_____________________________________________|was
|_________________________________________|that
|__________________________________|as
|_______________________________|her
|_____________________________|with
|____________________________|at
|___________________________|t
|___________________________|s
|_________________________|on
|_________________________|all
|_______________________|this
|______________________|for
|______________________|had
|_____________________|but
|_____________________|be
|_____________________|not