Qual è la parola più frequente?


26

Qual è la parola più frequente?

Data una frase, il tuo programma deve farsi strada, contando le frequenze di ogni parola, quindi emettere la parola più utilizzata. Poiché una frase non ha una lunghezza fissa e pertanto può richiedere molto tempo, il codice deve essere il più breve possibile.

Regole / Requisiti

  • Ogni invio dovrebbe essere un programma o una funzione completi. Se è una funzione, deve essere eseguibile solo aggiungendo la chiamata di funzione nella parte inferiore del programma. Qualsiasi altra cosa (ad es. Intestazioni in C) deve essere inclusa.
  • Deve essere disponibile un interprete / compilatore gratuito per la tua lingua.
  • Se possibile, fornire un collegamento a un sito in cui è possibile testare il programma.
  • Il tuo programma non deve scrivere nulla su STDERR.
  • Il tuo programma dovrebbe ricevere input da STDIN(o l'alternativa più vicina nella tua lingua).
  • Sono vietate le scappatoie standard .
  • Il vostro programma deve essere case-insensitive ( tHe, Thee thetutti contribuiscono al conteggio dei the).
  • Se non ci sono parole più frequenti (vedi caso di test n. 3), il tuo programma non dovrebbe produrre nulla.

Definizione di una 'parola':

Ottieni l'elenco di parole suddividendo il testo di input negli spazi. L'input non conterrà mai nessun altro tipo di spazio bianco che gli spazi semplici (in particolare nessuna nuova riga). Tuttavia, le parole finali dovrebbero contenere solo caratteri alfanumerici (az, AZ, 0-9), trattini (-) e apostrofi ('). Puoi farlo rimuovendo tutti gli altri personaggi o sostituendoli con lo spazio prima di dividere la parola. Per rimanere compatibili con le versioni precedenti delle regole, non è necessario includere gli apostrofi.

Casi test

The man walked down the road.
==> the

-----

Slowly, he ate the pie, savoring each delicious bite. He felt like he was truly happy.
==> he

-----

This sentence has no most frequent word.
==> 

-----

"That's... that's... that is just terrible!" he said.
==> that's / thats

-----

The old-fashioned man ate an old-fashioned cake.
==> old-fashioned

-----

IPv6 looks great, much better than IPv4, except for the fact that IPv6 has longer addresses.
==> IPv6

-----

This sentence with words has at most two equal most frequent words.
==>

Nota: il terzo e il settimo caso di test non hanno output, è possibile scegliere il quarto.

punteggio

I programmi vengono classificati in base ai byte. Il solito set di caratteri è UTF-8, se ne usi un altro, specifica.

Al termine della sfida, il programma con il minor numero di byte (si chiama ), vincerà.

Inseriti

Per assicurarti che la tua risposta venga visualizzata, ti preghiamo di iniziare la risposta con un titolo, utilizzando il seguente modello Markdown:

# Language Name, N bytes

dov'è Nla dimensione del tuo invio. Se si migliora il punteggio, è possibile mantenere i vecchi punteggi nel titolo, colpendoli. Per esempio:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Se si desidera includere più numeri nell'intestazione (ad es. Perché il punteggio è la somma di due file o si desidera elencare separatamente le penalità del flag dell'interprete), assicurarsi che il punteggio effettivo sia l' ultimo numero nell'intestazione:

# Perl, 43 + 2 (-p flag) = 45 bytes

Puoi anche rendere il nome della lingua un collegamento che verrà quindi visualizzato nello snippet della classifica:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes

Classifica

Ecco uno snippet di stack per generare sia una classifica regolare che una panoramica dei vincitori per lingua.


2
I commenti non sono per una discussione estesa; questa conversazione è stata spostata in chat .
Maniglia della porta

1
Quindi, data la tua nuova definizione di "parola", qual è la parola più comune qui don't d'ont dont a a? Sarebbe dont?
DJMcMayhem

@DrGreenEggsandHamDJ Se si dispone di una sottomissione che fa apostrofi rimuovere, dont. In caso contrario a,. ma la maggior parte degli invii lo fanno, e quindi dontè una risposta corretta.
George Gibson,

1
L'output è sensibile al maiuscolo / minuscolo? Quindi è ipv6valido un output per l'ultimo caso di test?
Kirbyfan64sos,

1
Potrebbe essere utile un ulteriore test: "Questa frase con parole ha al massimo due parole uguali più frequenti." -> <nulla>
philcolbourn,

Risposte:


6

Pyke, 26 25 byte

l1dcD}jm/D3Sei/1qIi@j@
(;

Provalo qui!

O 23 22 byte (non competitivo, aggiungi nodo dove uccide lo stack se falso)

l1cD}jm/D3Sei/1q.Ii@j@

Provalo qui!

O con punteggiatura, 23 byte (penso che questo competa? Commit era prima della modifica)

l1.cD}jm/D3Sei/1q.Ii@j@

Provalo qui!

O 12 byte (sicuramente non competitivi)

l1.cj.#jR/)e

Provalo qui!

l1           -     input.lower()
  .c         -    punc_split(^)
    j        -   j = ^
     .#   )  -  sort(V(i) for i in ^)
       jR/   -   j.count(i)
           e - ^[-1]

La risposta di 23 byte sarebbe in competizione se l'unica punteggiatura conservata fosse -e '(trattino e apostrofo).
George Gibson,

Conserva solo la punteggiatura che non è alla fine di una parola
Blue

Oh, ok (non capisco Pyke). Immagino che competa allora ...
George Gibson,

1
@GeorgeGibson Sono abbastanza sicuro che la versione a 23 byte non sia in competizione: potrebbe trovarsi in scappatoie standard. Inoltre non mi aspetto (m) che qualcuno capisca Pyke, lo sto facendo come la mia lingua
Blue

Bene allora. Penso che vincerai comunque, quindi non importa.
George Gibson,


11

Pyth - 23 30 byte

Ci deve essere un modo migliore per includere cifre e trattini, ma voglio solo risolvere questo problema in questo momento.

Kc@s+++GUTd\-rzZ)I!tJ.M/KZ{KhJ

Test Suite .


1
Le regole riviste richiedono la conservazione di cifre e trattini.
Dennis,

@GeorgeGibson risolto.
Maltysen,

6

Ottava, 115 94 byte

[a,b,c]=unique(regexp(lower(input('')),'[A-z]*','match'));[~,~,d]=mode(c); try disp(a{d{:}})

Conta per il caso senza parole più frequenti utilizzando try. In questo caso non genera nulla e "fa una pausa" fino a quando non si rileva l'eccezione.

Hai salvato 21 (!) Byte grazie al suggerimento di Luis Mendo (usando il terzo output da modeper ottenere la parola più comune).


Le regole sono cambiate un po 'da quando ho pubblicato la mia risposta originale. Esaminerò la regex più tardi.


1
mi hai battuto, penserò per qualcos'altro ora.
Abr001,

Fare domanda modesu cforse? La sua terza uscita fornisce tutti i valori legati, se ricordo bene
Luis Mendo

Conto 115 byte.
Conor O'Brien,

Credo che la tua regex dovrebbe essere ['\w\d]perché devi conservare apostrofi e cifre. A meno che non siano tra maiuscole e minuscole in ASCII, nel qual caso ignorami perché non ho una tabella a portata di mano.
Fondi Monica's Lawsuit

1
@StewieGriffin [~, ~, out] = mode([1 1 2 2 1 2 3 4 5 5])out = {1 2}
Luis Mendo

5

Perl 6, 80 byte

{$_>1&&.[0].value==.[1].value??""!!.[0].key given .lc.words.Bag.sort:{-.value}}

Dividiamo la risposta in due parti ...

given .lc.words.Bag.sort:{-.value}

givenè un'istruzione di controllo (come ifo for). In Perl 6, sono consentiti come postfissi. ( a if 1o come qui, foo given 3). giveninserisce il suo argomento (lato destro) nella variabile speciale $_per il lato sinistro.

L '"argomento" in sé minuscolo ( lc), suddiviso per parola ( words), inserisce i valori in un Bag (impostato con il numero di occorrenze), quindi ordina per valore (DESC). Dato sortche sa solo operare su liste, qui Bagviene trasformato in a Listdi Pairs.

$_>1&&.[0].value==.[1].value??""!!.[0].key

un semplice condizionale ( ?? !!sono usati in Perl 6, invece di ? :).

$_ > 1

Controlla solo che l'elenco abbia più di un elemento.

.[0].value==.[1].value

Gli accessi a $_possono essere abbreviati ... Non specificando la variabile. .aè esattamente come $_.a. Quindi questo è effettivamente "entrambi gli elementi superiori hanno lo stesso numero di occorrenze" - In tal caso, stampiamo '' (la stringa vuota).

In caso contrario, il risultato della stampa chiave dell'elemento superiore (il conte): .[0].key.


7
È come metà inglese e metà rumore. Stupefacente.
gatto

1
è divertente come siano le funzionalità in stile OO che sembrano inglese-y: P
Ven

2
Riesce anche a essere meno leggibile di Perl 5 mentre contiene più inglese di Perl 5. D:
cat

1
@cat ha risolto il problema - dovrebbe essere totalmente illeggibile ora
Ven

5
value??!!(So ​​che è un operatore ternario, è solo divertente)
cat


4

JavaScript (ES6), 155 byte

s=>(m=new Map,s.toLowerCase().replace(/[^- 0-9A-Z]/gi,'').split(/\ +/).map(w=>m.set(w,-~m.get(w))),[[a,b],[c,d]]=[...m].sort(([a,b],[c,d])=>d-b),b==d?'':a)

Basato sulla risposta Python di @ Blue.


La tua sostituzione regex sembra far cadere i numeri e romperà il caso di test IPv6, giusto?
Tessellating Heckler,

@TessellatingHeckler La definizione di parola è cambiata da quando ho letto la domanda in origine, ma ho aggiornato la mia risposta ora.
Neil,

4

Python 3.5, 142 137 134 112 117 110 127 byte:

( +17 byte, perché apparentemente anche se ci sono parole più frequenti delle altre, ma hanno la stessa frequenza, nulla dovrebbe essere ancora restituito. )

def g(u):import re;q=re.findall(r"\b['\-\w]+\b",u.lower());Q=q.count;D=[*map(Q,{*q})];return['',max(q,key=Q)][1in map(D.count,D)]

Ora dovrebbe soddisfare tutte le condizioni. Questa presentazione presuppone che sia stata inserita almeno 1 parola.

Provalo online! (Ideone)

Inoltre, se ne vuoi uno, ecco un'altra versione della mia funzione priva di qualsiasi espressione regolare al costo di circa 43 byte, sebbene questa non sia comunque competitiva, quindi non importa davvero. L'ho appena messo qui per diamine:

def g(u):import re;q=''.join([i for i in u.lower()if i in[*map(chr,range(97,123)),*"'- "]]).split();Q=q.count;D=[*map(Q,{*q})];return['',max(q,key=Q)][1in map(D.count,D)]

Prova questa nuova versione online! (Ideone)


Dai commenti della sfida "se ci sono due parole più frequenti delle altre, ma con la stessa frequenza", l'output è "niente".
Root Due

@RootTwo Fixed! :)
R. Kap

@TessellatingHeckler Queste sono parole diverse però. That'sè una contrazione per that ismentre in thatsrealtà non è una parola.
R. Kap,

@TessellatingHeckler Puoi darmi qualche prova di questo commento? Perché sto esaminando tutti i commenti sul post e non vedo tali commenti.
R. Kap,

4

Ruby, 94 92 102 byte

Devo andare veloce (risposta FGITW). Restituisce la parola in maiuscolo onil se non è presente la parola più frequente.

Ora aggiornato a nuove specifiche, penso. Tuttavia, sono riuscito a giocare a golf un po ', quindi il conteggio dei byte è lo stesso!

->s{w=s.upcase.tr("_'",'').scan /[-\w]+/;q=->x{w.count x};(w-[d=w.max_by(&q)]).all?{|e|q[e]<q[d]}?d:p}

5
Gotta go fast?
gatto

@cat sì, perché stavolta ero FGITW
Value Ink


3

JavaScript (ES6), 99 byte

F=s=>(f={},w=c='',s.toLowerCase().replace(/[\w-']+/g,m=>(f[m]=o=++f[m]||1)-c?o>c?(w=m,c=o):0:w=''),w)
#input { width: 100%; }
<textarea id="input" oninput="output.innerHTML=F(this.value)"></textarea>
<div id="output"></div>


3

SQL Server 2008, 250 byte

DECLARE @ varchar(max) = 'That''s... that''s... that is just terrible!" he said.';

WITH c as(SELECT
@ p,@ x
UNION ALL
SELECT LEFT(x,k-1),STUFF(x,1,k,'')FROM
c CROSS APPLY(SELECT patindex('%[^a-z''-]%',x+'!')k)k
WHERE''<x)SELECT max(p)FROM(SELECT top 1with ties p
FROM c WHERE p>''GROUP BY p
ORDER BY count(*)DESC
)j HAVING count(*)=1

Provalo online!

SQL Server 2016, 174 byte

Impossibile gestire dati come questo esempio (contando gli uguali come 3 parole):

DECLARE @ varchar(max) = 'That''s... that''s... that is just terrible!" he said. = = ='

SELECT max(v)FROM(SELECT TOP 1WITH TIES value v
FROM STRING_SPLIT(REPLACE(REPLACE(REPLACE(@,'"',''),',',''),'.',''),' ')GROUP
BY value ORDER BY count(*)DESC)x HAVING count(*)=1

Non mi piace l'approccio variabile perché è un po 'barare :) Un input -> niente o qualcosa, con un approccio basato su set deve essere più lungo, perché è necessario aggiungere GROUP BY, LEFT JOIN, or PARTITION BYcomunque SQL Server ha incorporato la funzione SPLIT. La demo Ungolfed è libera di renderla il più breve possibile.
lad2025,

@ lad2025 grazie mille, non conoscevo nessuna funzionalità del 2016. SPLIT_STRING è sicuramente una funzionalità attesa da tempo. Ho provato a golfare lo script usando split, l'ho portato a 174, tuttavia non sarà in grado di filtrare il testo come "= = ="
t-clausen.dk

3

PostgreSQL, 246 , 245 byte

WITH z AS(SELECT DISTINCT*,COUNT(*)OVER(PARTITION BY t,m)c FROM i,regexp_split_to_table(translate(lower(t),'.,"''',''),E'\\s+')m)
SELECT t,CASE WHEN COUNT(*)>1 THEN '' ELSE MAX(m)END
FROM z WHERE(t,c)IN(SELECT t,MAX(c)FROM z GROUP BY t)
GROUP BY t  

Produzione:

enter image description here

Inserisci se qualcuno è interessato:

CREATE TABLE i(t TEXT);

INSERT INTO i(t)
VALUES ('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.'), ('a   a            a b b b c');


Normalmente userei MODE() WITHIN GROUP(...)e sarà molto più breve, ma violerà:

Se non ci sono parole più frequenti (vedi caso di test n. 3), il tuo programma non dovrebbe produrre nulla.


MODIFICARE:

Trattamento ':

WITH z AS(SELECT DISTINCT*,COUNT(*)OVER(PARTITION BY t,m)c FROM i,regexp_split_to_table(translate(lower(t),'.,"!',''),E'\\s+')m)
SELECT t,CASE WHEN COUNT(*)>1 THEN '' ELSE MAX(m)END
FROM z WHERE(t,c)IN(SELECT t,MAX(c)FROM z GROUP BY t)
GROUP BY t  

SqlFiddleDemo

Produzione:

╔═══════════════════════════════════════════════════════════════════════════════════════════════╦═══════════════╗
║                                              t                                                ║      max      ║
╠═══════════════════════════════════════════════════════════════════════════════════════════════╬═══════════════╣
║ a a a b b b c                                                                                 ║               ║
║ The old-fashioned man ate an old-fashioned cake.                                              ║ old-fashioned ║
║ IPv6 looks great, much better than IPv4, except for the fact that IPv6 has longer addresses.  ║ ipv6          ║
║ This sentence has no most frequent word.                                                      ║               ║
║ "That's... that's... that is just terrible!" he said.                                         ║ that's        ║
║ The man walked down the road.                                                                 ║ the           ║
║ Slowly, he ate the pie, savoring each delicious bite. He felt like he was truly happy.        ║ he            ║
╚═══════════════════════════════════════════════════════════════════════════════════════════════╩═══════════════╝

non è riuscito a scendere come te, sqlserver non ha ancora compilato in split. Tuttavia, la parte selezionata è più corta.
t-clausen.dk

@GeorgeGibson Certo, riparato + aggiunta demo live.
lad2025,

@ lad2025 Di comune accordo nella chat, ciò che hai fatto non è più necessario, sentiti libero di tornare indietro.
George Gibson,

@GeorgeGibson Sì, la modifica sarà molto chiara. La demo live funziona ora, quando ho scritto la risposta sqlfiddle non rispondeva.
lad2025,

2

R, 115 byte

function(s)if(sum(z<-(y=table(tolower((x=strsplit(s,"[^\\w']",,T)[[1]])[x>""])))==max(y))<2)names(which(z))else NULL

Questa è una funzione che accetta una stringa e restituisce una stringa se una singola parola appare più spesso di altre e NULL non. Per chiamarlo, assegnarlo a una variabile.

Ungolfed:

f <- function(s) {
    # Create a vector of words by splitting the input on characters other
    # than word characters and apostrophes
    v <- (x <- strsplit(s, "[^\\w']", perl = TRUE))[x > ""]

    # Count the occurrences of each lowercased word
    y <- table(tolower(v))

    # Create a logical vector such that elements of `y` which occur most
    # often are `TRUE` and the rest are fase
    z <- y == max(y)

    # If a single word occurs most often, return it, otherwise `NULL`
    if (sum(z) < 2) {
        names(which(z))
    } else {
        NULL
    }
}

2

Retina, 97 byte

Le regole continuano a cambiare ...

T`L`l
[^-\w ]

O`[-\w]+
([-\w]+)( \1\b)*
$#2;$1
O#`[-\w;]+
.*\b(\d+);[-\w]+ \1;[-\w]+$

!`[-\w]+$

Provalo online!

Suite di test.



@ CᴏɴᴏʀO'Bʀɪᴇɴ Grazie, risolto.
Leaky Nun

1
E hai giocato a golf 11 byte ._. impressionante
Conor O'Brien

Fallisce anche per "L'uomo vecchio stile ha mangiato una torta vecchio stile".
t-clausen.dk,

Neanche questo sembra giusto (aspettandosi adi essere la parola più comune lì)
TessellatingHeckler,

2

Python, 132 byte

import collections as C,re
def g(s):(a,i),(b,j)=C.Counter(re.sub('[^\w\s-]','',s.lower()).split()).most_common(2);return[a,''][i==j]

Il codice sopra presuppone che l'input abbia almeno due parole.


Adoro quel regex, però.
Blue

Questo non è corretto La classe di caratteri \winclude caratteri di sottolineatura.
mbomb007,

1

PHP, 223 byte

$a=array_count_values(array_map(function($s){return preg_replace('/[^A-Za-z0-9]/','',$s);},explode(' ',strtolower($argv[1]))));arsort($a);$c=count($a);$k=array_keys($a);echo($c>0?($c==1?$k[0]:($a[$k[0]]!=$a[$k[1]]?$k[0]:'')):'');

1

Python 2, 218 byte

Presuppone più di 2 parole. Sbarazzarsi della punteggiatura mi ha distrutto ...

import string as z
def m(s):a=[w.lower()for w in s.translate(z.maketrans('',''),z.punctuation).split()];a=sorted({w:a.count(w)for w in set(a)}.items(),key=lambda b:b[1],reverse=1);return a[0][0]if a[0][1]>a[1][1]else''

Questa striscia ',-ecc?
Tim

@Tim No, ho fatto questa sfida prima che le regole fossero pienamente definite. Cambierà.
Blue

Puoi assegnare il risultato sorteda una tupla anziché dover indicizzare l'array manualmente?
Neil,

@Neil intendi semplicemente ottenere il primo e il secondo elemento per il confronto anziché l'intero array? Non so come farlo
Blue

1

Matlab (225)

  • Regole modificate: /

.

      function c=f(a),t=@(x)feval(@(y)y(y>32),num2str(lower(x)-0));f=@(x)num2str(nnz(x)+1);e=str2num(regexprep(a,'([\w''-]+)',' ${t($1)} ${f($`)} ${f([$`,$1])}'));[u,r,d]=mode(e);try c=find(e==d{:});c=a((e(c(1)+1)):(e(c(1)+2)));end
  • Toolbox è necessario per eseguire questo.

  • Come funziona, uno dei più bei privilegi di regex sostituisce in matlab questo campo esegue token chiamando funzioni esterne-ambientali parametrizzate dai token catturati nell'ambiente interno, quindi qualsiasi sequenza di "Word_A Word_B .."viene sostituita da numeri interi in "A0 A1 A2 B0 B1 B2 ..."cui è il primo intero la firma numerica ascii della parola, il secondo è l'indice di partenza, il terzo è l'indice di fine, questi ultimi due numeri interi non si duplicano nell'intera sequenza, quindi ho sfruttato questo vantaggio per trasporlo in un array, quindi modalizzarlo quindi cercare risulta in quell'array, quindi seguiranno gli indici di inizio / fine.

  • Modifica: dopo aver modificato alcuni dettagli, il programma viene chiamato funzione da un parametro stringa.


20 byte salvati grazie a @StewieGriffin, 30 byte hanno aggiunto rimproveri alle lacune concordate.


Avrai il mio voto quando tu (o qualcun altro) dimostrerai che questo funziona davvero, sia per gli input che hanno una parola più comune, sia per gli input che non lo fanno. =) (Purtroppo non posso provarlo)
Stewie Griffin,

@StewieGriffin penso che il programma si comporti in modo errato con frasi con parole di equi-frequenza che risolverò
Abr001am

1

05AB1E , 22 21 20 byte

žK„- JÃl#{D.MDgiJëõ?

Spiegazione:

žK                     # Push [a-zA-Z0-9]
  „-                   # Push 2-char string containing a hyphen and a space
     J                 # Join the stack into a single element
      Ã                # Removes all characters from implicit input except those specified above
       l               # Converts to lowercase
        #              # Split string by spaces
         {             # Sorts array
          D            # Duplicates
           .M          # Finds most common element
             Dg        # Gets length of string without popping
                 iJ    # If length == 1, then convert the array to a string (otherwise the output would be ['example'] instead of example
                   ëõ? # Else push an empty string.

Nota: se stai bene trascinando le nuove righe nell'output per quando non dovresti produrre nulla, rimuovi il ?alla fine per salvare un byte.

Nota n. 2: il programma non funzionerà con una sola parola, ma dubito che questo sarebbe un problema. Se vuoi risolvere questo problema, sostituiscilo #con ð¡un byte extra.

05AB1E utilizza CP-1252 come set di caratteri, non UTF-8.

Provalo online!


1

Perl, 60 56 55 54 byte

Include +3 per -p

#!/usr/bin/perl -p
s/[\pL\d'-]+/$;[$a{lc$&}++]++or$\=$&/eg}{$\x=2>pop@

Se una parola non può essere solo un numero, puoi anche rilasciare aper un punteggio di 53.


Il trattino nel -anEnon conta? Lo fa sull'altra risposta (+2 byte per la -pbandiera) ...
George Gibson,

@GeorgeGibson No, vedi meta.codegolf.stackexchange.com/questions/273/… . Il trattino, lo spazio e il Enon contano. L'altra risposta dovrebbe normalmente fare solo +1 byte per -p, ma la sua soluzione ha 'quindi non può essere vista come un'estensione di -eo -E. Quindi dovrebbe in effetti contare +3 (non +2) poiché dovrebbe contare lo spazio e il trattino (ma ogni opzione aggiuntiva sarebbe solo +1).
Ton Hospel,

@ TomHospel Oh, giusto.
George Gibson,

Questo è considerato valido data la regola dell'apostrofo? [\pL\d-]sembra che potrebbe essere ridotto a [\w-](a meno che non ci preoccupiamo dei caratteri di sottolineatura) ma entrambe le versioni riporteranno thatinvece that'so thatsper il test 4. Altrimenti, è necessario aggiungere 4 byte da inserire \x27in quella classe di caratteri (a meno che non si abbia un modo migliore di aggiungere un apostrofo).
Adam Katz,

@AdamKatz La definizione di 'word' è cambiata un po 'mentre era in esecuzione e non ho mai adottato completamente l'ultima versione. Ma per farti felice ho creato una versione fissa (e più breve) :-). E sì, mi occupo dei caratteri di sottolineatura
Ton Hospel,

0

PowerShell (v4), 117 byte

$y,$z=@($input-replace'[^a-z0-9 \n-]'-split'\s'|group|sort Count)[-2,-1]
($y,($z,'')[$y.Count-eq$z.Count])[!!$z].Name

La prima parte è abbastanza semplice:

  • $input è ~ = stdin
  • Regex sostituisce i caratteri irrilevanti con nulla, mantieni le nuove righe in modo da non mescolare due parole dalla fine di una riga e l'inizio della riga successiva in una per errore. (Nessun altro ha discusso di più righe, potrebbe golf -2 se l'input è sempre una singola riga).
  • Regex split, Groupper frequenza (~ = collezioni di Python.Counter), Sortper mettere le parole più frequenti alla fine.
  • PowerShell non distingue tra maiuscole e minuscole per impostazione predefinita per tutto.

Gestire se non c'è una parola più frequente:

  • Prendi gli ultimi due elementi [-2, -1] in $ ye $ z;
  • un elenco di elementi N, dove N> = 2, rende $ ye $ z gli ultimi due elementi
  • un elenco di 1 elemento rende $ y l'ultimo elemento e $ z null
  • un elenco vuoto li rende entrambi nulli

Usa il golf bool-as-array-index fake-ternary-operator (0,1)[truthyvalue], nidificato, per scegliere "", $ z o $ y come output, quindi prendi .Name.

PS D:\> "The man walked down the road."|.\test.ps1
The

PS D:\> "Slowly, he ate the pie, savoring each delicious bite. He felt like he was truly happy."|.\test.ps1
he

PS D:\> "`"That's... that's... that is just terrible!`" he said."|.\test.ps1
Thats

PS D:\> "The old-fashioned man ate an old-fashioned cake."|.\test.ps1
old-fashioned

PS D:\> "IPv6 looks great, much better than IPv4, except for the fact that IPv6 has longer addresses."|.\test.ps1
IPv6

0

Lua, 232 199 175 byte

w,m,o={},0;io.read():lower():gsub("[^-%w%s]",""):gsub("[%w-]+",function(x)w[x]=(w[x]or 0)+1 end)for k,v in pairs(w)do if m==v then o=''end if(v>m)then m,o=v,k end end print(o)

1
if not w[x]then w[x]=0 end w[x]=w[x]+1 end->w[x]=(w[x]or0)+1
Leaky Nun,

if m==v then o=''end->o=m==v and '' or o
Leaky Nun,

0

Perl 5, 96 92 84 + 2 ( -pflag) = 86 byte

++$h{+lc}for/\w(?:\S*\w)?/g}{$m>$e[1]||$e[1]>$m&&(($_,$m)=@e)||($_="")while@e=each%h

usando:

> echo "The man walked down the road." | perl -p script.pl

La tua -pbandiera dovrebbe invocare una penalità di 3 byte. Le regole sono all'incirca: ogni flag della riga di comando è +1 byte poiché è il numero di byte extra necessari per estendere la -e'code'riga di comando di stile libero . Quindi normalmente -pè solo +1 byte. Ma qui il tuo codice ha 'quindi non può essere eseguito semplicemente dalla riga di comando senza escape. Quindi nessuna combinazione con -ee lo -spazio e prima dello psono extra e devono essere contati anche
Ton Hospel

@TonHospel Risolto.
Denis Ibaev,

Questo è in realtà 84 + 1 ( -pflag) se lo invochi dalla riga di comando come perl -pe'…'(reso disponibile rimuovendo il 'come indicato nei primi commenti)
Adam Katz

0

Python, 158 byte

def g(s):import collections as c,re;l=c.Counter(re.sub('[^\w\s-]',"",s.lower()).split());w,f=l.most_common(1)[0];return[w,""][all(f==i[1]for i in l.items())]

Prende il suo input in questo modo:

g("Bird is the word")

Dovrebbe soddisfare tutti i requisiti, anche se non riesce su stringhe vuote, è necessario verificarli? Scusa per il ritardo.

Consigli / feedback / suggerimenti per la magia nera per salvare byte sono sempre ben accetti


Ciao e benvenuto in PPCG! Valutiamo le sfide del code-golf in base al numero di byte nella risposta. Sono andato avanti e l'ho modificato per te con le informazioni corrette.
Rɪᴋᴇʀ

2
Benvenuti in PPCG! Sfortunatamente, il tuo invio non soddisfa tutti i requisiti di questa sfida in quanto, prima di tutto, NON è sensibile al maiuscolo / minuscolo. Ad esempio, NON conterà le occorrenze della parola Thatcome occorrenze della parola thatpoiché la prima inizia con una maiuscola Te la seconda inizia con una minuscola t. Inoltre, questo NON rimuove tutte le altre forme di punteggiatura eccetto trattini ( -) e, facoltativamente, apostrofi ( ') e, di conseguenza, NON funzionerebbe per il quarto caso di test fornito nella domanda.
R. Kap,

1
Inoltre, questo NON genera nulla se non ci sono parole più frequenti. Ad esempio, usando il terzo caso di test ( This sentence has no most frequent word.) come esempio, la tua funzione viene emessa [('This', 1)], quando invece dovrebbe non produrre nulla. Potrei andare avanti all'infinito su più problemi, quindi consiglierei di risolverli il prima possibile.
R. Kap,

Lo farò presto, quando avrò tempo
Non ti piacerebbe sapere

Questo non è corretto La classe di caratteri \winclude caratteri di sottolineatura.
mbomb007,

0

Tcl 8.6, 196 byte

lmap s [join [read stdin] \ ] {dict incr d [regsub -all {[^\w-]} [string tol $s] {}]}
set y [dict fi $d v [lindex [lsort [dict v $d]] end]]
if {[llength $y]!=2} {set y {}}
puts "==> [lindex $y 0]"

(Ahimè, non riesco a capire come ottenerlo più piccolo di così ...)

Spiegazione

Usa diversi idiomi oscuri di Tcl per fare cose.

  • [join [read stdin] " "] - stringa di input → elenco di parole separate da spazi bianchi
  • lmap ... - iterare su ogni elemento di tale elenco. (Più breve di foreached effettivamente identico poiché il risultato viene scartato.)
  • [regsub ... [string tolower ...]] - Converti la stringa in minuscolo e rimuovi tutti i caratteri tranne i caratteri di parole e il trattino.
  • [dict incr d ...] - Crea / modifica un dizionario / parola → conta istogramma.
  • set y ... - Ordinare i valori del dizionario, prendere il più grande e restituire tutte le coppie (chiave, valore) corrispondenti ad esso.
  • if... - Ci devono essere esattamente due elementi: una singola coppia (chiave, valore), altrimenti non c'è nulla da stampare.
  • puts... - Stampa la chiave nella coppia valore chiave, se presente. (Nessuna parola ha spazi.)

Puoi giocarci usando CodeChef .



0

Rexx, 109 128 122 byte

pull s;g.=0;m=0;do i=1 to words(s);w=word(s,i);g.w=g.w+1;if g.w>=m then do;m=g.w;g.m=g.m+1;r=w;end;end;if g.m=1 then say r

Abbastanza stampato ...

pull s
g.=0
m=0
do i=1 to words(s)
  w=word(s,i)
  g.w=g.w+1
  if g.w>=m
  then do
    m=g.w
    g.m=g.m+1
    r=w
  end
end
if g.m=1 then say r

Non penso che questo gestisca tutti i casi di parole più frequenti legate - vedi (nuovo) ultimo test case - Ho fatto un errore simile.
philcolbourn,

Spero che sia stato risolto ora
aja,

0

bash, 153 146 131 154 149 137 byte

declare -iA F
f(){ (((T=++F[$1])==M))&&I=;((T>M))&&M=$T&&I=$1;}
read L
L=${L,,}
L=${L//[^- a-z0-9]}
printf -vA "f %s;" $L
eval $A;echo $I

Funzionamento:

dichiarare una matrice associativa F di numeri interi (dichiarare -iA F)

f è una funzione che, dato un parametro di parola $ 1, incrementa il conteggio delle frequenze per questa parola (T = ++ F [$ 1]) e confronta con il conteggio massimo finora (M).

Se uguale, abbiamo un pareggio, quindi non considereremo questa parola più frequente (I =)

Se maggiore del conteggio massimo finora (M), imposta il conteggio massimo finora sul conteggio di frequenza di questa parola (M = $ T) e ricorda questa parola (I = $ 1)

Fine funzione f

Leggi una riga (leggi L) Rendi minuscolo (L = $ {L ,,}) Rimuovi qualsiasi carattere tranne az, 0-9, trattino (-) e spazio (L = $ {L // [^ - a-z0- 9]}) Crea una sequenza di istruzioni bash che chiama f per ogni parola (printf -vA "f% s;" $ L). Questo viene salvato nella variabile A. eval A e stampa il risultato (eval $ a; echo $ I)

Produzione:

This quick brown fox jumps over this lazy dog.
-->this
This sentence with the words has at most two equal most frequent the words.
-->
The man walked down the road.
-->the
This sentence has no most frequent word.
-->
Slowly, he ate the pie, savoring each delicious bite. He felt like he was truly happy.
-->he
"That's... that's... that is just terrible!" he said.
-->thats
The old-fashioned man ate an old-fashioned cake.
-->old-fashioned
IPv6 looks great, much better than IPv4, except for the fact that IPv6 has longer addresses.
-->ipv6

Bug: RISOLTO Ho un bug che non viene rivelato in questi casi di test. Se l'input è

This sentence with words has at most two equal most frequent words.

quindi il mio codice non dovrebbe generare nulla.

I have a fix but I seem to have hit a bash bug... I get very odd behaviour is M is not declared an integer: ++F[$1]==M (after a few repeated words) increments both F[$1] and M!! - my mistake.


0

Python 3, 76 98 100 bytes

import re,statistics as S
try:print(S.mode(re.split("([a-z0-9-]+)",input().lower())[1::2]))
except:1

Try it online

Outputs the most common word as lowercase. Does not include apostrophes because "apostrophes are not required to be included."

statistics.mode requires Python 3.4

Unfortunately, no output to stderr is allowed, or it'd be much shorter.


You're not allowed to print to STDERR, unless this program doesn't produce any error output?
Okx

Your new program doesn't support hyphens! I tried the input i- test i-
Okx

Fixed it all. Still short.
mbomb007

0

R, 96 bytes

19 bytes shorter than the existing R answer, with a somewhat different approach.

t=table(gsub("[^a-z0-9'-]","",tolower(scan(,''))))
`if`(sum(t==max(t))-1,'',names(which.max(t)))

Reads from stdin, so the input is automatically separated by spaces. We convert to lowercase and use gsub to remove all non-alphanumerics (plus - and '). We count the instances of each word with table and save the result to t. Next, we check if there is more than 1 maximum in t (by seeing if there is more than one element which is equal to max(t). If so, we return the empty string ''. If not, we return the word corresponding to the maximum in t.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.