Побудуйте діаграму ASCII з найбільш часто вживаних слів у заданому тексті [закрито]


156

Змагання:

Побудуйте 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).

  • Необов’язково (зараз вже занадто пізно формально змінювати технічні характеристики), ви можете відмовитись від однослівних «слів» (це може призвести і до скорочення списку ігнору).

Проаналізуйте заданий text(прочитайте файл, вказаний за допомогою аргументів командного рядка або прокладений в; припустімо us-ascii) та побудуйте нам word frequency chartтакі характеристики:

  • Покажіть діаграму (також див. Приклад нижче) для 22 найпоширеніших слів (упорядкованих за низхідною частотою).
  • Рядок widthпредставляє кількість випадків (частоти) слова (пропорційно). Додайте один пробіл і надрукуйте слово.
  • Переконайтеся, що ці рядки (плюс пробіл-слово-пробіл) завжди відповідають : bar+ [space]+ word+ [space]має бути завжди <= 80символів (переконайтеся, що ви враховуєте можливі різні довжини рядків і слів: наприклад: друге найпоширеніше слово може бути набагато довшим, ніж тоді перший при цьому не сильно відрізняється частотою). Максимально збільшуйте ширину смуги в межах цих обмежень і масштабуйте смуги відповідно (відповідно до частот, які вони представляють).

Приклад:

Текст прикладу можна знайти тут ( Пригоди Аліси в країні чудес, Льюїс Керролл ).

Цей конкретний текст дасть таку таблицю:

 _________________________________________________________________________
| _________________________________________________________________________ | вона
| _______________________________________________________________ | ти
| ____________________________________________________________ | сказав
| ____________________________________________________ | Аліса
| ______________________________________________ | був
| __________________________________________ | що
| ___________________________________ | як
| _______________________________ | її
| ____________________________ | з
| ____________________________ | у
| ___________________________ | с
| ___________________________ | т
| _________________________ | на
| _________________________ | всі
| ______________________ | це
| ______________________ | для
| ______________________ | мав
| _____________________ | але
| ____________________ | бути
| ____________________ | ні
| ___________________ | Вони
| __________________ | так


Для вашої інформації: це частоти, на яких будується вищевказана діаграма:

[('вона', 553), ('ти', 481), ('сказано', 462), ('alice', 403), ('було', 358), ('що
', 330), (' як ', 274), (' її ', 248), (' з ', 227), (' у ', 227), (' s ', 219), (' t '
, 218), ('на', 204), ('все', 200), ('це', 181), ('за', 179), ('мав', 178), ('
але ', 175), (' бути ', 167), (' не ', 166), (' вони ', 155), (' так ', 152)]

Другий приклад (щоб перевірити, чи ви реалізували повну специфікацію): Замініть кожне виникнення youу пов'язаному файлі Alice in Wonderland на superlongstringstring:

 ________________________________________________________________
| ________________________________________________________________ | вона
| _______________________________________________________ | супердовжинні струни
| _____________________________________________________ | сказав
| ______________________________________________ | Аліса
| ________________________________________ | був
| _____________________________________ | що
| ______________________________ | як
| ___________________________ | її
| _________________________ | з
| _________________________ | у
| ________________________ | с
| ________________________ | т
| ______________________ | на
| _____________________ | всі
| ___________________ | це
| ___________________ | для
| ___________________ | мав
| __________________ | але
| _________________ | бути
| _________________ | ні
| ________________ | Вони
| ________________ | так

Переможець:

Найкоротше рішення (за кількістю символів, за мовою). Веселіться!


Редагувати : Таблиця, що підсумовує результати до цього часу (2012-02-15) (спочатку додав користувач Нас Банов):

Мова розслаблена строга
========= ======= ======
GolfScript 130 143
Perl 185
Windows PowerShell 148 199
Mathematica 199
Рубі 185 205
Unix Toolchain 194 228
Пітон 183 243
Clojure 282
Scala 311
Haskell 333
Awk 336
R 298
Javascript 304 354
Гровий 321
Матлаб 404
C # 422
Малийрозмова 386
PHP 450
F # 452
TSQL 483 507

Цифри представляють довжину найкоротшого рішення певної мови. "Строгий" відноситься до рішення, яке повністю реалізує специфікацію (малює |____|смуги, закриває перший рядок зверху ____рядком, враховує можливість довгих слів з високою частотою тощо). "Розслаблений" означає, що деякі свободи були прийняті, щоб скоротити рішення.

Включаються лише рішення, менші за 500 символів. Список мов відсортований за довжиною «суворого» рішення. "Unix Toolchain" використовується для позначення різних рішень, які використовують традиційну оболонку * nix плюс суміш інструментів (наприклад, grep, tr, sort, uniq, head, perl, awk).


4
Ну, а "найдовший штрих" + слово = 80 може не вміщуватися в межах 80 копійок, якщо друге найпоширеніше слово - це набагато довше слово. Я думаю, що "максимальне обмеження" я думаю.
Брайан

1
Чи нормалізуємо ми корпус? 'Вона' = 'вона'?
Брайан

2
ІМО, що робить це виконанням, як за часом виконання, так і за обсягом використання пам'яті, здається більш цікавим завданням, ніж кількість символів.
Френк Фермер

81
Я радий бачити, що мої улюблені слова sі tпредставлені.
indiv

8
@indiv, @Nas Banov - нерозумно занадто простий токенізатор читає "не" як {didn, t} і "she's" як {she, s} :)
hobbs

Відповіді:


123

LabVIEW 51 вузол, 5 структур, 10 діаграм

Навчити слона танцювати ніколи не буває досить. Я, ах, пропускаю кількість персонажів.

код labVIEW

результати

Програма тече зліва направо:

пояснено код labVIEW


10
ЦЕ НЕ варто

4
LabVIEW дуже щасливий у своїй апаратній ніші для управління та вимірювання, але насправді дуже жахливий для маніпуляцій із струнами.
Джо Z

19
Найкращий відповідь на гольф з кодом, який я бачив. +1 для роздумів поза межами!
Блер Холлоуей

1
Треба порахувати елементи для нас ... кожне поле та віджет, які вам довелося перетягнути на екран, враховуються.
dmckee --- колишнє кошеня-модератор

1
Чи можна було б додати посилання на більшу версію цих діаграм?
Свиш

42

Рубін 1,9, 185 символів

(значною мірою базується на інших рішеннях Ruby)

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

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

Оскільки я тут використовую символи-літерали, це рішення працює лише в Ruby 1.9.

Редагувати: Замінено крапками з комою на розриви рядків для "читабельності". : P

Редагування 2: Штееф зазначив, що я забув простір, що залишився, - це виправлено.

Редагувати 3: Знову видалено простір;)


У ньому відсутнє пробіл після кожного слова.
Stéphan Kochen

Aww стріляй, ігноруй це. Схоже на те, що гольф щойно оновлений, простір більше не потрібно. :)
Stéphan Kochen

Чи не здається, що він підходить для "надвисокої струни" у другій чи пізнішій позиції? (див. опис проблеми)
Нас Банов

2
Це виглядає справді ретельно.
Зомбі

39

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

Повільний - 3 хвилини для зразкового тексту (130)

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

Пояснення:

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

"Правильно" (сподіваємось). (143)

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

Менш повільно - півхвилини. (162)

'"'/' ':S*n/S*'"#{%q
'\+"
.downcase.tr('^a-z','
')}\""+~n%"oftoitinorisa"2/-"theandi"3/-$(1@{.3$>1{;)}if}/]2/{~~\;}$22<.0=~:2;,76\-:1'_':0*S\@{"
|"\~1*2/0*'| '@}/

Вихідні дані видно в журналах ревізії.


2
Про GolfScript: golfscript.com/golfscript
Assaf Lavie

2
Неправильно, якщо друге слово дійсно довге, воно перетвориться на наступний рядок.
Гейб

5
"ділити на нуль" ... GolfScript це дозволяє?
JAB

35

206

оболонка, греп, тр, греп, сортування, унік, сортування, голова, перл

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

хм, щойно видно вище: sort -nr-> sort -nа потім head-> tail=> 208 :)
update2: erm, звичайно, вище сказане нерозумно, оскільки це буде перевернуто тоді. Отже, 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

Трансактне рішення на основі набору SQL (SQL Server 2005) 1063 892 873 853 827 820 783 683 647 644 630 символів

Дякую Гейбу за кілька корисних пропозицій щодо зменшення кількості персонажів.

Примітка: для уникнення смуг прокрутки додаються розриви рядків, потрібен лише останній розрив рядка.

DECLARE @ VARCHAR(MAX),@F REAL SELECT @=BulkColumn FROM OPENROWSET(BULK'A',
SINGLE_BLOB)x;WITH N AS(SELECT 1 i,LEFT(@,1)L UNION ALL SELECT i+1,SUBSTRING
(@,i+1,1)FROM N WHERE i<LEN(@))SELECT i,L,i-RANK()OVER(ORDER BY i)R INTO #D
FROM N WHERE L LIKE'[A-Z]'OPTION(MAXRECURSION 0)SELECT TOP 22 W,-COUNT(*)C
INTO # FROM(SELECT DISTINCT R,(SELECT''+L FROM #D WHERE R=b.R FOR XML PATH
(''))W FROM #D b)t WHERE LEN(W)>1 AND W NOT IN('the','and','of','to','it',
'in','or','is')GROUP BY W ORDER BY C SELECT @F=MIN(($76-LEN(W))/-C),@=' '+
REPLICATE('_',-MIN(C)*@F)+' 'FROM # SELECT @=@+' 
|'+REPLICATE('_',-C*@F)+'| '+W FROM # ORDER BY C PRINT @

Читаема версія

DECLARE @  VARCHAR(MAX),
        @F REAL
SELECT @=BulkColumn
FROM   OPENROWSET(BULK'A',SINGLE_BLOB)x; /*  Loads text file from path
                                             C:\WINDOWS\system32\A  */

/*Recursive common table expression to
generate a table of numbers from 1 to string length
(and associated characters)*/
WITH N AS
     (SELECT 1 i,
             LEFT(@,1)L

     UNION ALL

     SELECT i+1,
            SUBSTRING(@,i+1,1)
     FROM   N
     WHERE  i<LEN(@)
     )
  SELECT   i,
           L,
           i-RANK()OVER(ORDER BY i)R
           /*Will group characters
           from the same word together*/
  INTO     #D
  FROM     N
  WHERE    L LIKE'[A-Z]'OPTION(MAXRECURSION 0)
             /*Assuming case insensitive accent sensitive collation*/

SELECT   TOP 22 W,
         -COUNT(*)C
INTO     #
FROM     (SELECT DISTINCT R,
                          (SELECT ''+L
                          FROM    #D
                          WHERE   R=b.R FOR XML PATH('')
                          )W
                          /*Reconstitute the word from the characters*/
         FROM             #D b
         )
         T
WHERE    LEN(W)>1
AND      W NOT IN('the',
                  'and',
                  'of' ,
                  'to' ,
                  'it' ,
                  'in' ,
                  'or' ,
                  'is')
GROUP BY W
ORDER BY C

/*Just noticed this looks risky as it relies on the order of evaluation of the 
 variables. I'm not sure that's guaranteed but it works on my machine :-) */
SELECT @F=MIN(($76-LEN(W))/-C),
       @ =' '      +REPLICATE('_',-MIN(C)*@F)+' '
FROM   #

SELECT @=@+' 
|'+REPLICATE('_',-C*@F)+'| '+W
             FROM     #
             ORDER BY C

PRINT @

Вихідні дані

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

І з довгою струною

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

12
Я дав вам +1, тому що ви робили це в T-SQL, і цитую Team America - "У вас є кулі. Мені подобаються м'ячі".

Я взяв на себе можливість перетворити деякі простори в нові рядки, щоб зробити його більш читабельним. Сподіваюся, я не зіпсував справи. Я також трохи поменшав його.
Гейб

3
Цей код кричить на мене! : O
Joey

1
Один хороший спосіб зберегти - змінити 0.000на справедливий 0, а потім використовувати -Cзамість цього 1.0/C. І введення FLOATв REALекономію також врятує інсульт. Найголовніше, однак, це те, що схоже, що у вас є безліч ASпримірників, які повинні бути необов’язковими.
Гейб

1
Добре, а як SELECT [ ] FROM (SELECT $0 O, ' '+REPLICATE('_', MAX(C)*@F)+' ' [ ] FROM # UNION SELECT $1/C, '|'+REPLICATE('_',C*@F)+'| '+W FROM #)X ORDER BY O?
Гейб

34

Рубін 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. EDIT: Не працює, змінює довжину. EDIT: Не гірше, ніж раніше
Edit7: Використовувати STDIN.read.


+1 - люблю сортувальну частину, дуже розумна :)
Anurag

Гей, невелика оптимізація порівняно з придумкою її основної частини. :)
аргумент

Приємно! Додано дві зміни, які я також вніс у версію Anurag. Поголить ще 4.
Стефан Кохен

Рішення відхилилося від вихідного результату, я спробую зрозуміти, де це сталося.
аргумент

1
Далі є коротший варіант цього.
аргумент

28

Математика ( 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)

Вихідні дані

alt текст http://i49.tinypic.com/2n8mrer.jpg

Mathematica не дуже підходить для гольфу, і це лише через довгі описові назви функцій. Такі функції, як "RegularExpression []" або "StringSplit []", просто змушують мене плакати :(.

Тестування закону Зіпфа

Закон Зіпфа передбачає, що для тексту на природній мові Схема Журнал (Ранг) проти Журналу (входження) дотримується лінійної залежності.

Закон використовується при розробці алгоритмів криптографії та стиснення даних. (Але це НЕ "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 текст http://i46.tinypic.com/33fcmdk.jpg

Правка 6> (242 символів)

Рефакторинг Regex (функція вибору більше не
відміняється ) Видалення 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на Transposeта Slot( #1/#2 ) аргументів.
  • Нам не потрібно ніяких смердючих дужок (використовувати f@xзамість того, f[x]де це можливо)


9
Ви вважаєте, що "RegularExpression" поганий? Я плакала, коли я набрала "System.Text.RegularExpressions.Regex.Split" у версію C #, поки не побачила код Objective-C: "stringWithContentsOfFile", "enumerateSubstringsInRange", "NSStringEnumerationByWords", "sortedArpaUUrationPsing .
Гейб

2
@Gabe Спасибі ... я почуваюся зараз краще. Іспанською мовою ми говоримо "mal de muchos, consuelo de tontos". Щось на кшталт "Багато проблемних, дурні полегшені": D
доктор belisarius

1
У |i|вашому регексе це надмірне значення, оскільки воно вже є .|.
Гейб

1
Мені подобається ця іспанська приказка. Найближче, що я можу придумати англійською, - це «бідність любить компанію». Ось моя спроба перекладу: "Дурний, хто, страждаючи, втішається в думці про інших людей у ​​тій же ситуації". Дивовижна робота над реалізацією Mathematica, btw.
дрівс

@dreeves Дурність легко перевершує мовний бар'єр ... Радий бачити, що ти любиш мою маленьку програму Mathematica, я тільки починаю вивчати мову
доктор belisarius

26

C # - 510 451 436 446 434 426 422 символів (мінімізовано)

Не так коротко, але зараз, напевно, правильно! Зауважте, попередня версія не показувала перший рядок смужок, не масштабувала бруски правильно, завантажувала файл замість того, щоб отримати його зі stdin та не включала всіх необхідних багатослівностей C #. Ви можете легко погладити багато ударів, якщо C # не знадобилося стільки зайвого лайна. Можливо, Пауершелл міг би зробити краще.

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

+1 для смарт-дупи, яка завантажує файл в рядку. :)
сарнольд

1
Вкрасти коротку URL-адресу з відповіді Метта.
indiv

2
Специфікація заявила, що файл повинен бути прокладений або переданий як арг. Якщо ви припускаєте, що в аргументах [0] міститься ім'я локального файлу, ви можете його значно скоротити, використовуючи аргументи [0] замість (новий WebClient ()) . txt " ) -> це дозволить вам заощадити приблизно 70 символів
thorkia

1
Ось версія, що замінює виклик WebClient аргументами 0, викликом StreamReader та видаляє кілька зайвих пробілів. Загальна кількість символів = 413 var a = Regex.Replace ((новий StreamReader (args [0])). ReadToEnd (), "[^ a-zA-Z]", "") .ToLower (). Спліт ('' ) .Where (x =>! (New [] {"the", "and", "of", "to", "a", "i", "it", "in", "or", " є "}). Містить (x)). GroupBy (x => x) .Select (g => new {w = g.Key, c = g.Count ()}). OrderByDescending (x => xc). Пропустити (1) .Take (22) .ToList (); var m = a.OrderByDescending (x => xc). First (); a.ForEach (x => Console.WriteLine ("|" + new String (' _ ', xc * (80-mwLength-4) / mc) + "|" + xw));
thorkia

"новий StreamReader" без "використання" забруднений. File.ReadAllText (args [0]) або Console.In.ReadToEnd () набагато кращі. В останньому випадку ви навіть можете видалити аргумент із вашого Main (). :)
Ротсор

25

Перл, 237 229 209 символів

(Оновлено знову, щоб перемогти версію Ruby з більш брудними хитрощами, замінивши split/[^a-z/,lcнаlc=~/[a-z]+/g , і усунення чек на порожній рядок в іншому місці. Вони були натхненні версії Рубі, тому кредит , де кредит повинен.)

Оновлення: тепер з Perl 5.10! Замінити printз say, і використовувати ~~щоб уникнути map. Це потрібно викликати в командному рядку як perl -E '<one-liner>' 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;

Зараз має кілька помилок; фіксація та скорочення.
JSB ձոգչ

4
Це не стосується випадку, коли друге слово набагато довше першого, правда?
Joey

1
Обидва foreachs можна записати як fors. Це на 8 символів вниз. Тоді у вас є те grep{!($_~~@s)}map{lc=~/[a-z]+/g}<>, що, на мою думку, можна було б написати так, grep{!(/$_/i~~@s)}<>=~/[a-z]+/gщоб піти ще на 4. Замінити " "з $"і ви вниз 1 більше ...
Заїд

sort{$c{$b}-$c{$a}}...щоб зберегти ще два. Ви також можете просто передати %cзамість keys %cдо sortфункції і більш зберегти чотири.
мафія

20

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

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

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

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

Припущення:

  • США ASCII як вхід. Це, мабуть, стає дивно з Unicode.
  • Принаймні два безперервних слова в тексті

Історія

Розслаблена версія (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 символів.

Старішу пояснену версію можна знайти тут .


Вражає, здається, Powershell - це придатне середовище для гри в гольф. Ваш підхід з огляду на довжину бруска - це саме те, що я намагався описати (не так блискуче, зізнаюся) у специфікації.
ChristopheD

1
@ChristopheD: На моєму досвіді (Anarchy Golf, деякі завдання Project Euler та деякі інші завдання лише для задоволення), PowerShell, як правило, трохи гірший за Ruby і часто пов'язаний з Perl і Python. Однак, для GolfScript немає відповідності. Але наскільки я бачу, це може бути найкоротшим рішенням, яке правильно враховує довжину смуги ;-)
Joey

Мабуть, я мав рацію. Powershell може зробити краще - набагато краще! Надайте розширену версію з коментарями.
Габе

Йоганнес: Ти спробував -split("\b(?:the|and|of|to|a|i[tns]?|or)\b|[^a-z]")? Це працює для мене.
Гейб

Не забудьте інтерполювати вихідний рядок: "|$('_'*($w*$_.count/$x[0].count))| $($_.name) "(або усунути останній пробіл, як це начебто автоматичний). І ви можете використовувати -split("(?:\b(?:the|and|of|to|a|i[tns]?|or)\b|[^a-z])+")для збереження ще декількох, не включаючи пробіли (або використовувати [-2..-23]).
Гейб

19

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

оновлення 1: Ура ! Це зв'язок з JS чубчиком ' рішення . Не можу придумати спосіб зменшити більше :)

оновлення 2: зіграв брудний трюк з гольфу. Змінено eachнаmap зберегти 1 символ :)

оновлення 3: Змінено File.readна IO.read+2. Array.group_byне дуже плідно, змінили на reduce+6. Справа на нечутливу перевірку не потрібна після нижнього корпусуdowncase регексом +1. Сортування в порядку зменшення легко здійснити, відкинувши значення +6. Загальна економія +15

оновлення 4: [0]замість .first, +3. (@ Штееф)

оновлення 5: Розгорніть змінну lна місці, +1. Розгорніть змінну sна місці, +2. (@ Штееф)

оновлення 6: Використовуйте додавання рядків, а не інтерполяцію для першого рядка, +2. (@ Штееф)

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, хоча, можливо, є потенціал. Збереження попередньої версії, тому що я вважаю, що це чорна магія. (@ Штееф)

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

Читаема версія

string = File.read($_).downcase

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

word_length = highest_frequency_word.size
widest = 76 - word_length

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

Використовувати:

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

Вихід:

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

3
Чи не "p" ярлик для "put"? Це могло б поголити декілька.
rfusca

1
Приємно. Ти scan, однак, твій досвід дав мені кращу ідею, тому я знову випереджав :).
JSB ձոգչ

2
Потрібно масштабувати смуги, щоб найдовше слово плюс його смужка вмістилося на 80 символів. Як запропонував Брайан, довге друге слово порушить вашу програму.
Габе

3
Цікаво, чому це все-таки збирає голоси. Рішення є невірним (у загальному випадку) і на сьогоднішній день тут вже є два шляхи коротших рішень Ruby.
Joey

1
Тепер, виправте мене, якщо я помиляюся, але замість того, щоб використовувати "нижню букву", чому ви не використовуєте прапор REGEXP, нечутливий до регістру, що зберігає 6-7 байт, чи не так?
st0le

19

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

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

Дозволяючи свободу в реалізації, я сконструював рядок конкатенації, який містить усі слова, що вимагаються для виключення (the, and, of, to, a, i, it, in, or, is ) - плюс це також виключає два сумнозвісних "слова" sта tз прикладу - і я безкоштовно кинув виключення для an, for, he. Я спробував усі сполучення цих слів проти корпусу слів з Аліси, Біблії короля Джеймса та файлу Жаргона, щоб побачити, чи є слова, які будуть неправильно виключені рядком. І ось так я закінчився двома рядками виключення: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

Рант

Щодо слів, що їх ігнорувати, можна подумати, що вони будуть взяті зі списку найбільш вживаних слів англійською мовою. Цей список залежить від використовуваного текстового корпусу . За одним із найпопулярніших списків ( 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
10 кращих слів з файлу жаргону (v4.4.7)the a of to and in is that or for

Тож питання чому or було включено до списку ігнорування проблеми, де це ~ 30-та популярність, коли слово that(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 слів, які потрібно виключити the, and, of, to, a, i, it, in, or, is , щоб вони передавались як параметри командного рядка, наприклад:
python WordFrequencyChart.py the and of to a i it in or is <"Alice's Adventures in Wonderland.txt"

Це 213 символів + 30, якщо ми враховуємо "оригінальний" список ігнорування, переданий у командному рядку = 243

PS. Другий код також робить "коригування" за довжиною всіх верхніх слів, тому жодне з них не переповниться у виродженому випадку.

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

Приємне рішення поки що, хоча список ігнорувань слів не реалізований (поки що), і бари на даний момент трохи рудиментарні.
ChristopheD

@ChristopheD: він був там, але "посібника користувача" не було. Щойно доданий текст тексту
Нас Банов

Стосовно вашого списку мов та рішень: Будь ласка, шукайте рішення, які використовують розщеплення уздовж \Wабо використання \bв регулярному виразі, оскільки вони, швидше за все, не відповідають специфікації, тобто вони не розбиваються на цифри, або _вони також не можуть видаляти стоп-слова з рядків таких як the_foo_or123bar. Вони можуть не відображатися в тестовому тексті, але специфікація досить чітка для цього випадку.
Joey

Дивовижна робота Nas, я провів південь, намагаючись оптимізувати це, і знайшов лише одне вдосконалення. Ви можете скоротити його до 239 символів, видаливши sys.argvхак і скориставшись:re.findall(r'\b(?!(?:the|and|.|of|to|i[tns]|or)\b)\w+',sys.stdin.read().lower())
intgr

12

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 створює список слів, скидаючи розділовий пробіл.
  • filter (notElem words "the and of to a i it in or is")відкидає всі записи із забороненими словами.
  • group . sort сортує слова та згрупує однакові слова у списки.
  • map h відображає кожен список однакових слів на кордоні форми (-frequency, word) .
  • take 22 . sort сортує кортежі за низхідною частотою (перший запис кортежу) та зберігає лише перші 22 кортежі.
  • b відображає кортежі до барів (див. нижче).
  • a попередньо виділяє перший рядок підкреслення, щоб завершити верхню смугу.
  • unlines з'єднує всі ці рядки разом з новими рядками.

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

Зверніть увагу на хитрість використання -frequency. Це усуває необхідність в з моменту сортування ( по зростанню) буде місце слова з найбільшою частотою в першу чергу. Пізніше у функції множать два значення, які скасують заперечення.reversesort-frequencyu-frequency


Дуже приємна робота (підкреслила б, але сьогодні не вистачало голосів з усіма чудовими відповідями в цій темі).
ChristopheD

Це болить мої очі таким чином, що боляче навіть думати про опис, але я багато навчився Haskell шляхом зворотного введення його в розбірливий код. Молодці, сер. :-)
Оуен С.

Це насправді досить ідіоматичний Хаскелл, але не дуже ефективний. Короткі назви дозволяють виглядати набагато гірше, ніж є насправді.
Томас

@Thomas: Ви можете сказати це ще раз. :-)
Оуен С.

1
divНасправді не можна перемістити Спробуйте - вихід неправильний. Причина в тому, що робити divраніше, ніж *втрачає точність.
MtnViewMark

11

JavaScript 1.8 (SpiderMonkey) - 354

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

На жаль, for([k,v]in z)версія Rhino, здається, не хоче працювати в SpiderMonkey, і readFile()трохи простіше, ніж використовувати, readline()але переміщення до 1,8 дозволяє нам використовувати функції закриття, щоб скоротити ще кілька рядків ....

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

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

Використання: js golf.js < input.txt

Вихід:

 _________________________________________________________________________ 
| _________________________________________________________________________ | вона
| _______________________________________________________________ | ти
| ____________________________________________________________ | сказав
| ____________________________________________________ | Аліса
| ______________________________________________ | був
| ___________________________________________ | що
| ___________________________________ | як
| ________________________________ | її
| _____________________________ | у
| _____________________________ | з
| ____________________________ | с
| ____________________________ | т
| __________________________ | на
| _________________________ | всі
| _______________________ | це
| ______________________ | для
| ______________________ | мав
| ______________________ | але
| _____________________ | бути
| _____________________ | ні
| ___________________ | Вони
| ___________________ | так

(базова версія - неправильно обробляє ширину смуги)

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

Я думаю, що моя логіка сортування вимкнена, але .. я дуно. Брейнфарт виправлений.

Мінімізовано (зловживання \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)}

Ах, сер. Я вважаю, це ваша рукавичка. Попросіть друге поговорити зі своїм.
dmckee --- колишнє кошеня-модератор

2
BTW-- Мені подобається i[tns]?трохи. Дуже підлий.
dmckee --- кошеня колишнього модератора

@dmckee - добре зіграний, я не думаю, що я можу перемогти твій 336, насолоджуйся своїм заслуженим надбавкою :)
Метт

Ви можете точно перемогти 336 ... Є 23 скорочення символів - .replace(/[^\w ]/g, e).split(/\s+/).map(можна замінити .replace(/\w+/g,і використовувати ту ж функцію, що і ви .map... Також не впевнений, чи підтримує Rhino function(a,b)b.c-a.cзамість вашої функції сортування (робить павук), але це буде гоління {return }... b.c-a.cє кращим сортом, який a.c<b.cдо речі ... Редагування версії Spidermonkey внизу з цими змінами
gnarf

Я перемістив свою версію SpiderMonkey до верху, оскільки вона відповідає обмеженню ширини смуги ... Також мені вдалося вирізати ще кілька символів у вашій початковій версії, використовуючи негативне regexp lookahead, щоб заперечувати слова, що дозволяють проводити одну заміну (), та гольфували нечисленні ifs з Чудовою ?:базою для роботи з хоча!
gnarf

11

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

Це рішення враховує останню вимогу, яку більшість пуристів незмінно вирішили ігнорувати. Це коштувало 170 символів!

Використання: php.exe <this.php> <file.txt>

Мінімізовано:

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

Людина, читана:

<?php

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

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

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

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

// Sort:
arsort($a);

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


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

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


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

?>

Вихід:

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

Коли є довге слово, бруски регулюються належним чином:

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

11

Python 3.1 - 245 229

Я думаю, що використання 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.


Перший рядок відсутній. І довжина планки не вірна.
Joey

у вашому коді здається, що open('!')читається зі stdin - на якій версії / ОС це включено? чи вам потрібно назвати файл "!"?
Нас Банов

Назвіть файл "!" :) Вибачте, це було досить незрозуміло, і я повинен був це згадати.
Сем Долан

11

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

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

Оригінал:

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

Остання версія до 191 символу:

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

Остання версія до 189 символів:

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

Ця версія (205 знаків) обчислює рядки зі словами, довшими за те, що було б знайдено пізніше.

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

10

Perl: 203 202 201 198 195 195 208 203/231 символів

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

Почергова, повна реалізація, включаючи вказувану поведінку (глобальний стрибкоподібний порядок) для патологічного випадку, коли вторинне слово є популярним і досить довгим, щоб поєднати більше 80 символів ( ця реалізація становить 231 символів ):

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

У специфікації ніде не вказано, що це потрібно перейти до STDOUT, тому я використав perl’s warn () замість друку - там збереглися чотири символи. Використовувана карта замість передбачення, але я відчуваю, що все-таки можна було б зекономити на розщепленні (join ()). Але все-таки знизився до 203 року - може спати на ньому. Принаймні, Perl зараз під знаком "shell, grep, tr, grep, sort, uniq, sort, head, perl";)

PS: Reddit каже "Привіт";)

Оновлення: Видалене з'єднання () на користь присвоєння та неявне скалярне перетворення. Знизу до 202. Також зверніть увагу, що я скористався необов’язковим правилом "ігнорувати слова з 1 літери", щоб вистригти 2 символи, тому майте на увазі, що частота відображатиме це.

Оновлення 2: Замінено призначення та неявне приєднання для вбивства $ / щоб отримати файл одним глотком за допомогою <> в першу чергу. Той же розмір, але більш неприємний. Замінено, якщо (! $ Y) {} для $ y || {} &&, збережено ще 1 char => 201.

Оновлення 3: Рано взяв на себе керування нижньою обробкою (lc <>), перемістивши lc з блоку карти - замінили обидва регулярні вирази, щоб більше не використовувати параметр / i, як більше не потрібно. Поміняв явний умовний x? Y: z конструкцію для традиційного perlgolf || неявна умовна конструкція - /^...$/i?1:$x{$ } ++ для /^...$/||$x{$ } ++ Збережено три символи! => 198, зламав 200 бар'єр. Можливо, незабаром спати ... можливо.

Оновлення 4: Депривація сну зробила мене божевільним. Ну. Більш божевільний. Зрозумівши, що для цього потрібно розібрати лише звичайні текстові файли щасливого тексту, я змусив його відмовитись, якщо він потрапляє в нуль. Збережено два символи. "Довжина" замінена на 1-коротку коротку (і набагато більше гольфу) y /// c - ви мене чуєте, GolfScript ?? Я йду за тобою!!! ридання

Оновлення 5: Демонстрація сну змусила мене забути про обмеження 22row та обмеження наступного рядка. Завантажте до 208 із обробленими. Не так вже й погано, 13 символів, щоб впоратися, це не кінець світу. Зіграли з регулярним виразком Perl inline eval, але не мали труднощів отримати його як до роботи, так і до збереженням символів ... lol. Оновлено приклад, щоб відповідати поточному виводу.

Оновлення 6: Видалено непотрібні брекети, що захищають (...) для, оскільки синтаксична цукерка ++ дозволяє підштовхувати її проти "на щастя". Завдяки вкладенню 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

Ви можете скоротити регулярний вираз слова для зупинки, збільшивши is|in|it|iйого, i[snt]?- і тоді вже немає різниці з додатковим правилом. (Гм, я ніколи б не замислювався над тим, щоб сказати хлопцеві Perl, як робити Regex: D) - єдина проблема зараз: я мушу подивитися, як я можу збрити три байти з власного рішення, щоб знову бути кращим за Perl: - |
Joey

Гаразд, нехтуй частиною того, що я казав раніше. Ігнорування однобуквенних слів справді є байтом коротшим, ніж не робити цього.
Joey

Кожен байт має значення;) Я розглядав трюк у новому рядку, але вважав, що це насправді однакова кількість байтів, навіть якщо це менше символів для друку. Я все ще працюю над тим, чи зможу я це трохи зменшити :)
Syntaera

Ну добре, нормалізація випадків повернула мене до 209. Я не бачу, що ще я міг би скоротити. Хоча PowerShell може бути коротшим, ніж Perl. ;-)
Joey

Я не бачу, де ви обмежуєте вихід на 22 найпопулярніші слова, а також де не переконайтеся, що довге друге слово не загорнеться.
Габе

9

F #, 452 символів

Зрозуміло: отримайте послідовність aпар лічильників слів, знайдіть кращий множник слів на колонку k, а потім виведіть результати.

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

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

% app.exe < Alice.txt

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

виявляється, моє власне рішення насправді було трохи вимкнено (завдяки трохи іншим специфікаціям), рішення відповідають зараз ;-)
ChristopheD

+1 за єдину досі правильну реалізацію масштабування смуги
Ротсор

2
(@Rotsor: Іронічно, зважаючи на те, що моє найдавніше рішення.)
Брайан

Надіваюсь, ви могли трохи скоротити її, об'єднавши етапи розділення, карти та фільтра. Я також очікував, що вам не знадобиться стільки floatс.
Габе

Хіба що функції гніздування зазвичай не коротші, ніж використання оператора трубопроводу |>?
Joey

8

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

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

Вихід:

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

1
Ви можете втратити рядок, bm=(76.-len(W[0][0]))/W[0][1]оскільки ви лише один раз використовуєте bm (зробіть наступний рядок U=lambda n:"_"*int(n*(76.-len(W[0][0]))/W[0][1]), обстригайте 5 символів. Також: чому б ви використовували 2-символьне ім'я змінної у гольф-коді ?;-)
ChristopheD

На останньому рядку пробіл після друку не потрібен, оббриває один символ
ChristopheD

1
Не вважає випадок, коли друге найчастіше слово дуже довге, правда?
Joey

@ChristopheD: Тому що я занадто довго дивився на цей код. : P Хороший улов. @Johannes: Це теж можна виправити, так. Не впевнений, що всі інші реалізації робили це, коли я писав це.
AKX

7

* ш (+ завиток), часткове рішення

Це є неповним, але для чорта, ось частота слів, що рахує половину проблеми в 192 байтах:

curl -s http://www.gutenberg.org/files/11/11.txt|sed -e 's@[^a-z]@\n@gi'|tr '[:upper:]' '[:lower:]'|egrep -v '(^[^a-z]*$|\b(the|and|of|to|a|i|it|in|or|is)\b)' |sort|uniq -c|sort -n|tail -n 22

7

Гаук - 336 (спочатку 507) символів

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

Хе-хе! Я на мить передую [Метт JavaScript] [1] зустрічний виклик рішення ! ;) та [пітон AKX] [2].

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

Це все надзвичайно неефективно, і з усіма створеними мною голфіфкаціями це також було дуже жахливо.

Мінімізовано:

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

рядкові перерви лише для наочності: вони не потрібні і їх не слід зараховувати.


Вихід:

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

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

{
    gsub("[^a-zA-Z]"," ");
    for(;NF;NF--)
    a[tolower($NF)]++
}
END{
    # remove "short" words
    split("the and of to a i it in or is",b," ");
    for (w in b) 
    delete a[b[w]];
    # Find the bar ratio
    d=1;
    for (w in a) {
    e=a[w]/(78-length(w));
    if (e>d)
        d=e
    }
    # Print the entries highest count first
    for (i=22; i; --i){               
    # find the highest count
    e=0;
    for (w in a) 
        if (a[w]>e)
        e=a[x=w];
        # Print the bar
    l=a[x]/d-2;
    # make a string of "_" the right length
    t=sprintf(sprintf("%%%dc",l)," ");
    gsub(" ","_",t);
    if (i==22) print" "t;
    print"|"t"| "x;
    delete a[x]
    }
}

Гарна робота, добре, що ви включили з відступною / коментованою версією ;-)
ChristopheD

7

Загальний LISP, 670 символів

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

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

можна запустити, наприклад, з cat alice.txt | clisp -C golf.lisp.

У читаному вигляді є

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

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

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

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

       ; add alphabetic to current word, and bump word counter
       ; on non-alphabetic
       (cond
        ((char<= #\a x #\z)
         (push x w))
        (t
         (incf (gethash (concatenate 'string (reverse w)) c 0))
         (setf w nil)))))

чи намагалися ви встановити макрос користувальницького зчитувача для гоління певного розміру вводу?
Аарон

@Aaron насправді це не було тривіально для мене, навіть я просто працюю цим ... :-) для фактичної частини гольфу, я просто використав змінні з однієї літери, і це все. У всякому разі, окрім дещо високої багатослівності, яка притаманна CL для цієї шкали проблем ("concatenate 'string", "setf" або "gethash" є вбивцями ... в python вони є "+", "=", "[]" ) все ж я відчував це набагато гірше, що я б очікував навіть на логічному рівні. У певному сенсі я відчуваю, що Lisp - це нормально, але звичайний lisp - це так, і це вже не називає (перечитавши це дуже несправедливий коментар, оскільки мій досвід роботи з CL близький до нуля).
6502,

правда. Схема полегшить гольф трохи легше, з єдиним простором імен. замість додавання рядків у всьому місці ви могли (letrec ((рядок-додаток) (b gethash)) ... ... (a "x" "yz") ...)
Аарон

6

C (828)

Він дуже схожий на неясний код і використовує glib для рядка, списку та хешу. Char граф з 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);}

Нові рядки вважаються символами, але ви можете викреслити будь-які з рядків, що не є вказівками попереднього процесу. Для гольфу я не вважав би звільнення пам'яті поганою практикою.
Stéphan Kochen

ок ... покладіть всі в рядок (очікуйте макросів препроці) і надайте версію без звільнення пам’яті (і з двома іншими пробілами вилучено ... трохи покращення можна зробити на "обфускування", наприклад *v=*v*(77-lw)/m, дасть 929. .. але я думаю, що це може бути нормально, якщо я не знайду спосіб зробити це набагато коротше)
ShinTakezou

Я думаю , що ви можете рухатися по крайней мере, int cв mainдекларації і mainнеявно int(як і будь-які нетипізований аргументи, AFAIK): main(c){...}. Можливо, ви могли також просто написати 0замість цього NULL.
Joey

це робити, звичайно, спровокує попередження із значком -Wallабо зі -std=c99значком на…, але я вважаю, що для коду-гольфу це безглуздо, правда?
ShinTakezou

uff, вибачте за короткий проміжок часу, я повинен змінити Without freeing memory stuff, it reaches 866 (removed some other unuseful space)щось інше, щоб люди не думали, що різниця з версією вільної пам’яті полягає в тому, що зараз: версія без вільної пам’яті має багато більше "поліпшень".
ShinTakezou

6

Perl, 185 char

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 символів.

Третій рядок (містить два символи нового рядка) дає результат.


Це не видалить слова стоп із рядків, таких як "foo_the_bar". Довжина рядка також одна занадто довга (перечитайте специфікацію: "смуга + пробіл + слово + пробіл <= 80 символів")
Джої

5

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

  • Оновлення до першого 742 : покращений регулярний вираз, видалено зайві параметризовані типи, видалено зайвий пробіл.

  • Оновлення 742> 744 знаків : виправлено злому фіксованої довжини. Це залежить лише від 1-го слова, а не від інших слів (поки). Знайдено кілька місць для скорочення коду ( \\sу регулярному виразі замінено і ArrayListзамінено на Vector). Зараз я шукаю короткий спосіб усунути залежність IO Commons і читання з stdin.

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

  • Оновлення 752> 742 символів : я видалив publicпробіл, зробив назви класу 1 char замість 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);
 }
}

Вихід:

 _________________________________________________________________________
| _________________________________________________________________________ | вона
| _______________________________________________________________ | ти
| ____________________________________________________________ | сказав
| _____________________________________________________ | Аліса
| _______________________________________________ | був
| ___________________________________________ | що
| ____________________________________ | як
| ________________________________ | її
| _____________________________ | з
| _____________________________ | у
| __________________________ | на
| __________________________ | всі
| _______________________ | це
| _______________________ | для
| _______________________ | мав
| _______________________ | але
| ______________________ | бути
| _____________________ | ні
| ____________________ | Вони
| ____________________ | так
| ___________________ | дуже
| __________________ | що

Це досить гарно, що у Java немає String#join()і закривається (поки).

Редагувати: Ротсор:

Я змінив ваше рішення:

  • Список замінено рядком []
  • Повторно використовував аргумент 'args' замість декларування власного масиву String. Також використовується його як аргумент для .ToArray ()
  • Замінив StringBuffer з рядком (так, так, жахливе виконання)
  • Замінено сортування 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);}}}

Не могли б ви просто використати повноцінне ім'я, IOUtilsа не імпортувати його? Наскільки я можу бачити, ви все одно користуєтесь ним лише раз.
Joey

5
Ви наче обдурили, припускаючи, що найдовша смужка буде рівно 75 символів. Ви повинні переконатися, що жодне слово + слово не перевищує 80 знаків.
Гейб

Ви пропустите пробіл після слова. ;)
st0le

Коли я резюмував свою відповідь , я сподівався перемогти подання BalusC. У мене ще 200 символів, так що! Цікаво, як довго це триватиме без припущення IO та 75 Commons.
Джонатан Фауст

1
Схоже, ви можете поголити деяких символів, зробивши bString замість StringBuffer. Я не хочу думати про те, якою буде вистава (тим більше, що ти додаєш по одному персонажу за раз).
Майкл Майерс

4

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

включаючи довге коригування слова. Ідеї, запозичені з інших рішень.

Тепер як сценарій ( a.scala):

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

Біжи з

scala -howtorun:script a.scala alice.txt

До речі, редагування від 314 до 311 символів фактично видаляє лише 1 символ. Хтось раніше помилявся з підрахунком (Windows CR?).


4

Clojure 282 строгий

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

Дещо більш розбірливо:

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

4

Scala, 368 символів

По-перше, розбірлива версія з 592 символами:

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

Вихід консолі виглядає так:

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

Ми можемо зробити агресивне мінімізування та зменшити його до 415 символів:

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

Сеанс консолі виглядає так:

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

Я впевнений, що експерт Scala міг би зробити ще краще.

Оновлення: У коментарях Томас дав ще коротшу версію, на 368 символів:

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

Розбірливо - 375 символів:

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

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

Звичайно, завжди зручне для розуміння! Приємно!
pr1001

3

Ява - 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

8
Цілком короп, чи справді немає можливості скоротити його на Яві? Сподіваюся, вам, хлопці, заплатять за кількістю персонажів, а не за функціональністю :-)
Нас Банов
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.