Znalezienie najbardziej „unikalnego” słowa

12

Używając wybranego języka, napisz najkrótszą możliwą funkcję / skrypt / program, który zidentyfikuje słowo o największej liczbie unikalnych liter w tekście.

  • Unikalne litery powinny zawierać dowolny wyraźny znak wykorzystujący kodowanie UTF-8 .
    • Wielkie i małe wersje tego samego znaku są różne i wyraźne; 'a' != 'A'
  • Słowa są powiązane dowolnymi znakami spacji.
  • „Litery” to dowolny symbol, który może być reprezentowany przez pojedynczy znak Unicode.
  • Dokument tekstowy musi zostać wczytany przez Twój kod - niedozwolone jest wstępne ładowanie / kodowanie tekstu.
  • Wynikiem powinno być słowo, a po nim liczba unikalnych liter.
    • llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch - 18
    • Wszelkie separatory / odstępy między tymi dwiema wartościami zależą od Ciebie, o ile istnieje co najmniej jeden znak do ich rozdzielenia.
  • W przypadku, gdy istnieje więcej niż jedno słowo o najwyższej liczbie, wydrukuj wszystkie słowa dla tej liczby, z jedną nową linią oddzielającą.
    przeświadczenie - 16
    pseudolamellibranchiate - 16
  • To jest kod golfowy, więc wygrywa najkrótszy kod.

Ta odpowiedź na English.SE zainspirowała mnie do stworzenia tego wyzwania. W przykładzie użyto tylko listy słów , ale każdy tekst powinien być przetwarzany.

Gaffi
źródło
1
Jak słowa są rozdzielone? Mówisz, że unikalne litery to dowolne znaki UTF-8, ale to sugerowałoby, że cały plik jest tylko jednym słowem.
cardboard_box
1
Jak tu definiujesz litery? Jak właśnie wskazałem na jednej z angielskich odpowiedzi. SE LlanfairPGjest słowem walijskim i zawiera litery alfabetu walijskiego - lli choba są pojedynczymi literami w języku walijskim.
Gareth
1
@Gareth Nie zdawałem sobie sprawy z tego rozróżnienia, mój błąd. Czy istnieją reprezentacje tych dwóch „liter” w standardzie Unicode? Na potrzeby tego wyzwania każdy indywidualny znak Unicode jest literą.
Gaffi
1
Czy abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+~`<>/\\?'";:{}[],.to prawidłowe „słowo”?
Shmiddty,
2
Nie na temat, ale najwyraźniej były tam pojedyncze litery dla LL i II w języku walijskim. Przynajmniej Unicode ma dla nich U + 1EFA i U + 1EFB; Nazywa je „środkowo-walijski”. Nie ma jednak tytułu do Ll.
Pan Lister,

Odpowiedzi:

7

APL (56)

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

Jest to funkcja (pytanie mówi, że jest to dozwolone), która pobiera ciąg znaków i zwraca macierz słów i unikalne długości.

Stosowanie:

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

Wyjaśnienie:

  • ⎕ML←3: ustaw poziom migracji na 3 (czyli partycja zamiast załączenia)
  • W←⍵⊂⍨⍵≠' ': przechowuj w Wpodanym ciągu, gdzie każda partycja składa się ze znaków spacji.
  • ⍙←⍒∆←↑∘⍴∘∪¨W: pobierz ilość ( ) unikalnych ( ) elementów w każdej części ( ¨) Wi zapisz je , a następnie uzyskaj porządek sortowania po posortowaniu w dół na tej ( ) i zapisz w .
  • ∆[⍙... ]: sortuj według , więc teraz mamy unikalne długości w kolejności.
  • ∆∘.=∆←∆: zapisz posortowane z powrotem i sprawdź, które elementy są równe.
  • ↑+/: zsumuj wiersze (teraz wiemy, ile elementów jest równych każdemu elementowi), a następnie weź pierwszy element (teraz wiemy, ile elementów jest równych pierwszemu elementowi, tj. ile słów jest powiązanych na pierwszym miejscu).
  • W[⍙]⍴⍨: posortuj Wwedług i weź pierwsze N, gdzie N jest liczbą, którą właśnie obliczyliśmy.
  • {⍵,⍴∪⍵}¨: dla każdego z nich uzyskaj samo słowo i liczbę unikalnych znaków w słowie
  • : format jako macierz
marinus
źródło
4

Mathematica 96 115

Edycja : kod znajduje teraz wszystkie słowa maksymalnej liczby znaków. Odmawiam traktowania przecinków jako znaków słownych.

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

Przykłady

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

lub

f@Import["t1.txt"]

{{„niedowierzanie”, 10}, {„superlative”, 10}}


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

lub

f@Import["t2.txt"]

{„Vestibulum”, 9}


Dłuższe przykłady

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"]

Niespodzianka: najbardziej „unikalne” słowo w Deklaracji Niepodległości jest również najbardziej wyjątkowym słowem w Alicji w Krainie Czarów !

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

DavidC
źródło
czy to zwraca tylko jedno najbardziej unikalne słowo? Powinien zwrócić je wszystkie. np. „superlatyw, niedowierzanie, 10”
Shmiddty
@Shmiddty Zwróciłem się do twojej krytyki. (Kosztował 19 bajtów.)
DavidC
4

Python 2 (110 (98 przy użyciu wprowadzania plików))

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

Co poprawić: drukowanie (33 znaki)

Interpunkcję uważa się za litery.

beary605
źródło
Python 2.7.3: NameError: global name 'r' is not defined. Po dodaniu apostrofów wokół r: AttributeError: 'file' object has no attribute 'split'. Python 3.3.0: SyntaxError: invalid syntax 'print i,c'.
primo,
Ups, nie przetestowałem tego. Dzięki, że to powiedziałeś, nigdy bym tego nie widział. Co do Pythona 3: nie działa.
beary605
4

To mój pierwszy codegolf, jestem bardzo podekscytowany :) Oznacza to również, że prawdopodobnie nie jest dobry.

Groovy 127 117 112 105

Edycja: Ponieważ funkcje tutaj wydają się być dozwolone, jest to jedna na 105. Zmieniłem również nazwy zmiennych, aby pierwsza kolumna czytała ACDC, ponieważ jest to ważne w każdym kodzie źródłowym:

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

Można to tak nazwać:

A (nowy plik („words.txt”))

Bez funkcji przy użyciu standardowego wejścia w numerze 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 "$ to $ k "}}

Dane wejściowe: Lorem Ipsum Tekst z primo

Dane wyjściowe wszystkich skryptów:

consequat 9
ullamcorper 9
Vestibulum 9

Czy ktoś wpadł na pomysł, jak uczynić je bardziej atrakcyjnymi?

Fels
źródło
3

Perl 78 bajtów

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

Interpretacja ograniczenia „Dokument tekstowy musi zostać wczytany przez Twój kod”, co oznacza, że ​​opcje wiersza poleceń, które czytają i analizują dane wejściowe, są niedozwolone. Podobnie jak w poniższym rozwiązaniu PHP, tylko znaki 10 i 32 są uznawane za separatory słów. Wejście i wyjście są również brane w ten sam sposób.


PHP 128 bajtów

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

Jedynymi znakami uważanymi za ograniczniki słów są znak 10 i znak 32. Reszta, w tym znaki interpunkcyjne, są uważane za część słowa.

Zawiera on kilka znaków binarnych, które zapisują znaki cudzysłowu, ale w związku z tym należy je zapisać z kodowaniem ANSI, aby działać poprawnie. Alternatywnie można użyć tej wersji, która jest o 3 bajty cięższa:

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

Przykładowe I / O:

wejście 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.

wyjście 1:

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

wejście 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.

wyjście 2:

$ php most-unique.php < input2.dat
consequat 9
ullamcorper 9
Vestibulum 9
primo
źródło
incredulityma 10 unikalnych liter, a nie 11.
DavidC
@DavidCarraher jego kod zawiera przecinek, co teoretycznie jest dozwolone przez reguły.
Shmiddty,
Wyjaśnienie jest absolutnie niewiarygodne.
DavidC,
2
Jest to nie tylko „teoretycznie dozwolone”, ale biorąc pod uwagę treść pytania (w szczególności pkt 2 i 3), wydaje się, że jest to wymóg.
primo,
@DavidCarraher Tak, interpunkcja to poprawne znaki. Wszystko inne niż białe znaki jest poprawne.
Gaffi
3

GoRuby 2.0.0 - 66 znaków

Poniższe rozwiązania nie znalazły wszystkich dopasowań, ale tylko jeden. Oto moja ostateczna wersja:

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

Przykłady:

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec mollis, nisl sit ametsequat fringilla, justo risus iaculis justo, vel ullamcorper dui tellus ut enim. Suspendisse lectus risus, molestie sed volutpat gdzie indziej niesklasyfikowana, 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.

produkuje:

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

GoRuby 2.0.0 - 29 znaków (niedokładny format wyjściowy)

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

Oczekuje danych wejściowych ze standardowego wejścia. Format wyjściowy jest jednak nieco inny. Na przykład:

$ ruby golf.rb < british.1
14
manoeuvrability

GoRuby 2.0.0 - 42 40 znaków

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

oczekuje danych wejściowych od standardowego wejścia

Ruby 1.9.3 - 69 65 znaków

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

oczekuje danych wejściowych od standardowego wejścia (takie same jak powyżej, ale bez skrótów GoRuby)

Patrick Oscity
źródło
2

JavaScript 163 155 152 162 bajtów

To jest tak krótko, jak mogę to uzyskać:

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'))

W tej wersji /\s/słowa są oddzielane na podstawie białych znaków, więc zawiera interpunkcję, przecinki, kropki itp. Jako część słów. Można to łatwo zmienić, aby /\b/ich nie uwzględnić.

Za chwilę zobaczę, co mogę zrobić z pętlami for zamiast zamiast forEaches.

I / O:

To były najlepsze czasy, to były najgorsze czasy, to był wiek mądrości, to był wiek głupoty, to była epoka wiary, to była epoka niedowierzania, to była pora Światła, to była pora Ciemności, wiosna nadziei, zima rozpaczy, mieliśmy przed sobą wszystko, nie mieliśmy przed sobą niczego, wszyscy jechaliśmy prosto do Nieba, wszyscy zmierzaliśmy w drugą stronę - w Krótko mówiąc, okres był do tej pory podobny do okresu obecnego, że niektórzy z jego najgłośniejszych autorytetów nalegali na otrzymanie go dla dobra lub zła jedynie w najwyższym stopniu.

11:incredulity,

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec mollis, nisl sit ametsequat fringilla, justo risus iaculis justo, vel ullamcorper dui tellus ut enim. Suspendisse lectus risus, molestie sed volutpat gdzie indziej niesklasyfikowana, 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

Może trochę zmęczony. Ale czuję się spokojny. Pański sukces na ringu był w pewnym stopniu moim sukcesem. Twoja przyszłość jest zapewniona. Będziesz żyć, bezpiecznie i bezpiecznie, Wilbur. Nic nie może ci teraz zaszkodzić. Te jesienne dni skracają się i stają się zimne. Liście uwolnią się z drzew i spadną. Nadejdą święta i śniegi zimy. Będziesz żył, aby cieszyć się pięknem zamarzniętego świata, ponieważ wiele znaczysz dla Zuckermana, a on nigdy cię nie skrzywdzi. Zima minie, dni się wydłużą, lód rozpłynie się w stawie pastwiskowym. Wróbel pieśni powróci i zaśpiewa, żaby się obudzą, ciepły wiatr znów wróci. Wilbur - ten cudowny świat, te cenne dni…

10:Wilbur—this

Prawie wszystkie dzisiejsze dzieci były okropne. Najgorsze było to, że dzięki takim organizacjom, jak Szpiedzy, systematycznie przekształcano ich w nie dających się opanować małych dzikusów, a jednak nie powodowało to u nich skłonności do buntowania się przeciwko dyscyplinie partii. Przeciwnie, uwielbiali Partię i wszystko, co z nią związane ... Cała ich zaciekłość została skierowana na zewnątrz, przeciwko wrogom państwa, przeciwko obcokrajowcom, zdrajcom, sabotażystom, myślicielom. Ludzie w wieku powyżej trzydziestu lat bali się własnych dzieci.

15:thought-criminals.
Shmiddty
źródło
W wyniku występuje potencjalna niezręczność: jeśli na wyjściu znajduje się wiele słów, a jedno ze słów kończy się przecinkiem, może to oznaczać dwa przecinki z rzędu, co może być mylące.
Shmiddty,
Ze specyfikacji,In the event more than one word exists with the highest count, print all words for that count, **with one new line delimiting**.
Gaffi
@ Gaffi powinno zostać naprawione teraz. 10 bajtów>. <
Shmiddty
2

Scala 129 znaków:

def f{
val l=readLine.split(" ").map(s=>(s,s.distinct.length)).sortBy(_._2)
println(l.filter(x=>x._2==l.last._2).mkString)}
nieznany użytkownik
źródło
2

R - 106 znaków
Jako funkcja z tekstem wejściowym jako parametrem:

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

I kilka przykładów:

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"

Lub R - 100 znaków
Jako funkcja ze ścieżką do pliku tekstowego jako parametrem:

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

Stosowanie:

f("t1.txt")
Read 120 items
     [,1]           [,2]
[1,] "incredulity," "11"
plannapus
źródło
Myślę, że tego brakuje „Dokument tekstowy musi zostać odczytany przez twój kod”.
Steven Rumbalski
@StevenRumbalski to jest poprawione.
plannapus
1

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]])
Raufio
źródło
1

Python3 119

Odczytuje z pliku o nazwie 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())))

Testowany z tekstami wejściowymi z @primo:

Input 1:
    ('incredulity,', 11)

Input 2:
    ('Vestibulum', 9)
    ('consequat', 9)
    ('ullamcorper', 9)
gcq
źródło
0

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
Gaffi
źródło