Skip to main content
use other submissions' cheat of allowing underscores
Source Link
Adam Katz
  • 366
  • 5
  • 10

Shell, 89 8686 82 bytes

grep -ioPo "[a-z0-9'"[\w'-]*"|sort]+"|sort -f|uniq -ci|sort -nr|awk 'c>$1{print w}c{exit}{c=$1;w=$2}'
grep -ioPo "[a-z0-9'"[\w'-]*"]+"      # get a list of the words, one per line
  |sort -f              # sort (case insensitive, "folded")
  |uniq -ci             # count unique entries while still ignoring case
  |sort -nr             # sort counted data in descending order
  |awk '
    count > $1 {        # if count of most common word exceeds that of this line
      print word        # print the word saved from it
    }
    count {             # if we have already saved a count (-> we are on line 2)
      exit              # we always exit on line 2 since we have enough info
    }
    {                   # if true (run on line 1 only due to the above exit)
      count = $1        # save the count of the word on this first line
      word = $2         # save the word itself
    }'

grep -o is the magic tokenizer here. It takes each word (as defined by the given regular expressiona regex accepting word characters (letters, case insensitivenumbers, underscore), apostrophe, or hyphen using PCRE given -iP) and puts it on its own line. This accepts underscores, as to many other answers here. To disallow underscores, add four characters to turn this portion into grep -oi "[a-z0-9'-]*"

Shell, 89 86 bytes

grep -io "[a-z0-9'-]*"|sort -f|uniq -ci|sort -nr|awk 'c>$1{print w}c{exit}{c=$1;w=$2}'
grep -io "[a-z0-9'-]*"  # get a list of the words, one per line
  |sort -f              # sort (case insensitive, "folded")
  |uniq -ci             # count unique entries while still ignoring case
  |sort -nr             # sort counted data in descending order
  |awk '
    count > $1 {        # if count of most common word exceeds that of this line
      print word        # print the word saved from it
    }
    count {             # if we have already saved a count (-> we are on line 2)
      exit              # we always exit on line 2 since we have enough info
    }
    {                   # if true (run on line 1 only due to the above exit)
      count = $1        # save the count of the word on this first line
      word = $2         # save the word itself
    }'

grep -o is the magic tokenizer here. It takes each word (as defined by the given regular expression, case insensitive given -i) and puts it on its own line.

Shell, 89 86 82 bytes

grep -Po "[\w'-]+"|sort -f|uniq -ci|sort -nr|awk 'c>$1{print w}c{exit}{c=$1;w=$2}'
grep -Po "[\w'-]+"      # get a list of the words, one per line
  |sort -f              # sort (case insensitive, "folded")
  |uniq -ci             # count unique entries while still ignoring case
  |sort -nr             # sort counted data in descending order
  |awk '
    count > $1 {        # if count of most common word exceeds that of this line
      print word        # print the word saved from it
    }
    count {             # if we have already saved a count (-> we are on line 2)
      exit              # we always exit on line 2 since we have enough info
    }
    {                   # if true (run on line 1 only due to the above exit)
      count = $1        # save the count of the word on this first line
      word = $2         # save the word itself
    }'

grep -o is the magic tokenizer here. It takes each word (as defined by a regex accepting word characters (letters, numbers, underscore), apostrophe, or hyphen using PCRE given -P) and puts it on its own line. This accepts underscores, as to many other answers here. To disallow underscores, add four characters to turn this portion into grep -oi "[a-z0-9'-]*"

shaved off three characters, vastly improved the explanation. also added syntax highlighting.
Source Link
Adam Katz
  • 366
  • 5
  • 10

Shell, 8989 86 bytes

grep -io "[a-z0-9'-]*"|sort -f|uniq -ci|sort -nr|awk 'c{if(c>$1)print w;exit}{c=$1;w=$2}'
grep -io "[a-z0-9'-]*"|sort -f|uniq -ci|sort -nr|awk 'c>$1{print w}c{exit}{c=$1;w=$2}'
grep -io "[a-z0-9'-]*"  # get a list of the words, one per line
  |sort -f              # sort (case insensitive, "folded")
  |uniq -ci             # count unique entries while still ignoring case
  |sort -nr             # sort counted data in descending order
  |awk '
    c {                 # if c (the most common word's count) is defined yet
      if (c > $1)       # if line 1's word was more common than line 2's
        print w
      exit              # we always exit on line 2
    }
    {                   # this stanza always runs (unless we have exited)
      c = $1            # define c as the count of the first line's word
      w = $2            # define w as the word itself
    }'
grep -io "[a-z0-9'-]*"  # get a list of the words, one per line
  |sort -f              # sort (case insensitive, "folded")
  |uniq -ci             # count unique entries while still ignoring case
  |sort -nr             # sort counted data in descending order
  |awk '
    count > $1 {        # if count of most common word exceeds that of this line
      print word        # print the word saved from it
    }
    count {             # if we have already saved a count (-> we are on line 2)
      exit              # we always exit on line 2 since we have enough info
    }
    {                   # if true (run on line 1 only due to the above exit)
      count = $1        # save the count of the word on this first line
      word = $2         # save the word itself
    }'

grep -o is the magic tokenizer here. It takes each word (as defined by the given regular expression, case insensitive given -i) and puts it on its own line.

alias cnt='sort -f |uniq -ci |sort -nr' is an old standby of mine. Without regards to case, it alphabetizes (erm, asciibetizes) the lines of the input counts occurrences of each entry, then reverse-sorts by the numeric occurrences so the most popular is first.

awk only looks at the first two lines of that descending ranked list. On line one, count is not yet defined, so it is evaluated as zero and therefore the first two stanzas are skipped (zero == false). The third stanza sets count and word. On the second line, awk has a defined and nonzero value for count, so it compares that count to the second best count. If it's not tied, the saved word is printed. Regardless, the next stanza exits for us.

Test implemented as:

for s in "The man walked down the road." "Slowly, he ate the pie, savoring each delicious bite. He felt like he was truly happy." "This sentence has no most frequent word." "\"That's... that's... that is just terrible\!\" he said." "The old-fashioned man ate an old-fashioned cake." "IPv6 looks great, much better than IPv4, except for the fact that IPv6 has longer addresses." "This sentence with words has at most two equal most frequent words."; do printf "%s\n==> " "$s"; echo "$s" |grep -io "[a-z0-9'-]*"|sort -f|uniq -ci|sort -nr|awk 'c{if(c>$1)print w;exit}{c=$1;w=$2}'; echo; done
for s in "The man walked down the road." "Slowly, he ate the pie, savoring each delicious bite. He felt like he was truly happy." "This sentence has no most frequent word." "\"That's... that's... that is just terrible\!\" he said." "The old-fashioned man ate an old-fashioned cake." "IPv6 looks great, much better than IPv4, except for the fact that IPv6 has longer addresses." "This sentence with words has at most two equal most frequent words."; do printf "%s\n==> " "$s"; echo "$s" |grep -io "[a-z0-9'-]*"|sort -f|uniq -ci|sort -nr|awk 'c>$1{print w}c{exit}{c=$1;w=$2}'; echo; done

Shell, 89 bytes

grep -io "[a-z0-9'-]*"|sort -f|uniq -ci|sort -nr|awk 'c{if(c>$1)print w;exit}{c=$1;w=$2}'
grep -io "[a-z0-9'-]*"  # get a list of the words, one per line
  |sort -f              # sort (case insensitive, "folded")
  |uniq -ci             # count unique entries while still ignoring case
  |sort -nr             # sort counted data in descending order
  |awk '
    c {                 # if c (the most common word's count) is defined yet
      if (c > $1)       # if line 1's word was more common than line 2's
        print w
      exit              # we always exit on line 2
    }
    {                   # this stanza always runs (unless we have exited)
      c = $1            # define c as the count of the first line's word
      w = $2            # define w as the word itself
    }'

Test implemented as:

for s in "The man walked down the road." "Slowly, he ate the pie, savoring each delicious bite. He felt like he was truly happy." "This sentence has no most frequent word." "\"That's... that's... that is just terrible\!\" he said." "The old-fashioned man ate an old-fashioned cake." "IPv6 looks great, much better than IPv4, except for the fact that IPv6 has longer addresses." "This sentence with words has at most two equal most frequent words."; do printf "%s\n==> " "$s"; echo "$s" |grep -io "[a-z0-9'-]*"|sort -f|uniq -ci|sort -nr|awk 'c{if(c>$1)print w;exit}{c=$1;w=$2}'; echo; done

Shell, 89 86 bytes

grep -io "[a-z0-9'-]*"|sort -f|uniq -ci|sort -nr|awk 'c>$1{print w}c{exit}{c=$1;w=$2}'
grep -io "[a-z0-9'-]*"  # get a list of the words, one per line
  |sort -f              # sort (case insensitive, "folded")
  |uniq -ci             # count unique entries while still ignoring case
  |sort -nr             # sort counted data in descending order
  |awk '
    count > $1 {        # if count of most common word exceeds that of this line
      print word        # print the word saved from it
    }
    count {             # if we have already saved a count (-> we are on line 2)
      exit              # we always exit on line 2 since we have enough info
    }
    {                   # if true (run on line 1 only due to the above exit)
      count = $1        # save the count of the word on this first line
      word = $2         # save the word itself
    }'

grep -o is the magic tokenizer here. It takes each word (as defined by the given regular expression, case insensitive given -i) and puts it on its own line.

alias cnt='sort -f |uniq -ci |sort -nr' is an old standby of mine. Without regards to case, it alphabetizes (erm, asciibetizes) the lines of the input counts occurrences of each entry, then reverse-sorts by the numeric occurrences so the most popular is first.

awk only looks at the first two lines of that descending ranked list. On line one, count is not yet defined, so it is evaluated as zero and therefore the first two stanzas are skipped (zero == false). The third stanza sets count and word. On the second line, awk has a defined and nonzero value for count, so it compares that count to the second best count. If it's not tied, the saved word is printed. Regardless, the next stanza exits for us.

Test implemented as:

for s in "The man walked down the road." "Slowly, he ate the pie, savoring each delicious bite. He felt like he was truly happy." "This sentence has no most frequent word." "\"That's... that's... that is just terrible\!\" he said." "The old-fashioned man ate an old-fashioned cake." "IPv6 looks great, much better than IPv4, except for the fact that IPv6 has longer addresses." "This sentence with words has at most two equal most frequent words."; do printf "%s\n==> " "$s"; echo "$s" |grep -io "[a-z0-9'-]*"|sort -f|uniq -ci|sort -nr|awk 'c>$1{print w}c{exit}{c=$1;w=$2}'; echo; done
Source Link
Adam Katz
  • 366
  • 5
  • 10

Shell, 89 bytes

grep -io "[a-z0-9'-]*"|sort -f|uniq -ci|sort -nr|awk 'c{if(c>$1)print w;exit}{c=$1;w=$2}'

This lists all words in the input, then sorts them with counts from most common to least common. The awk call merely ensures that the #2 word doesn't have the same count as the #1 word.

Unwrapped:

grep -io "[a-z0-9'-]*"  # get a list of the words, one per line
  |sort -f              # sort (case insensitive, "folded")
  |uniq -ci             # count unique entries while still ignoring case
  |sort -nr             # sort counted data in descending order
  |awk '
    c {                 # if c (the most common word's count) is defined yet
      if (c > $1)       # if line 1's word was more common than line 2's
        print w
      exit              # we always exit on line 2
    }
    {                   # this stanza always runs (unless we have exited)
      c = $1            # define c as the count of the first line's word
      w = $2            # define w as the word itself
    }'

Test implemented as:

for s in "The man walked down the road." "Slowly, he ate the pie, savoring each delicious bite. He felt like he was truly happy." "This sentence has no most frequent word." "\"That's... that's... that is just terrible\!\" he said." "The old-fashioned man ate an old-fashioned cake." "IPv6 looks great, much better than IPv4, except for the fact that IPv6 has longer addresses." "This sentence with words has at most two equal most frequent words."; do printf "%s\n==> " "$s"; echo "$s" |grep -io "[a-z0-9'-]*"|sort -f|uniq -ci|sort -nr|awk 'c{if(c>$1)print w;exit}{c=$1;w=$2}'; echo; done