# Count the words in a text and display them

The code should take input a text (not mandatory can be anything file, stdin, string for JavaScript, etc):

This is a text and a number: 31.


The output should contain the words with their number of occurrence, sorted by the number of occurrences in descending order:

a:2
and:1
is:1
number:1
This:1
text:1
31:1


Notice that 31 is a word, so a word is anything alpha-numeric, number are not acting as separators so for example 0xAF qualifies as a word. Separators will be anything that is not alpha-numeric including .(dot) and -(hyphen) thus i.e. or pick-me-up would result in 2 respectively 3 words. Should be case sensitive, This and this would be two different words, ' would also be separator so wouldnand t will be 2 different words from wouldn't.

Write the shortest code in your language of choice.

• Does case matter (ie is This the same as this and tHIs)? – Gareth Jan 29 '14 at 7:49
• If anything non-alphanumeric counts as a separator, is wouldn't 2 words (wouldn and t)? – Gareth Jan 29 '14 at 7:51
• @Gareth Should be case sensitive, This and this would be indeed two different words, same wouldnand t. – Eduard Florinescu Jan 29 '14 at 9:08
• If Wouldn't are 2 words, shouldn't it be "Would" and "nt" since its short for Would not, or is that to much grammer nazi-ish? – Teun Pronk Jan 29 '14 at 9:12
• @TeunPronk I try to keep it simple, putting a few rules will encourage exceptions to be in order with grammar , and there are a lot of exceptions out there.Ex in English i.e. is a word but if we let the dot all the dots at the end of phrases will be taken, same with quotes or single quotes, etc. – Eduard Florinescu Jan 29 '14 at 9:18

## grep and coreutils  44  42

grep -io '[a-z0-9]*'|sort|uniq -c|sort -nr


Test:

printf "This is a text and a number: 31." |
grep -io '[a-z0-9]*'|sort|uniq -c|sort -nr


Results in:

  2 a
1 This
1 text
1 number
1 is
1 and
1 31


### Update

• Use case-insensitive option and shorter regex. Thanks Tomas.
• This being almost exactly McEllroy's response to Knuth's book Literate Programming. The only difference being that this does not include a pipe into head at the end. – AJMansfield Jan 29 '14 at 10:54
• This was pretty much my first thought too. – Rob Jan 29 '14 at 17:15
• Wouldn't '\w+' work as well? – Sylwester Jan 30 '14 at 18:05
lsort -s 2 -inde 1 -de $D}  Try it online! Python 2.X (108 - Characters) print'\n'.join('{}:{}'.format(a,b)for a,b in __import__("collections").Counter(raw_input().split()).items())  Python 3.X (106 - Characters) print('\n'.join('{}:{}'.format(a,b)for a,b in __import__("collections").Counter(input().split()).items())  • Separators will be anything that is not alpha-numeric - You only split on whitespace. – daniero Jan 29 '14 at 11:43 # Haskell - 137 import Data.List count text=let textS=(words(text\\".-\':")) in (sortBy (\(_,n) (_,m) -> compare m n)).nub$map(\t->(t,(length.(filter(==t)))textS)) textS


# Python 3 - 76

The requirement of splitting on non-alphanumeric chars unfortunately extends the code by 19 chars. The output of the following is shown correctly. If you are not sure, add a .most_common() after the .Counter(...).

i=__import__
print(i('collections').Counter(i('re').findall('\w+',input())))


### In/Output

Given the input of This is a text and a number: 31. you get following output:

Counter({'a': 2, 'is': 1, 'This': 1, 'and': 1, '31': 1, 'number': 1, 'text': 1})


I tried it with other values like

1 2 3 4 5 6 7 8 2 1 5 3 4 6 8 1 3 2 4 6 1 2 8 4 3 1 3 2 5 6 5 4  2 2 4 2 1 3 6


to ensure, the output-order does not rely on the key's value/hash. This example produces:

Counter({'2': 8, '3': 6, '1': 6, '4': 6, '6': 5, '5': 4, '8': 3, '7': 1})


But as I said, print(i('collections').Counter(i('re').findall('\w+',input())).most_common()) would return the results as an definitly ordered list of tuples.

## Python 3 - 57 (if a space would be enough for splitting :P)

print(__import__('collections').Counter(input().split()))

• If you assumed the string was in some variable s, as some other answers do, you could lose 6 characters by replacing input(). – Phil H Jan 31 '14 at 8:24
• @PhilH well. you are right, but I would never read that out of the requirements. sure the "string for JavaScript"-part might suggest it, but I cannot, with a clear conscience, interpret a string-variable as a valid "input". But you are right. that would shorten it even more. :P – Dave J Jan 31 '14 at 19:43
• -1. Underscore _ should not be included in a word. – n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Mar 24 '14 at 22:31
• Well this depends on the definition of alpha-numeric. In Python, "\w" is defined for accepting alpha-numeric chars. You might be correct but a with this kind of interpretation of the rules, my solution keeps being correct. :) – Dave J Mar 26 '14 at 15:20