g | x | w | all
Bytes Lang Time Link
nanPerl 5 n0250723T184529ZXcali
035Dyalog APL250723T170847ZAaron
012Vyxal 3250722T213116Zpacman25
023Pip p230127T160718ZBaby_Boy
nan230127T174302ZThe Thon
014Husk201028T112940ZDominic
071JavaScript230127T170930ZShaggy
147JavaScript230127T150124ZEzioMerc
077Zsh230126T112835Zroblogic
085Haskell201028T142141ZWheat Wi
088Python 3201028T124436ZJitse
011Japt v2.0a0 hR201028T101341ZShaggy
013Jelly201027T195457Zcaird co
119Python3140305T155908Zgcq
420VBScript 430 / VBA130206T212825ZGaffi
168Python130211T045855ZStephen
nanThis is my first codegolf130206T223113ZFels
nan130206T011517Zbeary605
106R130208T120432Zplannapu
129Scala130207T223526Zuser unk
056APL130207T041707Zmarinus
066GoRuby 2.0.0 –130206T193023ZPatrick
162Javascript130205T215155ZShmiddty
115Mathematica130205T233109ZDavidC
078Perl130205T164732Zprimo

Perl 5 -n0, 60 + 2 = 62 bytes

map{my%z;@z{/./g}=1;$a[$c=keys%z].="$_ $c
"}/\S+/g;say$a[-1]

Try it online!

Dyalog APL, 35 chars

{↑(⊢,≢)¨{⍵/⍨(⊢=⌈/)≢∘∪¨⍵}(' '∘≠⊆⊢)⍵}

Explanation

                         (     ⊆ )    ⍝ Partition
                                ⊢     ⍝   the input
                          ' '∘≠       ⍝   breaking on spaces
         {              }             ⍝ Select the elements with max length
                      ¨⍵              ⍝   For each of the words
                   ≢∘∪                ⍝     get unique letters and count them
             (⊢=⌈/)                   ⍝   Find which are equal to the maximum
          ⍵/⍨                         ⍝   Replicate (backwords) to filter to just those words
   (⊢,≢)¨                             ⍝ For each word, concatenate its length to it
  ↑                                   ⍝ And mix so it looks pretty

Vyxal 3, 12 bytes

⌈:¨uĿƓ£Z~¥c'

Vyxal It Online!

Pip -p, 24 23 bytes

(a^:s(Y#*UQ*a)@*My)ZDNy

Try It Online!

Thunno N, \$ 29 \log_{256}(96) \approx \$ 23.87 bytes

A_ZiDedZULEZZz:zGAJzHAKerA_sj

Attempt This Online!

We can save a character if joining by a digit is allowed: Attempt This Online!

Explanation

A_Zi      # Split the (implicit) input by spaces        ["Finding", "the", "most", "unique", "word"]
    D     # Duplicate this list                         ["Finding", "the", "most", "unique", "word"], ["Finding", "the", "most", "unique", "word"]
     e    # Map over it:                                ["Finding", "the", "most", "unique", "word"]
      dZU #  Uniquify the string                         ["Findg", "the", "most", "uniqe", "word"]
L         #  And get the length                          [5, 3, 4, 5, 4]
 E        # (End map)                                   ["Finding", "the", "most", "unique", "word"], [5, 3, 4, 5, 4]
  ZZ      # Zip this with the split list                [[5, "Finding"], [3, "the"], [4, "most"], [5, "unique"], [4, "word"]]
    z:zG  # Sort and group by:                          [[3, "the"], [4, "most"], [4, "word"], [5, "Finding"], [5, "unique"]]
AJ        #  First element of each                       [3, 4, 4, 5, 5]
  zH      # (End group)                                 [[[3, "the']], [[4, "most"], [4, "word"]], [[5, "Finding"], [5, "unique"]]]
    AK    # Get the last element                        [[5, "Finding"], [5, "unique"]]
      e   # Map over it:                                [[5, "Finding"], [5, "unique"]]
       r  #  Reverse                                     [["Finding", 5], ["unique", 5]]
A_sj      #  And join by spaces                          ["Finding 5", "unique 5"]
          # (N flag joins by newlines)                  "Finding 5", "unique 5"
          # Implicit output

Husk, 19 13 16 15 14 bytes

Edit: -6 bytes by taking inspiration from Shaggy's Japt answer, but then +3 +2 +1 byte to scrupulously adhere to the output format (without surrounding parentheses and/or quotation marks)

mS+ȯΘs₁→k₁w
Lu

Try it online!

Lu                  # helper function: get the number of unique letters

¶m§,I₁→k₁w          # main program
¶                   # split result by newlines
 m                  # for each element of list
  §,I₁              # combine itself (I) with result of helper function
      →k₁w          # list:
      →             # last element of
       k w          # groups of words of input, grouped & sorted by
        ₁           # results of helper function

JavaScript, 76 71 bytes

s=>s.split` `.map(w=>(n=new Set(w).size)<s||[w,s=n]).filter(x=>x[1]==s)

Try it online!

JavaScript, 147 bytes

With map:

t=>(s='',m=new Map(),t.split(' ').map(w=>m.set(w,new Set(w).size)),d=[...m].sort((a,b)=>b[1]-a[1]),d.map(x=>x[1]==d[0][1]&&(s+=x.join('-')+`
`)),s)

With plain object

t=>(s='',m={},t.split(' ').map(w=>m[w]=new Set(w).size),d=Object.entries(m).sort((a,b)=>b[1]-a[1]),d.map(x=>x[1]==d[0][1]&&(s+=x.join('-')+`
`)),s)

Try it:

f=t=>(s='',m=new Map(),t.split(' ').map(w=>m.set(w,new Set(w).size)),d=[...m].sort((a,b)=>b[1]-a[1]),d.map(x=>x[1]==d[0][1]&&(s+=x.join('-')+`
`)),s)

console.log(f('It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way - in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.'));

console.log(f('Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec mollis, nisl sit amet consequat fringilla, justo risus iaculis justo, vel ullamcorper dui tellus ut enim. Suspendisse lectus risus, molestie sed volutpat nec, eleifend vitae ligula. Nulla porttitor elit vel augue pretium cursus. Donec in turpis lectus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Quisque a lorem eu turpis viverra sodales. Pellentesque justo arcu, venenatis nec hendrerit a, molestie vitae augue.'));

console.log(f('A little tired, perhaps. But I feel peaceful. Your success in the ring this morning was, to a small degree, my success. Your future is assured. You will live, secure and safe, Wilbur. Nothing can harm you now. These autumn days will shorten and grow cold. The leaves will shake loose from the trees and fall. Christmas will come, and the snows of winter. You will live to enjoy the beauty of the frozen world, for you mean a great deal to Zuckerman and he will not harm you, ever. Winter will pass, the days will lengthen, the ice will melt in the pasture pond. The song sparrow will return and sing, the frogs will awake, the warm wind will blow again. All these sights and sounds and smells will be yours to enjoy, Wilbur—this lovely world, these precious days…'));

console.log(f('Nearly all children nowadays were horrible. What was worst of all was that by means of such organizations as the Spies they were systematically turned into ungovernable little savages, and yet this produced in them no tendency whatever to rebel against the discipline of the Party. On the contrary, they adored the Party and everything connected with it... All their ferocity was turned outwards, against the enemies of the State, against foreigners, traitors, saboteurs, thought-criminals. It was almost normal for people over thirty to be frightened of their own children.'));

Zsh, 77 bytes

for x;z=`fold -1<<<$x|sort|uniq|wc -l` m=$[z>m?z:m]&&echo $z $x>>p
grep ^$m p

Try it Online!

$z is a count of the unique letters in each word. $m is the maximum $z. We write each word and its count to file p, then grep for $m.

OG: 119 bytes using associative array.

Haskell, 85 bytes

k(a:b)=k(filter(/=a)b)-1
k[]=0
f x=unlines[y++show(k y)|y<-x,all((>=k y).k)x]
f.words

Try it online!

This employs one clever trick. Instead of counting up the number of unique characters in each word, it counts down. So hello yeilds \$-4\$ rather than \$4\$. This allows us to use - as the delimter later which saves us a tiny bit.

With more lenient IO, 65 bytes

k(a:b)=1+k(filter(/=a)b)
k[]=0
f x=[(y,k y)|y<-x,all((<=k y).k)x]

Try it online!

20 bytes were spent just conforming to the archaic IO restrictions. This takes a list of input words and outputs a list of tuples containing the word and the count.

Python 3, 88 bytes

lambda s:[(w,len({*w}))for w in s.split()if len({*w})==max(map(len,map(set,s.split())))]

Try it online!

Japt v2.0a0 -hR, 11 bytes

Uses a comma as the delimiter.

¸®¸pZâ lÃüÌ

Try it

¸®¸pZâ lÃüÌ     :Implicit input of string            > "Finding the most unique word"
¸               :Split on spaces                     > ["Finding","the","most","unique","word"]
 ®              :Map each Z
  ¸             :  Split on spaces                   > [["Finding"],["the"],["most"],["unique"],["word"]]
   p            :  Push
    Zâ          :    Z deduplicated                  >   ["Findg","the","most","uniqe","word"]
       l        :    Length                          >   [5,3,4,5,4]
        Ã       :End map                             > [["Finding",5],["the",3],["most",4],["unique",5],["word",4]]
         ü      :Group & sort by
          Ì     :  Last element                      > [[["the",3]],[["most",4],["word",4]],[["Finding",5],["unique",5]]]
                :Implicit output of last element     > [["Finding",5],["unique",5]]
                :  joined with newlines              > "Finding,5\nunique,5"

Jelly, 13 bytes

QL
ḲÇÐṀ,ÇKƊ€Y

Try it online!

Just returning the number of unique characters is 6 bytes and just returning the words (no count), is 7 bytes.

How it works

QL - Helper link. Takes a string W on the left
Q  - Deduplicate W
 L - Length
     This returns the number of unique characters in W

ḲÇÐṀ,ÇKƊ€Y - Main link. Takes a string S on the left
Ḳ          - Split S on spaces
  ÐṀ       - Find the words for which the following is maximal:
 Ç         -   The number of unique characters
       Ɗ€  - Over each maximal word:
     Ç     -   Yield the number of unique characters
    ,      -   Pair with the word
      K    -   Join by spaces
         Y - Join by newlines

Python3 119

Reads from a file called a.

r={w:len(set(w))for w in open("a").read().split()};print("\n".join(str((k,v))for k,v in r.items()if v==max(r.values())))

Tested with the input texts from @primo:

Input 1:
    ('incredulity,', 11)

Input 2:
    ('Vestibulum', 9)
    ('consequat', 9)
    ('ullamcorper', 9)

VBScript - 430 / VBA - 420

VBScript:

Function r(t)
d="Scripting.Dictionary"
Set w=CreateObject(d)
c=1
Do Until c>Len(t)
p=InStr(c,t," ")
i=InStr(c,t,vbCr)
If p<i Then s=i Else s=p
If s=0 Then s=Len(t)+1
f=Mid(t,c,s-c)  
If Not w.Exists(f) Then 
Set x=CreateObject(d)
For l=1 To Len(f)
n=Mid(f,l,1)
If Not x.Exists(n) Then x.Add n,n
Next
w.Add f,f
y=x.Count
If m=y Then z=f &vbCr &z
If m<y Then m=y:z=f
End If
c=s+1
Loop
r=z &" " &m
End Function

VBA:

Function r(t)
d="Scripting.Dictionary"
Set w=CreateObject(d)
c=1
Do Until c>Len(t)
p=InStr(c,t," ")
i=InStr(c,t,vbCr)
s=IIf(p<i,i,p)
If s=0 Then s=Len(t)+1
f=Mid(t,c,s-c)  
If Not w.Exists(f) Then 
Set x=CreateObject(d)
For l=1 To Len(f)
n=Mid(f,l,1)
If Not x.Exists(n) Then x.Add n,n
Next
w.Add f,f
y=x.Count
If m=y Then z=f &vbCr &z
If m<y Then m=y:z=f
End If
c=s+1
Loop
r=z &" " &m
End Function

Python 176 168

w = "".join((open('c')).readlines()).replace("\n", " ").split(" ")
l = sorted(zip([len(set(w[i])) for i in range(len(w))],w,))
print([x for x in l if l[-1][0] == x[0]])

This is my first codegolf, I'm so excited :) Also that means it is probably not any good.

Groovy 127 117 112 105

Edit: Since functions seem to be allowed here is one in 105. I also renamed the variables to make the first column read ACDC, because that is important in any kind of source code:

A={e={it.toSet().size()}
C=it.text.tokenize()
D=e(C.max{e(it)})
C.grep{e(it)==D}.each{println"$it $D"}}

You would call it like that:

A(new File("words.txt"))

Without function using standard input in 112:

a={it.toSet().size()}
b=System.in.getText().tokenize()
c=a(b.max{a(it)})
b.grep{a(it)==c}.each{println "$it $c"}

a={it.toSet().size()}
b=System.in.getText().tokenize().sort{-a(it)}
c=a(b[0])
b.grep{a(it)==c}.each{println "$it $c"}

a={it.toSet().size()}
System.in.getText().tokenize().sort({-a(it)}).groupBy{a(it)}.take(1).each{k,v->v.each{println "$it $k"}}

Input: Lorem Ipsum Text from primo

All scripts output:

consequat 9
ullamcorper 9
Vestibulum 9

Anyone got an idea how to make them more groovy?

Python 2 (110 (98 using file input))

import sys
f=lambda x:len(set(x))
a=sys.stdin.read().split()
c=max(map(f,a))
for i in a:
 if f(i)==c:print i,c

.

f=lambda x:len(set(x))
a=file('a').read().split()
c=max(map(f,a))
for i in a:
 if f(i)==c:print i,c

Things to improve: printing (33 characters)

Punctuation is considered letters.

R - 106 characters
As a function with the input text as parameter:

f=function(t){
s=strsplit
a=sapply
t=s(t," ")[[1]]
w=a(a(s(t,""),unique),length)
n=(w==max(w))
cbind(t[n],w[n])
}

And a few examples:

f("It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way - in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.")
     [,1]           [,2]
[1,] "incredulity," "11"

f("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec mollis, nisl sit amet consequat fringilla, justo risus iaculis justo, vel ullamcorper dui tellus ut enim. Suspendisse lectus risus, molestie sed volutpat nec, eleifend vitae ligula. Nulla porttitor elit vel augue pretium cursus. Donec in turpis lectus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Quisque a lorem eu turpis viverra sodales. Pellentesque justo arcu, venenatis nec hendrerit a, molestie vitae augue.")
     [,1]          [,2]
[1,] "consequat"   "9" 
[2,] "ullamcorper" "9" 
[3,] "Vestibulum"  "9"

Or R - 100 characters
As a function with the path to the text file as parameter:

f=function(t){
t=scan(t,"")
a=sapply
w=a(a(strsplit(t,""),unique),length)
n=(w==max(w))
cbind(t[n],w[n])
}

Usage:

f("t1.txt")
Read 120 items
     [,1]           [,2]
[1,] "incredulity," "11"

Scala 129 chars:

def f{
val l=readLine.split(" ").map(s=>(s,s.distinct.length)).sortBy(_._2)
println(l.filter(x=>x._2==l.last._2).mkString)}

APL (56)

{⎕ML←3⋄⊃{⍵,⍴∪⍵}¨W[⍙]⍴⍨↑+/∆∘.=∆←∆[⍙←⍒∆←↑∘⍴∘∪¨W←⍵⊂⍨⍵≠' ']}

This is a function (question says that's allowed) that takes a string and returns a matrix of words and unique lengths.

Usage:

      {⎕ML←3⋄⊃{⍵,⍴∪⍵}¨W[⍙]⍴⍨↑+/∆∘.=∆←∆[⍙←⍒∆←↑∘⍴∘∪¨W←⍵⊂⍨⍵≠' ']}'The quick brown fox jumps over the lazy dog.'
quick 5
brown 5
jumps 5

Explanation:

GoRuby 2.0.0 – 66 chars

The solutions below didn't actually find all matches but only one. Here's my final version:

a=$<.r.sp.m{|x|[x,x.ch.u.sz]};a.m{|x|s x*' - 'if x.l==a.m_(&:l).l}

Examples:

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec mollis, nisl sit amet consequat fringilla, justo risus iaculis justo, vel ullamcorper dui tellus ut enim. Suspendisse lectus risus, molestie sed volutpat nec, eleifend vitae ligula. Nulla porttitor elit vel augue pretium cursus. Donec in turpis lectus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Quisque a lorem eu turpis viverra sodales. Pellentesque justo arcu, venenatis nec hendrerit a, molestie vitae augue.

produces:

$ ruby golf.rb < input.txt
consequat - 9
ullamcorper - 9
Vestibulum - 9

GoRuby 2.0.0 – 29 chars (not exact output format)

s$<.sp.m{|x|[x.ch.u.sz,x]}.mx

Expects input from stdin. The output format is a little bit different, though. For example:

$ ruby golf.rb < british.1
14
manoeuvrability

GoRuby 2.0.0 – 42 40 chars

s$<.r.sp.m{|x|[x.ch.u.sz,x]}.mx.rv*' - '

expects input from stdin

Ruby 1.9.3 - 69 65 chars

puts$<.read.split.map{|x|[x.chars.uniq.size,x]}.max.reverse*' - '

expects input from stdin (same as above, but without GoRuby abbreviations)

Javascript 163 155 152 162 bytes

This is about as short as I can get it:

prompt(x=[]).split(/\s/).forEach(function(a){b={};c=0;a.split('').forEach(function(d){b[d]?1:b[d]=++c});x[c]?x[c].push(a):x[c]=[a]});alert((l=x.length-1)+':'+x[l])
prompt(x=[]).split(/\b/).map(function(a){b={};c=0;a.split('').map(function(d){b[d]?1:b[d]=++c});x[c]?x[c].push(a):x[c]=[a]});alert((l=x.length-1)+':'+x[l])
prompt(x=[]).split(/\s/).map(function(a){b=[c=0];a.split('').map(function(d){b[d]?1:b[d]=++c});x[c]=(x[c]||[]).concat(a)});alert((l=x.length-1)+':'+x[l])

prompt(x=[]).split(/\s/).map(function(a){b=[c=0];a.split('').map(function(d){b[d]?1:b[d]=++c});x[c]=(x[c]||[]).concat(a)});alert((l=x.length-1)+':'+x[l].join('\n'))

In this version /\s/ separates words based on whitespace, so it includes punctuation, commas, periods, etc as part of words. This is easily changed to /\b/ to not included them.

I'll see what I can do with for-loops instead of forEaches in a bit.

I/O:

It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way - in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.

11:incredulity,

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec mollis, nisl sit amet consequat fringilla, justo risus iaculis justo, vel ullamcorper dui tellus ut enim. Suspendisse lectus risus, molestie sed volutpat nec, eleifend vitae ligula. Nulla porttitor elit vel augue pretium cursus. Donec in turpis lectus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Quisque a lorem eu turpis viverra sodales. Pellentesque justo arcu, venenatis nec hendrerit a, molestie vitae augue.

9:consequat
ullamcorper
Vestibulum

A little tired, perhaps. But I feel peaceful. Your success in the ring this morning was, to a small degree, my success. Your future is assured. You will live, secure and safe, Wilbur. Nothing can harm you now. These autumn days will shorten and grow cold. The leaves will shake loose from the trees and fall. Christmas will come, and the snows of winter. You will live to enjoy the beauty of the frozen world, for you mean a great deal to Zuckerman and he will not harm you, ever. Winter will pass, the days will lengthen, the ice will melt in the pasture pond. The song sparrow will return and sing, the frogs will awake, the warm wind will blow again. All these sights and sounds and smells will be yours to enjoy, Wilbur—this lovely world, these precious days…

10:Wilbur—this

Nearly all children nowadays were horrible. What was worst of all was that by means of such organizations as the Spies they were systematically turned into ungovernable little savages, and yet this produced in them no tendency whatever to rebel against the discipline of the Party. On the contrary, they adored the Party and everything connected with it... All their ferocity was turned outwards, against the enemies of the State, against foreigners, traitors, saboteurs, thought-criminals. It was almost normal for people over thirty to be frightened of their own children.

15:thought-criminals.

Mathematica 96 115

Edit: code now finds all words of the maximum number of characters. I refuse to treat commas as word characters.

f@t := With[{r = {#, Length@Union@Characters@#} & /@ 
StringSplit[t,RegularExpression@"\\W+"]},  Cases[r, {_, Max[r[[All, 2]]]}]]

Examples

f@"It was the best of times,...of comparison only."

or

f@Import["t1.txt"]

{{"incredulity", 10}, {"superlative", 10}}


f@"Lorem ipsum... vitae augue."

or

f@Import["t2.txt"]

{"Vestibulum", 9}


Longer Examples

f@Import["ShakespearesSonnets.txt"]
f@Import["OriginOfSpecies.txt"]
f@Import["DeclarationOfIndependence.txt"]
f@Import["DonQuixoteISpanish.txt"]
f@Import["AliceInWonderland.txt"]
f@Import["UNHumanRightsGerman.txt"]
f@Import["GenesisKJV.txt"]

Surprise: The most "unique" word in the Declaration of Independence is also the most unique word in Alice in Wonderland!

{"prognosticate", 11}
{"undiscoverable", 13}
{"uncomfortable", 12}
{"regocijadamente", 12}
{"uncomfortable", 12}
{"Verpflichtung", 13}
{"buryingplace", 12}

Perl 78 bytes

map{push$_[keys{map{$_,1}/./g}]||=[],$_}split for<>;print"$_ $#_
"for@{$_[-1]}

Interpretting the restriction "The text document must be read in by your code" to mean that command line options that read and parse the input are not allowed. As with the PHP solution below, only characters 10 and 32 are considered to be word delimiters. Input and output are also taken in the same manner.


PHP 128 bytes

<?foreach(split(~߃õ,fread(STDIN,1e6))as$s){$w[count(count_chars($s,1))][]=$s;}krsort($w)?><?=join($f=~ß.key($w).~õ,pos($w)),$f;

The only characters considered to be word delimiters are characer 10, and character 32. The rest, including puncuation, are considered to be part of the word.

This contains a few binary characters, which saves quotation marks, but as a result needs to be saved with an ANSI encoding in order to function properly. Alternatively, this version can be used, which is 3 bytes heavier:

<?foreach(split(' |
',fread(STDIN,1e6))as$s){$w[count(count_chars($s,1))][]=$s;}krsort($w)?><?=join($f=' '.key($w).'
',pos($w)),$f;

Sample I/O:

input 1:

It was the best of times, it was the worst of times, it was the age of wisdom,
it was the age of foolishness, it was the epoch of belief, it was the epoch of
incredulity, it was the season of Light, it was the season of Darkness, it was
the spring of hope, it was the winter of despair, we had everything before us,
we had nothing before us, we were all going direct to Heaven, we were all going
direct the other way - in short, the period was so far like the present period,
that some of its noisiest authorities insisted on its being received, for good
or for evil, in the superlative degree of comparison only.

output 1:

$ php most-unique.php < input1.dat
incredulity, 11

input 2:

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec mollis, nisl sit
amet consequat fringilla, justo risus iaculis justo, vel ullamcorper dui tellus
ut enim. Suspendisse lectus risus, molestie sed volutpat nec, eleifend vitae
ligula. Nulla porttitor elit vel augue pretium cursus. Donec in turpis lectus.
Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia
Curae; Quisque a lorem eu turpis viverra sodales. Pellentesque justo arcu,
venenatis nec hendrerit a, molestie vitae augue.

output 2:

$ php most-unique.php < input2.dat
consequat 9
ullamcorper 9
Vestibulum 9