Code Golf 4 июля Издание: Подсчитайте десятку происходящих слов

Учитывая следующий список президентов, можно сделать десятку лучших слов в наименьшей возможной программе:

ВХОДНЫЙ ФАЙЛ

    Washington
    Washington
    Adams
    Jefferson
    Jefferson
    Madison
    Madison
    Monroe
    Monroe
    John Quincy Adams
    Jackson
    Jackson
    Van Buren
    Harrison 
    DIES
    Tyler
    Polk
    Taylor 
    DIES
    Fillmore
    Pierce
    Buchanan
    Lincoln
    Lincoln 
    DIES
    Johnson
    Grant
    Grant
    Hayes
    Garfield 
    DIES
    Arthur
    Cleveland
    Harrison
    Cleveland
    McKinley
    McKinley
    DIES
    Teddy Roosevelt
    Teddy Roosevelt
    Taft
    Wilson
    Wilson
    Harding
    Coolidge
    Hoover
    FDR
    FDR
    FDR
    FDR
    Dies
    Truman
    Truman
    Eisenhower
    Eisenhower
    Kennedy 
    DIES
    Johnson
    Johnson
    Nixon
    Nixon 
    ABDICATES
    Ford
    Carter
    Reagan
    Reagan
    Bush
    Clinton
    Clinton
    Bush
    Bush
    Obama

Чтобы запустить его в символах bash 97

cat input.txt | tr " " "\n" | tr -d "\t " | sed 's/^$//g' | sort | uniq -c | sort -n | tail -n 10

Выход

      2 Nixon
      2 Reagan
      2 Roosevelt
      2 Truman
      2 Washington
      2 Wilson
      3 Bush
      3 Johnson
      4 FDR
      7 DIES

Разрыв связей, как вы считаете нужным! Счастливый четвертый!

Для тех из вас, кто интересуется более подробной информацией о президентах, можно найти здесь.

Ответ 1

Более короткая версия оболочки:

xargs -n1 < input.txt | sort | uniq -c | sort -nr | head

Если вы хотите нечувствительность к регистру, измените uniq -c на uniq -ci.

Немного короче, если вы довольны тем, что ранг отменен, а читаемость ухудшается из-за отсутствия пробелов. Это часы в 46 символов:

xargs -n1<input.txt|sort|uniq -c|sort -n|tail

(Вы можете удалить это до 38, если вам разрешили сначала переименовать входной файл, просто "i".)

Наблюдая, что в этом специальном случае ни слова не происходит более 9 раз, мы можем сбрить еще 3 символа, отбросив аргумент "-n" из окончательной сортировки:

xargs -n1<input.txt|sort|uniq -c|sort|tail

Это решение принимает до 43 символов без переименования входного файла. (Или 35, если да.)

Использование xargs -n1 для разбиения файла на одно слово в каждой строке предпочтительнее для решения tr \ \\n, так как это создает много пустых строк. Это означает, что решение неверно, потому что оно пропускает Nixon и показывает пустую строку, показывающую 256 раз. Однако пустая строка не является "словом".

Ответ 2

С#, 153:

Считывает файл в p и выводит результаты на консоль:

File.ReadLines(p)
    .SelectMany(s=>s.Split(' '))
    .GroupBy(w=>w)
    .OrderBy(g=>-g.Count())
    .Take(10)
    .ToList()
    .ForEach(g=>Console.WriteLine(g.Count()+"|"+g.Key));

Если вы просто создаете список, но не печатаете на консоли, то это 93 символа.

6|DIES
4|FDR
3|Johnson
3|Bush
2|Washington
2|Adams
2|Jefferson
2|Madison
2|Monroe
2|Jackson

Ответ 3

vim 60

    :1,$!tr " " "\n"|tr -d "\t "|sort|uniq -c|sort -n|tail -n 10

Ответ 4

Vim 36

:%s/\W/\r/g|%!sort|uniq -c|sort|tail

Ответ 5

Haskell, 102 символа (ничего себе, так близко к оригиналу):

import List
(take 10.map snd.sort.map(\(x:y)->(-length y,x)).group.sort.words)`fmap`readFile"input.txt"

J, всего 55 символов:

10{.\:~~.(,.~[:<"[email protected](+/)=/~);;:&.><;._2[1!:1<'input.txt'

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


   NB. read the file
   <1!:1<'input.txt'
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------...
|    Washington     Washington     Adams     Jefferson     Jefferson     Madison     Madison     Monroe     Monroe     John Quincy Adams     Jackson     Jackson     Van Buren     Harrison DIES     Tyler     Polk     Taylor DIES     Fillmore     Pierce     ...
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------...
   NB. split into lines
   <;._2[1!:1<'input.txt'
+--------------+--------------+---------+-------------+-------------+-----------+-----------+----------+----------+---------------------+-----------+-----------+-------------+-----------------+---------+--------+---------------+------------+----------+----...
|    Washington|    Washington|    Adams|    Jefferson|    Jefferson|    Madison|    Madison|    Monroe|    Monroe|    John Quincy Adams|    Jackson|    Jackson|    Van Buren|    Harrison DIES|    Tyler|    Polk|    Taylor DIES|    Fillmore|    Pierce|    ...
+--------------+--------------+---------+-------------+-------------+-----------+-----------+----------+----------+---------------------+-----------+-----------+-------------+-----------------+---------+--------+---------------+------------+----------+----...
   NB. split into words
   ;;:&.><;._2[1!:1<'input.txt'
+----------+----------+-----+---------+---------+-------+-------+------+------+----+------+-----+-------+-------+---+-----+--------+----+-----+----+------+----+--------+------+--------+-------+-------+----+-------+-----+-----+-----+--------+----+------+---...
|Washington|Washington|Adams|Jefferson|Jefferson|Madison|Madison|Monroe|Monroe|John|Quincy|Adams|Jackson|Jackson|Van|Buren|Harrison|DIES|Tyler|Polk|Taylor|DIES|Fillmore|Pierce|Buchanan|Lincoln|Lincoln|DIES|Johnson|Grant|Grant|Hayes|Garfield|DIES|Arthur|Cle...
+----------+----------+-----+---------+---------+-------+-------+------+------+----+------+-----+-------+-------+---+-----+--------+----+-----+----+------+----+--------+------+--------+-------+-------+----+-------+-----+-----+-----+--------+----+------+---...
   NB. count reptititions
   |:~.(,.~[:<"[email protected](+/)=/~);;:&.><;._2[1!:1<'input.txt'
+----------+-----+---------+-------+------+----+------+-------+---+-----+--------+----+-----+----+------+--------+------+--------+-------+-------+-----+-----+--------+------+---------+--------+---------+----+------+-------+--------+------+---+------+------...
|2         |2    |2        |2      |2     |1   |1     |2      |1  |1    |2       |6   |1    |1   |1     |1       |1     |1       |2      |3      |2    |1    |1       |1     |2        |2       |2        |1   |2     |1      |1       |1     |4  |2     |2     ...
+----------+-----+---------+-------+------+----+------+-------+---+-----+--------+----+-----+----+------+--------+------+--------+-------+-------+-----+-----+--------+------+---------+--------+---------+----+------+-------+--------+------+---+------+------...
|Washington|Adams|Jefferson|Madison|Monroe|John|Quincy|Jackson|Van|Buren|Harrison|DIES|Tyler|Polk|Taylor|Fillmore|Pierce|Buchanan|Lincoln|Johnson|Grant|Hayes|Garfield|Arthur|Cleveland|McKinley|Roosevelt|Taft|Wilson|Harding|Coolidge|Hoover|FDR|Truman|Eisenh...
+----------+-----+---------+-------+------+----+------+-------+---+-----+--------+----+-----+----+------+--------+------+--------+-------+-------+-----+-----+--------+------+---------+--------+---------+----+------+-------+--------+------+---+------+------...
   NB. sort
   |:\:~~.(,.~[:<"[email protected](+/)=/~);;:&.><;._2[1!:1<'input.txt'
+----+---+-------+----+------+----------+------+---------+------+-----+------+--------+-------+-------+---------+-------+--------+-----+----------+-------+---------+-----+---+-----+------+----+------+----+------+-----+-------+----+------+-----+-------+----...
|6   |4  |3      |3   |2     |2         |2     |2        |2     |2    |2     |2       |2      |2      |2        |2      |2       |2    |2         |2      |2        |2    |1  |1    |1     |1   |1     |1   |1     |1    |1      |1   |1     |1    |1      |1   ...
+----+---+-------+----+------+----------+------+---------+------+-----+------+--------+-------+-------+---------+-------+--------+-----+----------+-------+---------+-----+---+-----+------+----+------+----+------+-----+-------+----+------+-----+-------+----...
|DIES|FDR|Johnson|Bush|Wilson|Washington|Truman|Roosevelt|Reagan|Nixon|Monroe|McKinley|Madison|Lincoln|Jefferson|Jackson|Harrison|Grant|Eisenhower|Clinton|Cleveland|Adams|Van|Tyler|Taylor|Taft|Quincy|Polk|Pierce|Obama|Kennedy|John|Hoover|Hayes|Harding|Garf...
+----+---+-------+----+------+----------+------+---------+------+-----+------+--------+-------+-------+---------+-------+--------+-----+----------+-------+---------+-----+---+-----+------+----+------+----+------+-----+-------+----+------+-----+-------+----...
   NB. take 10
   10{.\:~~.(,.~[:<"[email protected](+/)=/~);;:&.><;._2[1!:1<'input.txt'
+-+----------+
|6|DIES      |
+-+----------+
|4|FDR       |
+-+----------+
|3|Johnson   |
+-+----------+
|3|Bush      |
+-+----------+
|2|Wilson    |
+-+----------+
|2|Washington|
+-+----------+
|2|Truman    |
+-+----------+
|2|Roosevelt |
+-+----------+
|2|Reagan    |
+-+----------+
|2|Nixon     |
+-+----------+

Ответ 6

Perl: 90

Perl: 114 (включая perl, ключи командной строки, одинарные кавычки и имя файла)

perl -nle'$h{$_}++for split/ /;END{$i++<=10?print"$h{$_} $_":0for reverse sort{$h{$a}cmp$h{$b}}keys%h}' input.txt

Ответ 7

Отсутствие AWK вызывает тревогу.

xargs -n1<input.txt|awk '{c[$1]++}END{for(p in c)print c[p],p|"sort|tail"}'

75 символов.

Если вы хотите получить немного больше AWKy, вы можете забыть xargs:

awk -v RS='[^a-zA-Z]' /./'{c[$1]++}END{for(p in c)print c[p],p|"sort|tail"}' input.txt

Ответ 8

Здесь приведена сжатая версия оболочки script, заметив, что для разумной интерпретации входных данных (без начальных или конечных пробелов), что вторая команда "tr" и "sed" в оригинале не изменяет данные (проверяется путем вставки "tee out.N" в подходящие точки и проверки размеров выходных файлов - одинаковых). Оболочке требуется меньше пробелов, чем люди - и использование cat вместо ввода перенаправления ввода-вывода тратит пространство.

tr \  \\n<input.txt|sort|uniq -c|sort -n|tail -10

Это весит 50 символов, включая новую строку в конце script.

С двумя другими наблюдениями (от других ответов):

  • tail сам по себе эквивалентен 'tail -10' и
  • в этом случае числовая и альфа-сортировка эквивалентны,

это может быть сокращено еще на 7 символов (до 43, включая конечную новую строку):

tr \  \\n<input.txt|sort|uniq -c|sort|tail

Использование 'xargs -n1' (без заданного префикса) вместо 'tr' чрезвычайно умно; он имеет дело с ведущими, конечными и множественными встроенными пространствами (которые этого решения нет).

Ответ 9

Моя лучшая попытка с рубином до сих пор, 166 символов:

h = Hash.new
File.open('f.l').each_line{|l|l.split(/ /).each{|e|h[e]==nil ?h[e]=1:h[e]+=1}}
h.sort{|a,b|a[1]<=>b[1]}.last(10).each{|e|puts"#{e[1]} #{e[0]}"}

Я удивлен, что никто не опубликовал сумасшедшего решения J.

Ответ 10

python 3.1 (88 символов)

import collections
collections.Counter(open('input.txt').read().split()).most_common(10)

Ответ 11

Python 2.6, 104:

l=open("input.txt").read().split()
for c,n in sorted(set((l.count(w),w) for w in l if w))[-10:]:print c,n

Ответ 12

vim 38 и работает для всех входных

:%!xargs -n1|sort|uniq -c|sort -n|tail

Ответ 13

Пересмотренная версия предыдущей записи, которая должна сохранить 10 символов:

h = {}
File.open('f.1').each {|l|l.split(/ /).each{|e|h[e]==nil ?h[e]=1:h[e]+=1}}
h.sort{|a,b|a[1]<=>b[1]}.last(10).each{|e|puts"#{e[1]} #{e[0]}"}

Ответ 14

Perl 86 символов

94, если вы считаете входное имя файла.

perl -anE'$_{$_}[email protected];END{say"$_{$_} $_"[email protected]{[sort{$_{$b}<=>$_{$a}}keys%_]}[0..10]}' test.in

Если вам все равно, сколько результатов вы получите, тогда это всего 75, за исключением имени файла.

perl -anE'$_{$_}[email protected];END{say"$_{$_} $_"for sort{$_{$b}<=>$_{$a}}keys%_}' test.in

Ответ 15

Ruby 66B

puts (a=$<.read.split).uniq.map{|x|"#{a.count x} "+x}.sort.last 10

Ответ 16

рубин

115 символов

w = File.read($*[0]).split
w.uniq.map{|x| [w.select{|y|x==y}.size,x]}.sort.last(10).each{|z| puts "#{z[1]} #{z[0]}"}

Ответ 17

Пакетный файл Windows

Это, очевидно, не самое маленькое решение, но я решил опубликовать его в любом случае, просто для удовольствия.:) NB: командный файл использует временный файл с именем $для хранения временных результатов.

Оригинальная несжатая версия с комментариями:

@echo off
setlocal enableextensions enabledelayedexpansion

set infile=%1
set cnt=%2
set tmpfile=$
set knownwords=

rem Calculate word count
for /f "tokens=*" %%i in (%infile%) do (
  for %%w in (%%i) do (

    rem If the word hasn't already been processed, ...
    echo !knownwords! | findstr "\<%%w\>" > nul
    if errorlevel 1 (

      rem Count the number of the word occurrences and save it to a temp file
      for /f %%n in ('findstr "\<%%w\>" %infile% ^| find /v "" /c') do (
        echo %%n^|%%w >> %tmpfile%
      )

      rem Then add the word to the known words list
      set knownwords=!knownwords! %%w
    )
  )
)

rem Print top 10 word count
for /f %%i in ('sort /r %tmpfile%') do (
  echo %%i
  set /a cnt-=1
  if !cnt!==0 goto end
)

:end
del %tmpfile%

Сжатая и запутанная версия, 317:

@echo off&setlocal enableextensions enabledelayedexpansion&set n=%2&set l=
for /f "tokens=*" %%i in (%1)do for %%w in (%%i)do echo !l!|findstr "\<%%w\>">nul||for /f %%n in ('findstr "\<%%w\>" %1^|find /v "" /c')do echo %%n^|%%w>>$&set l=!l! %%w
for /f %%i in ('sort /r $')do echo %%i&set /a n-=1&if !n!==0 del $&exit /b

Это может быть сокращено до символов 258, если эхо-сигнал уже выключен, а расширения команд и расширенное расширение переменной включены:

set n=%2&set l=
for /f "tokens=*" %%i in (%1)do for %%w in (%%i)do echo !l!|findstr "\<%%w\>">nul||for /f %%n in ('findstr "\<%%w\>" %1^|find /v "" /c')do echo %%n^|%%w>>$&set l=!l! %%w
for /f %%i in ('sort /r $')do echo %%i&set /a n-=1&if !n!==0 del $&exit /b

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

> filename.bat input.txt 10 & pause

Вывод:

6|DIES
4|FDR
3|Johnson
3|Bush
2|Wilson
2|Washington
2|Truman
2|Roosevelt
2|Reagan
2|Nixon