Создайте диаграмму ASCII обычно используемых слов в данном [закрытом] тексте

156
задан 24 revs, 11 users 85% 16 November 2014 в 21:47
поделиться

56 ответов

LabVIEW 51 узел, 5 структур, 10 диаграмм

Учить слона танцевать чечетку некрасиво. Я, ах, пропущу подсчет символов.

labVIEW code

results

Программа идет слева направо:

labVIEW code explained

123
ответ дан 23 November 2019 в 21:47
поделиться

Версия PHP CLI (450 символов)

В этом решении учтено последнее требование, которое большинство пуристов предпочитают игнорировать. Это стоило 170 символов!

Использование: php.exe

Уменьшено:

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

Читается человеком:

<?php

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

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

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

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

// Sort:
arsort($a);

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


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

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


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

?>

Вывод:

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

Если слово длинное, полосы отображаются отрегулировано правильно:

|--------------------------------------------------------| she
|---------------------------------------------------| thisisareallylongwordhere
|-------------------------------------------------| you
|-----------------------------------------------| said
|-----------------------------------------| alice
|------------------------------------| was
|---------------------------------| that
|---------------------------| as
|-------------------------| her
|-----------------------| with
|-----------------------| at
|--------------------| on
|--------------------| all
|------------------| this
|------------------| for
|------------------| had
|-----------------| but
|-----------------| be
|----------------| not
|---------------| they
|---------------| so
|--------------| very
11
ответ дан 23 November 2019 в 21:47
поделиться

206

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

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

hm, только что показано выше: sort -nr -> sort -n , а затем голова -> хвост => 208:)
update2: эээ, конечно, это глупо, так как тогда все будет наоборот. Итак, 209.
update3: оптимизировано исключение regexp -> 206

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



для развлечения, вот версия только для Perl (намного быстрее):

~ % wc -c pgolf
204 pgolf
~ % cat pgolf
perl -lne'$1=~/^(the|and|o[fr]|to|.|i[tns])$/i||$f{lc$1}++while/\b([a-z]+)/gi}{@w=(sort{$f{$b}<=>$f{$a}}keys%f)[0..21];$Q=$f{$_=$w[0]};$B=76-y///c;print" "."_"x$B;print"|"."_"x($B*$f{$_}/$Q)."| $_"for@w'
~ % # usage:
~ % sh pgolf < 11.txt
35
ответ дан 23 November 2019 в 21:47
поделиться

Решение на основе набора Transact SQL (SQL Server 2005) 1063 892 873 853 827 820 783 683 647 644 630 символов

Спасибо Гейбу за полезные предложения по сокращению количества символов.

NB: Разрывы строк добавлены, чтобы избежать полос прокрутки, требуется только последний разрыв строки.

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
35
ответ дан 23 November 2019 в 21:47
поделиться

Mathematica ( 297 284 248 244 242 199 символов) Чистый функциональный

и проверка закона Ципфа.

Смотри, мама ... без варов, без рук, .. без головы

Правка 1> определены некоторые сокращения (284 символа)

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

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

Некоторые пояснения

Import[] 
   # Get The File

ToLowerCase []
   # To Lower Case :)

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

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

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

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

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

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

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

Вывод

альтернативный текст http: // i49 .tinypic.com / 2n8mrer.jpg

Mathematica не очень подходит для игры в гольф, и это только из-за длинных описательных имен функций. Такие функции, как «RegularExpression []» или «StringSplit []» заставляют меня рыдать :(.

Проверка закона Ципфа

Закон Ципфа предсказывает, что для текста на естественном языке, Log (Rank) vs Log (вхождения) График следует линейному отношения.

Закон используется при разработке алгоритмов криптографии и сжатия данных. (Но это НЕ "Z" в алгоритме LZW).

В нашем тексте мы можем проверить это с помощью следующего

 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]

Результат (довольно линейный)

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

Edit 6> (242 Chars)

Рефакторинг Regex (функция Select больше не используется)
Удаление 1 символьного слова
Более эффективное определение функции «f»

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

Редактировать 7 → 199 символов

BarChart[#2, BarOrigin->Left, ChartLabels->Placed[#1, After], Axes->None]&@@ 
  Transpose@Take[SortBy[Tally@StringSplit[ToLowerCase@Import@i, 
    RegularExpression@"(\\W|\\b(.|the|and|of|to|i[tns]|or)\\b)+"],Last], -22]
  • Заменено f на Транспонирование и Слот ( # 1 / # 2 ) аргументы.
  • Нам не нужны вонючие скобки (используйте f @ x вместо f [x] , где это возможно)

28
ответ дан 23 November 2019 в 21:47
поделиться

Руби 207 213 211 210 207 203 201 200 символов

Улучшение Anurag, включая предложение rfusca. Также убирает аргумент для сортировки и некоторые другие мелкие игры в гольф.

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 .

34
ответ дан 23 November 2019 в 21:47
поделиться

C # - 510 451 436 446 434 426 422 символа (уменьшено)

Не так уж и коротко , а теперь наверное поправлю! Обратите внимание, что в предыдущей версии не отображалась первая строка столбцов, они не масштабировались правильно, загружался файл вместо того, чтобы получить его из стандартного ввода, и не содержал всей необходимой многословности 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));
    }
}

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));}}
27
ответ дан 23 November 2019 в 21:47
поделиться

Windows PowerShell, 199 символов

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

(Последний разрыв строки не обязателен, но включен здесь для удобства чтения)

(Текущий код и мои тестовые файлы доступны в мой репозиторий SVN . Я надеюсь, что мои тестовые примеры выявляют наиболее распространенные ошибки (длина полосы, проблемы с сопоставлением регулярных выражений и некоторые другие))

Предположения:

  • US ASCII в качестве входных данных. С Юникодом, наверное, становится странно.
  • По крайней мере два непрерывных слова в тексте

История

Расслабленная версия (137), так как они теперь считаются отдельно, очевидно:

($x=$input-split'\P{L}'-notmatch'^(the|and|of|to|.?|i[tns]|or)$'|group|sort *)[-1..-22]|%{"|$('_'*(76*$_.Count/$x[-1].Count))| "+$_.Name}
  • не закрыть первую полосу
  • не учитывает длину слова не первого слова

Вариации длины полосы одного символа по сравнению с другими решениями связаны с тем, что PowerShell использует округление вместо усечения при преобразовании чисел с плавающей запятой в целые числа. Поскольку задача требовала только пропорциональной длины стержня, это должно быть нормально.

По сравнению с другими решениями, я применил несколько иной подход к определению максимальной длины полосы, просто попробовав и выбрав наибольшую такую ​​длину, когда ни одна строка не превышает 80 символов.

Более старую версию можно найти здесь .

20
ответ дан 23 November 2019 в 21:47
поделиться

Perl, 237 229 209 символов

(Обновлено снова, чтобы превзойти версию Ruby с большим количеством грязных трюков с гольфом, заменив split / [^ az /, lc с lc = ~ / [az] + / g и устранением проверки на пустую строку в другом месте. Они были вдохновлены версией Ruby, поэтому следует отдать должное.)

Обновление: теперь с Perl 5.10! Замените print на скажем и используйте ~~ , чтобы избежать отображения . Его нужно вызывать в командной строке как perl -E '' alice.txt . Поскольку весь скрипт находится в одной строке, написание его однострочным не должно вызвать затруднений :).

 @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 к разделенному регулярному выражению, так что это промывка.

Если вы работаете в системе, где перевод строки состоит из одного символа, а не двух, вы можете сократить его еще на два символа, используя буквальный перевод строки вместо \ n . Однако я не написал приведенный выше образец таким образом, поскольку так он «яснее» (ха!).


Вот в основном правильное, но далеко не достаточно короткое решение 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;
25
ответ дан 23 November 2019 в 21:47
поделиться

JavaScript 1.8 (SpiderMonkey) - 354

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

К сожалению, for ([k, v] in z) из версии Rhino, похоже, не хочет работать в SpiderMonkey, а readFile () немного проще, чем использование readline () , но переход на 1.8 позволяет нам использовать закрытие функций, чтобы сократить еще несколько строк ....

Добавление пробелов для удобства чтения:

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

Использование: js golf.js

Вывод:

 _________________________________________________________________________ 
|_________________________________________________________________________| she
|_______________________________________________________________| you
|____________________________________________________________| said
|____________________________________________________| alice
|______________________________________________| was
|___________________________________________| that
|___________________________________| as
|________________________________| her
|_____________________________| at
|_____________________________| with
|____________________________| s
|____________________________| t
|__________________________| on
|_________________________| all
|_______________________| this
|______________________| for
|______________________| had
|______________________| but
|_____________________| be
|_____________________| not
|___________________| they
|___________________| so

(базовая версия - неправильно обрабатывает ширину полосы)

JavaScript (Rhino ) - 405 395 387 377 368 343 304 символа

Я думаю, моя логика сортировки отключена, но ... я не знаю. Brainfart исправлен.

Минифицированный (злоупотребление \ n интерпретируется как ; иногда):

x={};p='|';e=' ';z=[]
readFile(arguments[0]).toLowerCase().replace(/\b(?!(the|and|of|to|a|i[tns]?|or)\b)\w+/g,function(y){x[y]?x[y].c++:z.push(x[y]={w:y,c:1})})
z=z.sort(function(a,b){return b.c-a.c}).slice(0,22)
for([k,v]in z){s=Array((v.c/z[0].c)*70|0).join('_')
if(!+k)print(e+s+e)
print(p+s+p+e+v.w)}
11
ответ дан 23 November 2019 в 21:47
поделиться

Руби, 215, 216 , 218 , 221 , 224 , 236 , 237 символов

обновление 1: Ура ! Это связано с решением JS Bangs ' . Не могу придумать, как срубить больше :)

обновление 2: Сыграл грязный трюк с гольфом. Изменили каждый на карту , чтобы сохранить 1 символ :)

обновление 3: Изменил File.read на IO.read +2 . Array.group_by был не очень плодотворным, изменен на reduce +6. Проверка без учета регистра не требуется после нижнего регистра с downcase в регулярном выражении +1. Сортировку по убыванию легко выполнить, отрицая значение +6. Общая экономия +15

обновление 4: [0] вместо .first , +3. (@ Shtéf)

обновление 5: развернуть переменную l на месте, +1. Разверните переменную s на месте, +2.(@ Shtééf)

обновление 6: Используйте сложение строк, а не интерполяцию для первой строки, +2. (@ Shtéf)

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

обновление 7: я прошел через множество шумих, чтобы обнаружить первую итерацию внутри цикла, используя переменные экземпляра. Все, что у меня есть, это +1, хотя, возможно, есть потенциал. Сохраняю предыдущую версию, потому что я считаю, что это черная магия. (@ Shtéf)

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

Версия для чтения

string = File.read($_).downcase

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

word_length = highest_frequency_word.size
widest = 76 - word_length

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

Для использования:

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

Вывод:

 _________________________________________________________________________
|_________________________________________________________________________| she 
|_______________________________________________________________| you 
|____________________________________________________________| said 
|_____________________________________________________| alice 
|_______________________________________________| was 
|___________________________________________| that 
|____________________________________| as 
|________________________________| her 
|_____________________________| with 
|_____________________________| at 
|____________________________| s 
|____________________________| t 
|__________________________| on 
|__________________________| all 
|_______________________| this 
|_______________________| for 
|_______________________| had 
|_______________________| but 
|______________________| be 
|_____________________| not 
|____________________| they 
|____________________| so 
19
ответ дан 23 November 2019 в 21:47
поделиться

GolfScript, 177 175 173 167 164 163 144 131 130 символов

Медленно - 3 минуты на пример текста (130)

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

Объяснение:

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

"Правильно" (надеюсь). (143)

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

Менее медленно - полминуты. (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*'| '@}/

Выходные данные видны в журналах ревизий.

39
ответ дан 23 November 2019 в 21:47
поделиться

Python 2.x, широтный подход = 227 183 символа

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

Учитывая свободу в реализации, я построил конкатенацию строк, которая содержит все слова, запрошенные для исключения ( the, и , of, to, a, i, it, in, or is ) - плюс он также исключает два печально известных «слова» s и t из примера - и я добавил бесплатно исключение для и для него . Я попробовал все конкатенации этих слов с корпусом слов из Алисы, Библии короля Иакова и файла жаргона, чтобы увидеть, есть ли какие-то слова, которые будут ошибочно исключены строкой. Так я закончил двумя строками исключения: 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

Rant

Что касается слов, которые следует игнорировать, можно подумать, что они взяты из списка наиболее часто используемых слов в английском языке. Этот список зависит от используемого текстового корпуса . По одному из самых популярных списков ( http://en.wikipedia.org/wiki/Most_common_words_in_English , http://www.english-for-students.com/Frequent-Used-Words .html , http://www.sporcle.com/games/common_english_words.php ), первые 10 слов: the be (am / are / is / was / was / were) to of and a in that have I

10 лучших слов из текста «Алиса в стране чудес» - это , а к одной из них она, которую вы сказали
10 лучших слов из файла жаргонов (v4.4 .7) являются a of to и in is that or for

Итак, вопрос в том, почему или были включены в список игнорирования задачи, где оно ~ 30-е место по популярности, когда слово что (8-е место по популярности) - нет. и т. д. и т. д. Следовательно, я считаю, что список игнорирования должен предоставляться динамически (или может быть опущен).

Альтернативный вариант - просто пропустить первые 10 слов из результата - что фактически сократит решение (элементарно - должно отображаться только с 11-й по 32-ю записи).


Python 2.x, скрупулезный подход = 277 243 символа

Диаграмма, нарисованная в приведенном выше коде, упрощена (с использованием только одного символа для столбцов). Если кто-то хочет точно воспроизвести диаграмму из описания проблемы (что не требовалось), этот код сделает это:

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

Я беру проблему с несколько случайным выбором из 10 слов, чтобы исключить , и, of, to, a, i, it, in или, is , поэтому они должны передаваться как параметры командной строки, например:
python WordFrequencyChart.py the and of to ai it in or is <" Alice's Adventures in Wonderland.txt "

Это 213 символов + 30, если мы учтем" исходный "список игнорирования, переданный в командной строке = 243

PS. Второй код также выполняет «корректировку» длин всех верхних слов, поэтому ни одно из них не будет переполняться в вырожденном случае.

 _______________________________________________________________
|_______________________________________________________________| she
|_______________________________________________________| superlongstringstring
|_____________________________________________________| said
|______________________________________________| alice
|_________________________________________| was
|______________________________________| that
|_______________________________| as
|____________________________| her
|__________________________| at
|__________________________| with
|_________________________| s
|_________________________| t
|_______________________| on
|_______________________| all
|____________________| this
|____________________| for
|____________________| had
|____________________| but
|___________________| be
|___________________| not
|_________________| they
|_________________| so
19
ответ дан 23 November 2019 в 21:47
поделиться

Python 3.1 - 245 229 символов

Я полагаю, используя Counter - это обман :) Я только что прочитал об этом около недели назад, так что это был прекрасный шанс увидеть, как это работает.

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.

11
ответ дан 23 November 2019 в 21:47
поделиться

Обычный LISP, 670 символов

Я новичок в LISP, и это попытка использовать хэш-таблицу для подсчета (так что, вероятно, это не самый компактный метод).

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

можно запустить, например, с помощью. cat alice.txt | clisp -C golf.lisp.

В читабельном виде это

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

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

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

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

       ; add alphabetic to current word, and bump word counter
       ; on non-alphabetic
       (cond
        ((char<= #\a x #\z)
         (push x w))
        (t
         (incf (gethash (concatenate 'string (reverse w)) c 0))
         (setf w nil)))))
7
ответ дан 23 November 2019 в 21:47
поделиться

Gawk -- 336 (изначально 507) символов

(после исправления форматирования вывода; исправления проблемы с сокращениями; доработки; доработки; доработки снова; удаления совершенно ненужного шага сортировки; доработки еще раз; и еще (упс, этот шаг нарушил форматирование); доработки еще; принимая вызов Мэтта, я отчаянно дорабатываю еще; нашел другое место, чтобы сохранить несколько, но вернул два, чтобы исправить ошибку с длиной строки)

Хе-хе! Я на мгновение опережаю [JavaScript Мэтта][1] в решении встречной задачи! ;) и [AKX's python][2].

Проблема, похоже, требует языка, реализующего собственные ассоциативные массивы, поэтому конечно я выбрал язык с ужасно неполным набором операторов для них. В частности, вы не можете контролировать порядок, в котором awk предлагает элементы хэш-карты, поэтому я многократно сканирую всю карту, чтобы найти самый многочисленный элемент, печатаю его и удаляю из массива.

Все это ужасно неэффективно, а с учетом всех тех изменений, которые я сделал, стало еще и довольно ужасно.

Уменьшено:

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

переносы строк только для ясности: они не нужны и не должны учитываться.


Выход:

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

Читабельный; 633 символа (первоначально 949):

{
    gsub("[^a-zA-Z]"," ");
    for(;NF;NF--)
    a[tolower($NF)]++
}
END{
    # remove "short" words
    split("the and of to a i it in or is",b," ");
    for (w in b) 
    delete a[b[w]];
    # Find the bar ratio
    d=1;
    for (w in a) {
    e=a[w]/(78-length(w));
    if (e>d)
        d=e
    }
    # Print the entries highest count first
    for (i=22; i; --i){               
    # find the highest count
    e=0;
    for (w in a) 
        if (a[w]>e)
        e=a[x=w];
        # Print the bar
    l=a[x]/d-2;
    # make a string of "_" the right length
    t=sprintf(sprintf("%%%dc",l)," ");
    gsub(" ","_",t);
    if (i==22) print" "t;
    print"|"t"| "x;
    delete a[x]
    }
}
7
ответ дан 23 November 2019 в 21:47
поделиться

Python 2.6, 347 символов

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

Вывод:

 _________________________________________________________________________
|_________________________________________________________________________| she 
|_______________________________________________________________| you 
|____________________________________________________________| said 
|_____________________________________________________| alice 
|_______________________________________________| was 
|___________________________________________| that 
|____________________________________| as 
|________________________________| her 
|_____________________________| with 
|_____________________________| at 
|____________________________| s 
|____________________________| t 
|__________________________| on 
|__________________________| all 
|_______________________| this 
|_______________________| for 
|_______________________| had 
|_______________________| but 
|______________________| be 
|_____________________| not 
|____________________| they 
|____________________| so 
8
ответ дан 23 November 2019 в 21:47
поделиться

F #, 452 символа

Прямо вперед: получить последовательность a пар количества слов, найти лучший множитель количества слов на столбец k , затем распечатайте результаты.

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

Пример (у меня другое количество частот, чем у вас, не знаю почему):

% 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
9
ответ дан 23 November 2019 в 21:47
поделиться

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

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

Альтернативная, полная реализация, включающая указанное поведение (глобальное затухание штриха) для патологического случая, когда вторичное слово и популярно, и достаточно длинно, чтобы составить более 80 chars (эта реализация - 231 chars):

$/=\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, поэтому я использовал warn() от perl вместо print - четыре символа сохранены. Использовал map вместо foreach, но мне кажется, что можно было бы еще немного сэкономить на split(join()). Тем не менее, я сократил его до 203 - может, посплю еще. По крайней мере, Perl теперь находится в списке "shell, grep, tr, grep, sort, uniq, sort, head, perl" ;)

PS: Reddit говорит "Привет" ;)

Обновление: Удалил join() в пользу присваивания и неявного скалярного преобразования join. Уменьшилось до 202. Также обратите внимание, что я воспользовался опциональным правилом "игнорировать 1-буквенные слова", чтобы сбрить 2 символа, так что имейте в виду, что подсчет частот будет отражать это.

Обновление 2: Заменил присваивание и неявное присоединение на убийство $/, чтобы получить файл в одном gulp, используя <> в первую очередь. Размер тот же, но более неприятный. Заменил if(!$y){} на $y||{}&&&, сэкономил еще 1 символ => 201.

Обновление 3: Взял под контроль раннее нижнее подчеркивание (lc<>), переместив lc из блока map - Заменил оба регекса, чтобы больше не использовать опцию /i, так как в ней больше нет необходимости. Заменена явная условная конструкция x?y:z на традиционную неявную условную конструкцию perlgolf || - /^...$/i?1:$x{$}++ на /^...$/||$x{$}++ Сэкономлено три символа! => 198, преодолен барьер в 200. Скоро спать... возможно.

Обновление 4: Недостаток сна сделал меня безумным. Ну. Более безумным. Полагая, что это должно разбирать только нормальные счастливые текстовые файлы, я заставил его сдаваться, если он встречает null. Сэкономил два символа. Заменил "length" на на 1 символ короче (и гораздо более гольфовый) y///c - слышишь, GolfScript???? Я иду за тобой!!! sob

Обновление 5: Сон заставил меня забыть об ограничении в 22 строки и ограничении последующих строк. С этими проблемами разобрался и вернулся к 208. Не так уж плохо, 13 символов для обработки - это не конец света. Поигрался с inline eval regex в perl, но у меня проблемы с тем, чтобы заставить его работать и сохранять символы... lol. Обновил пример, чтобы он соответствовал текущему выводу.

Обновление 6: Удалены ненужные скобки, защищающие (...)for, поскольку синтаксическая конфетка ++ позволяет с радостью запихнуть ее в for. Благодаря помощи Chas. Оуэнса (напомнившего моему уставшему мозгу), там появилось решение для класса символов i[tns]. Возвращаемся к 203.

Обновление 7: Добавлена вторая часть работы, полная реализация спецификаций (включая поведение с полным убиранием бара для вторичных длинных слов, вместо усечения, которое делает большинство людей, на основе оригинальной спецификации без патологического примера)

Примеры:

 _________________________________________________________________________
|_________________________________________________________________________| 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
10
ответ дан 23 November 2019 в 21:47
поделиться

C (828)

Это очень похоже на обфусцированный код, и использует glib для строк, списков и хэшей. Подсчет символов с помощью wc -m показывает 828 . При этом не учитываются однозарядные слова. Для вычисления максимальной длины строки учитывается самое длинное слово из всех возможных, а не только первые 22. Является ли это отклонением от спецификации?

Он не обрабатывает сбои и не освобождает использованную память.

#include <glib.h>
#define S(X)g_string_##X
#define H(X)g_hash_table_##X
GHashTable*h;int m,w=0,z=0;y(const void*a,const void*b){int*A,*B;A=H(lookup)(h,a);B=H(lookup)(h,b);return*B-*A;}void p(void*d,void*u){int *v=H(lookup)(h,d);if(w<22){g_printf("|");*v=*v*(77-z)/m;while(--*v>=0)g_printf("=");g_printf("| %s\n",d);w++;}}main(c){int*v;GList*l;GString*s=S(new)(NULL);h=H(new)(g_str_hash,g_str_equal);char*n[]={"the","and","of","to","it","in","or","is"};while((c=getchar())!=-1){if(isalpha(c))S(append_c)(s,tolower(c));else{if(s->len>1){for(c=0;c<8;c++)if(!strcmp(s->str,n[c]))goto x;if((v=H(lookup)(h,s->str))!=NULL)++*v;else{z=MAX(z,s->len);v=g_malloc(sizeof(int));*v=1;H(insert)(h,g_strdup(s->str),v);}}x:S(truncate)(s,0);}}l=g_list_sort(H(get_keys)(h),y);m=*(int*)H(lookup)(h,g_list_first(l)->data);g_list_foreach(l,p,NULL);}
6
ответ дан 23 November 2019 в 21:47
поделиться

Scala, 368 символов

Во-первых, разборчивая версия из 592 символов:

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

Вывод консоли выглядит следующим образом:

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

Мы можем сделать несколько агрессивных сокращений и уменьшить его до 415 символов:

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

Консольный сеанс выглядит следующим образом :

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

Я уверен, что эксперт по Scala мог бы сделать даже лучше.

Обновление: В комментариях Томас дал еще более короткую версию, из 368 символов:

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

Разборчиво, из 375 символов:

object Alice {
  def main(a:Array[String]) {
    val t = (Map[String, Int]() /: (
      for (
        x <- io.Source.fromFile(a(0)).getLines
        y <- "(?i)\\w+\\b(?<!\\bthe|and|of|to|a|i|it|in|or|is)".r.findAllIn(x)
      ) yield y.toLowerCase
    ).toList)((c, x) => c + (x -> (c.getOrElse(x, 0) + 1))).toList.sortBy(_._2).reverse.take(22)
    val w = 76 - t.head._1.length
    print (" "+"_"*w)
    t.map(s => "\n|" + "_" * (s._2 * w / t.head._2) + "| " + s._1).foreach(print)
  }
}
4
ответ дан 23 November 2019 в 21:47
поделиться

Ruby 1.9, 185 символов

(в значительной степени основан на других решениях Ruby)

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

Вместо использования каких-либо ключей командной строки, как в других решениях, вы можете просто передать имя файла в качестве аргумента. (например, ruby1.9 wordfrequency.rb Alice.txt )

Поскольку я использую здесь символьные литералы, это решение работает только в Ruby 1.9.

Edit: Заменены точки с запятой на перенос строки для "удобочитаемости". : P

Редактировать 2: Штеф указал, что я забыл конечный пробел - исправлено.

Редактировать 3: снова удален конечный пробел;)

42
ответ дан 23 November 2019 в 21:47
поделиться

Ява - 886 865 756 744 742 744 752 742 714 ] 680 символов

  • Обновления перед первым 742 : улучшено регулярное выражение, удалены лишние параметризованные типы, удалены лишние пробелы.

  • Обновление 742> 744 символа : исправлена ​​ошибка фиксированной длины. Это зависит только от первого слова, а не от других слов (пока). Найдено несколько мест для сокращения кода ( \\ s в регулярном выражении заменено на и ArrayList заменено на Vector ). Теперь я ищу короткий способ удалить зависимость ввода-вывода Commons и чтение из стандартного ввода.

  • Обновление 744> 752 символа : Я удалил зависимость общего доступа. Теперь он читается со стандартного ввода. Вставьте текст в стандартный ввод и нажмите Ctrl + Z , чтобы получить результат.

  • Обновление 752> 742 символа : я удалил public и пробел, сделал имя класса 1 символом вместо 2, и теперь он игнорирует однобуквенные слова.

  • Обновление 742> 714 символов : Обновлено в соответствии с комментариями Карла: удалено избыточное присвоение (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);
 }
}

Вывод:

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

Довольно отстой, что Java не имеет закрытий String # join () и (пока).

Правка Ротсора:

Я внес несколько изменений в ваше решение:

  • Список заменен строкой []
  • Повторно использовал аргумент 'args' вместо объявления моего собственного массива String. Также использовал его в качестве аргумента для .ToArray ()
  • Заменен StringBuffer на String (да, да, ужасная производительность)
  • Заменена сортировка Java сортировкой по выбору с ранней остановкой (нужно найти только первые 22 элемента )
  • Объединение некоторого объявления int в один оператор
  • Реализован алгоритм без мошенничества, обнаруживающий наиболее ограничивающую строку вывода. Реализовал без ФП.
  • Исправлена ​​проблема сбоя программы, когда в тексте было менее 22 различных слов.
  • Реализован новый алгоритм чтения ввода, который является быстрым и всего на 9 символов длиннее медленного.

Краткий код составляет 688 711 684 символов:

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

Быстрая версия ( 720 693 символов)

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

Более читабельный версия:

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

Версия без улучшенного поведения - 615 символов:

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

Haskell - 366 351 344 337 333 символа

(Один разрыв строки в main добавлен для удобства чтения, и не требуется перенос строки в конце последней строки.)

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 создает список слов без разделительных пробелов.
  • фильтр ( notElem слова «the and of to a i it in or is») отбрасывает все записи с запрещенными словами.
  • группа. sort сортирует слова и группирует идентичные в списки.
  • map h отображает каждый список идентичных слов в кортеж формы (- частота, слово) .
  • дубль 22. sort сортирует кортежи по убыванию частоты (первая запись кортежа) и сохраняет только первые 22 кортежа.
  • b отображает кортежи в столбцы (см. Ниже).
  • a добавляет перед первой строкой подчеркивания, чтобы завершить самую верхнюю полосу.
  • unlines объединяет все эти строки вместе с символами новой строки.

Сложная задача - получить правильную длину стержня. Я предположил, что в длину полосы учитываются только символы подчеркивания, поэтому || будет полосой нулевой длины. Функция b отображает c x на x , где x - это список гистограмм. Весь список передается в c , так что каждый вызов c может вычислить масштабный коэффициент для себя, вызывая u . Таким образом, я избегаю использования математических или рациональных чисел с плавающей запятой, функции преобразования и импорт которых потребляют много символов.

Обратите внимание на уловку с использованием -частоты . Это устраняет необходимость инвертировать сортировку , поскольку при сортировке (по возрастанию) -частота первыми будут размещены слова с наибольшей частотой. Позже в функции u умножаются два значения -частоты , что отменяет отрицание.

12
ответ дан 23 November 2019 в 21:47
поделиться

Perl, 185 символов

200 (слегка сломанный) 199 197 195 193 187 185 знаков. Последние два символа новой строки значимы. Соответствует спецификации.

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 .

Вторая строка вычисляет минимальный коэффициент масштабирования, чтобы все выходные строки были <= 80 символов.

Третья строка (содержит два символа новой строки) производит вывод.

6
ответ дан 23 November 2019 в 21:47
поделиться

Java - 896 символов

931 символ

1233 символа стали нечитаемыми

1977 символов «несжатые»


Обновление: я агрессивно уменьшил количество символов. В обновленной спецификации пропускаются однобуквенные слова.

Я очень завидую 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

Вывод Дон Кихота (также из Гутенберга):

 ________________________________________________________________________
|________________________________________________________________________| that
|________________________________________________________| he
|______________________________________________| for
|__________________________________________| his
|________________________________________| as
|__________________________________| with
|_________________________________| not
|_________________________________| was
|________________________________| him
|______________________________| be
|___________________________| don
|_________________________| my
|_________________________| this
|_________________________| all
|_________________________| they
|________________________| said
|_______________________| have
|_______________________| me
|______________________| on
|______________________| so
|_____________________| you
|_____________________| quixote
3
ответ дан 23 November 2019 в 21:47
поделиться

Scala 2.8, 311 314 320 330 332 336 341 375 символов

включая корректировку длинных слов. Идеи, заимствованные из других решений.

Теперь в виде скрипта (a.scala):

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

Запуск с

scala -howtorun:script a.scala alice.txt

BTW, правка с 314 до 311 символов на самом деле удаляет только 1 символ. Кто-то ошибся в подсчете (Windows CRs?).

4
ответ дан 23 November 2019 в 21:47
поделиться

Clojure 282 strict

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

Несколько более разборчиво:

(let[[[_ m]:as s](->> (slurp *in*)
                   .toLowerCase
                   (re-seq #"\w+\b(?<!\bthe|and|of|to|a|i[tns]?|or)")
                   frequencies
                   (sort-by val >)
                   (take 22))
     [b] (sort (map #(/ (- 76 (count (key %)))(val %)) s))
     p #(do
          (print %1)
          (dotimes[_(* b %2)] (print \_))
          (apply println %&))]
  (p " " m)
  (doseq[[k v] s] (p \| v \| k)))
4
ответ дан 23 November 2019 в 21:47
поделиться

perl, 205 191 189 символов/ 205 символов (полностью реализовано)

Некоторые части были вдохновлены более ранними работами по perl/ruby, пара похожих идей были получены независимо, остальные - оригинальные. Более короткая версия также включает в себя некоторые вещи, которые я увидел/узнал из других материалов.

Оригинал:

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

Последняя версия сокращена до 191 символа:

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

Последняя версия сокращена до 189 символов:

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

Эта версия (205 символов) учитывает строки со словами длиннее, чем те, что будут найдены позже.

/^(the|and|of|to|.|i[tns]|or)$/||$k{$_}++for map{lc=~/[a-z]+/g}<>;($r)=sort{$a<=>$b}map{(76-y///c)/$k{$_}}@e=sort{$k{$b}<=>$k{$a}}keys%k;$n=" %s
";map{printf$n,'_'x($k{$_}*$r),$_;$n="|%s| %s
";}@e[0,0..21]
11
ответ дан 23 November 2019 в 21:47
поделиться

*sh (+curl), частичное решение

Оно неполное, но, черт возьми, вот половина задачи в 192 байтах, подсчитывающая частоту слов:

curl -s http://www.gutenberg.org/files/11/11.txt|sed -e 's@[^a-z]@\n@gi'|tr '[:upper:]' '[:lower:]'|egrep -v '(^[^a-z]*$|\b(the|and|of|to|a|i|it|in|or|is)\b)' |sort|uniq -c|sort -n|tail -n 22
7
ответ дан 23 November 2019 в 21:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: