Was ist das häufigste Wort?


26

Was ist das häufigste Wort?

Wenn ein Satz vorliegt, muss Ihr Programm ihn durchlaufen, die Häufigkeit jedes Wortes zählen und dann das am häufigsten verwendete Wort ausgeben. Da ein Satz keine feste Länge hat und daher sehr lang werden kann, muss Ihr Code so kurz wie möglich sein.

Regeln / Anforderungen

  • Jede Einreichung sollte entweder ein vollständiges Programm oder eine Funktion sein. Wenn es sich um eine Funktion handelt, muss sie ausgeführt werden können, indem nur der Funktionsaufruf am Ende des Programms hinzugefügt wird. Alles andere (z. B. Überschriften in C) muss enthalten sein.
  • Für Ihre Sprache muss ein kostenloser Dolmetscher / Compiler verfügbar sein.
  • Wenn es möglich ist, geben Sie einen Link zu einer Site an, auf der Ihr Programm getestet werden kann.
  • Ihr Programm darf nichts schreiben STDERR.
  • Ihr Programm sollte Eingaben von STDIN(oder der nächstgelegenen Alternative in Ihrer Sprache) übernehmen.
  • Standardlücken sind verboten.
  • Ihr Programm muss Groß- und Kleinschreibung sein ( tHe, Theund thealle tragen zur Zählung the).
  • Wenn es kein häufigstes Wort gibt (siehe Testfall 3), sollte Ihr Programm nichts ausgeben.

Definition eines Wortes:

Sie erhalten die Liste der Wörter, indem Sie den eingegebenen Text auf Leerzeichen aufteilen. Die Eingabe enthält niemals andere Arten von Leerzeichen als Leerzeichen (insbesondere keine Zeilenumbrüche). Die letzten Wörter sollten jedoch nur alphanumerische Zeichen (az, AZ, 0-9), Bindestriche (-) und Apostrophe (') enthalten. Sie können dies tun, indem Sie alle anderen Zeichen entfernen oder durch Leerzeichen ersetzen, bevor Sie das Wort aufteilen. Um mit früheren Versionen der Regeln kompatibel zu bleiben, müssen keine Apostrophe eingefügt werden.

Testfälle

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.
==>

Hinweis: Der dritte und der siebte Testfall haben keine Ausgabe. Sie können auch den vierten Testfall auswählen.

Wertung

Programme werden nach Bytes bewertet. Der übliche Zeichensatz ist UTF-8. Wenn Sie einen anderen Zeichensatz verwenden, geben Sie diesen bitte an.

Wenn die Herausforderung beendet ist, gewinnt das Programm mit den wenigsten Bytes (es heißt ).

Einreichungen

Um sicherzustellen, dass Ihre Antwort angezeigt wird, beginnen Sie Ihre Antwort mit einer Überschrift. Verwenden Sie dazu die folgende Markdown-Vorlage:

# Language Name, N bytes

Wo Nist die Größe Ihres Beitrags? Wenn Sie Ihren Score zu verbessern, Sie können alte Rechnungen in der Überschrift halten, indem man sich durch das Anschlagen. Zum Beispiel:

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

Wenn Sie mehrere Zahlen in Ihre Kopfzeile aufnehmen möchten (z. B. weil Ihre Punktzahl die Summe von zwei Dateien ist oder wenn Sie die Strafen für Interpreter-Flags separat auflisten möchten), stellen Sie sicher, dass die tatsächliche Punktzahl die letzte Zahl in der Kopfzeile ist:

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

Sie können den Namen der Sprache auch als Link festlegen, der dann im Leaderboard-Snippet angezeigt wird:

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

Bestenliste

Hier ist ein Stack-Snippet, um sowohl eine reguläre Rangliste als auch eine Übersicht der Gewinner nach Sprache zu generieren.


2
Kommentare sind nicht für eine längere Diskussion gedacht. Diese Unterhaltung wurde in den Chat verschoben .
Türklinke

1
Was ist hier angesichts Ihrer neuen Definition von "Wort" das gebräuchlichste Wort? don't d'ont dont a a ? Wäre es dont?
DJMcMayhem

@DrGreenEggsandHamDJ Wenn Sie eine Vorlage haben , die entfernen Apostrophe tut, dont. Wenn nicht a,. Aber die meisten Einreichungen tun dies, und dies dontist eine korrekte Antwort.
George Gibson

1
Unterscheidet die Ausgabe zwischen Groß- und Kleinschreibung? Ist also ipv6die Ausgabe für den letzten Testfall gültig?
kirbyfan64sos

1
Ein zusätzlicher Testfall kann von Nutzen sein: "Dieser Satz mit Wörtern enthält höchstens zwei gleich häufigste Wörter." -> <nichts>
Philcolbourn

Antworten:


6

Pyke, 26 25 Bytes

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

Probieren Sie es hier aus!

Oder 23 22 Bytes (noncompeting, fügt Knoten , auf den Stapel abtötet , wenn falsch)

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

Probieren Sie es hier aus!

Oder mit Interpunktion, 23 Bytes (ich denke das konkurriert? Commit war vor der Bearbeitung)

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

Probieren Sie es hier aus!

Oder 12 Bytes (definitiv nicht konkurrierend)

l1.cj.#jR/)e

Probieren Sie es hier aus!

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

Ihre 23-Byte-Antwort würde konkurrieren, wenn nur die Interpunktion -und '(Bindestrich und Apostroph) erhalten bliebe .
George Gibson

Es wird nur die Zeichensetzung beibehalten, die nicht am Ende eines Wortes steht
Blau,

Oh, OK (ich verstehe Pyke nicht). Ich denke, es konkurriert dann ...
George Gibson

1
@GeorgeGibson Ich bin mir ziemlich sicher, dass die 23-Byte-Version nicht mithalten kann - sie könnte unter Standardlücken fallen. Ich erwarte auch nicht, dass (m) irgendjemand Pyke versteht, ich mache es als meine eigene Sprache
Blue

Alles klar dann. Ich denke, du gewinnst trotzdem, also ist es nicht wirklich wichtig.
George Gibson


11

Pyth - 23 30 Bytes

Es muss einen besseren Weg geben, um Ziffern und Bindestriche einzuschließen, aber ich möchte dies jetzt nur korrigieren.

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

Test Suite .


1
Die überarbeiteten Regeln erfordern die Beibehaltung von Ziffern und Bindestrichen.
Dennis

@ GeorgeGibson behoben.
Maltysen

6

Oktave, 115 bis 94 Bytes

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

Konten für den Fall ohne das häufigste Wort mit try . In diesem Fall gibt es nichts aus und "macht eine Pause", bis Sie die Ausnahme abfangen.

21 (!) Bytes dank Luis Mendos Vorschlag eingespart (mit der dritten Ausgabe von wird modedas häufigste Wort gefunden).


Die Regeln haben sich ziemlich verändert, seit ich meine ursprüngliche Antwort gepostet habe. Ich werde später in die Regex schauen.


1
du hast mich geschlagen, jetzt wirst du über etwas anderes nachdenken.
8.

Bewerben modeauf cvielleicht? Sein dritter Ausgang liefert, wenn ich mich
Luis Mendo,

Ich zähle 115 Bytes.
Conor O'Brien

Ich glaube, Ihre Regex sollte sein, ['\w\d]weil Sie Apostrophe und Ziffern bewahren müssen. Wenn diese in ASCII nicht zwischen Groß- und Kleinschreibung liegen, ignorieren Sie mich in diesem Fall, da ich keine Tabelle zur Hand habe.
Fund Monica's Lawsuit

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

5

Perl 6, 80 Bytes

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

Teilen wir die Antwort in zwei Teile auf ...

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

givenist eine Steueranweisung (wie ifoder for). In Perl 6 sind sie als Postfixes zulässig. ( a if 1oder wie hier foo given 3). givenlegt sein Thema (rechte Seite) in die Sondervariable $_für die linke Seite.

Das "Thema" selbst, lowercases ( lc), teilt sich nach dem Wort ( words), legt die Werte in einen Beutel (mit der Anzahl der Vorkommen) und sortiert sie dann nach dem Wert (DESC). Da sortnur weiß, wie man mit Listen umgeht, Bagwird die hier in eine Listvon Pairs umgewandelt.

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

eine einfache Bedingung ( ?? !!werden in Perl 6 anstelle von verwendet ? :).

$_ > 1

Überprüft nur, ob die Liste mehr als ein Element enthält.

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

Zugriffe auf $_können verkürzt werden ... indem die Variable nicht angegeben wird. .aist genau wie$_.a . Das ist also effektiv "Haben beide Top-Elemente die gleiche Anzahl von Vorkommen" - Wenn ja, dann drucken wir '' (die leere Zeichenkette).

Andernfalls drucken wir den Schlüssel des oberen Elements (die Zählung): .[0].key.


7
Es ist wie halb Englisch, halb Linienrauschen. Tolle.
Katze

1
Es ist lustig, wie es die OO-Stil-Features ist, die englisch-y aussehen: P
Ven

2
Schafft es auch, weniger lesbar zu sein als Perl 5, während mehr Englisch als Perl 5 enthalten ist. D:
cat

1
@cat regelte es - sollte nun völlig unleserlich sein
Ven

5
value??!!(Ich weiß, das ist ein ternärer Operator, es ist nur unterhaltsam)
Katze


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)

Basierend auf der Antwort von @ Blue's Python.


Ihr Regex-Ersatz sieht so aus, als würde er Zahlen verlieren und den IPv6-Test abbrechen, oder?
TessellatingHeckler

@TessellatingHeckler Die Definition des Wortes hat sich geändert, seit ich die Frage ursprünglich gelesen habe, aber ich habe meine Antwort jetzt aktualisiert.
Neil

4

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

( +17 Bytes, da anscheinend auch dann nichts zurückgegeben werden sollte, wenn Wörter häufiger vorkommen als die übrigen, aber dieselbe Häufigkeit aufweisen. )

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

Sollte jetzt alle Bedingungen erfüllen. Bei dieser Übermittlung wird davon ausgegangen, dass mindestens 1 Wort eingegeben wurde.

Probieren Sie es online! (Ideone)

Wenn Sie eine möchten, finden Sie hier eine andere Version meiner Funktion ohne reguläre Ausdrücke auf Kosten von ungefähr 43 Bytes. Diese ist jedoch sowieso nicht wettbewerbsfähig, sodass es keine Rolle spielt. Ich habe es hier nur zum Teufel hingelegt:

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

Probieren Sie diese neue Version online aus! (Ideone)


Aus den Challenge-Kommentaren "Wenn es zwei Wörter gibt, die häufiger als die anderen sind, aber mit der gleichen Häufigkeit", lautet die Ausgabe "nichts".
RootTwo

@RootTwo behoben! :)
R. Kap

@TessellatingHeckler Das sind aber andere Wörter. That'sist eine Kontraktion für that iswohingegen thatsnicht wirklich ein Wort ist.
R. Kap

@TessellatingHeckler Kannst du mir einen Beweis für diesen Kommentar geben? Weil ich alle Kommentare zum Beitrag durchgehe und keinen solchen Kommentar sehe.
R. Kap

4

Rubin, 94 92 102 Bytes

Ich muss schnell gehen (FGITW-Antwort). Gibt das Wort in Großbuchstaben zurück oder nilwenn es kein häufigstes Wort gibt.

Jetzt auf neue Spezifikationen aktualisiert, denke ich. Ich habe es jedoch geschafft, ein wenig weniger zu spielen, damit die Byteanzahl gleich ist!

->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?
Katze

@cat ja, denn ich war diesmal 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 Bytes

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

Probieren Sie es online!

SQL Server 2016, 174 Byte

Daten wie in diesem Beispiel können nicht verarbeitet werden (zählen als 3 Wörter):

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

Ich mag den variablen Ansatz nicht, weil er eine Art von Betrug ist :) Eine Eingabe -> nichts oder etwas, beim satzbasierten Ansatz muss sie länger sein, weil Sie zusätzliche GROUP BY, LEFT JOIN, or PARTITION BYFunktionen hinzufügen müssen. Trotzdem hat SQL Server die SPLIT-Funktion eingebaut. Ungolfed Demo zögern Sie nicht, es so kurz wie möglich zu machen.
lad2025

@ lad2025 vielen Dank, kannte keine Features aus dem Jahr 2016. SPLIT_STRING ist sicherlich ein längst überfälliges Feature. Ich habe versucht, das Skript mit split
abzuspielen

3

PostgreSQL, 246 , 245 Bytes

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  

Ausgabe:

enter image description here

Geben Sie bei Interesse Folgendes ein:

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


Normalerweise würde ich verwenden MODE() WITHIN GROUP(...)und es wird viel kürzer sein, aber es wird verstoßen:

Wenn es kein häufigstes Wort gibt (siehe Testfall 3), sollte Ihr Programm nichts ausgeben.


BEARBEITEN:

Handhabung ':

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

Ausgabe:

╔═══════════════════════════════════════════════════════════════════════════════════════════════╦═══════════════╗
║                                              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            ║
╚═══════════════════════════════════════════════════════════════════════════════════════════════╩═══════════════╝

konnte nicht so niedrig wie Sie werden, sqlserver hat noch keinen Split eingebaut. Der ausgewählte Teil ist jedoch kürzer.
t-clausen.dk

@ George Gibson Sicher, behoben + Live-Demo hinzugefügt.
lad2025

@ lad2025 Nach gemeinsamer Absprache im Chat ist das, was du getan hast, nicht mehr nötig, du kannst jederzeit zurückkehren.
George Gibson

@ GeorgeGibson Yup, bearbeiten wird viel klarer. Die Live-Demo funktioniert jetzt, als ich antwortete, antwortete sqlfiddle nicht.
lad2025

2

R, 115 Bytes

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

Dies ist eine Funktion, die eine Zeichenfolge akzeptiert und eine Zeichenfolge zurückgibt, wenn ein einzelnes Wort häufiger vorkommt als andere und NULL . Um es aufzurufen, weisen Sie es einer Variablen zu.

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 Bytes

Die Regeln ändern sich ständig ...

T`L`l
[^-\w ]

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

!`[-\w]+$

Probieren Sie es online!

Testsuite.



@ CᴏɴᴏʀO'Bʀɪᴇɴ Danke, behoben.
Undichte Nonne

1
Und Sie haben es 11 Bytes gespielt. beeindruckend
Conor O'Brien

Scheitert auch für "Der altmodische Mann aß einen altmodischen Kuchen."
t-clausen.dk

Dies sieht auch nicht richtig aus (es wird erwartet a, dass es dort das häufigste Wort ist)
TessellatingHeckler

2

Python, 132 Bytes

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]

Der obige Code setzt voraus, dass die Eingabe mindestens zwei Wörter enthält.


Ich muss diesen Regex lieben, tho.
Blau

Das ist falsch. Die Zeichenklasse \wenthält Unterstriche.
mbomb007

1

PHP, 223 Bytes

$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 Bytes

Nimmt mehr als 2 Wörter an. Die Zeichensetzung loszuwerden hat mich zerstört ...

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

Does this strip ',- etc?
Tim

@Tim No, I did this challenge before the rules were fully fleshed. Will change.
Blue

Can you assign the result of sorted to a tuple rather than having to index into the array manually?
Neil

@Neil you mean just get the first and second items for comparison instead of the entire array? I don't know how to do that
Blue

1

Matlab (225)

  • Rules chaneged :/

.

      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 is necessary to run this.

  • How does this work, one of the nicest privileges of regex replace in matlab this it field-executes tokens by calling external-environmental functions parameterized by the tokens caught in the inner environment, so any sequence of "Word_A Word_B .." is replaced by integers "A0 A1 A2 B0 B1 B2 ..." where the first integer is the numerica ascii signature of the word, the second is the starting index, the third is the ending index, these last two integers dont reduplicate in the whole sequence so i took this advantage to transpose it to an array, then mode it then search the result in that array, so the starting/ending indices will consequently follow.

  • Edit: after changing some details, the program is called function by a string parameter.


20 bytes saved thanks to @StewieGriffin, 30 bytes added reproaches to common-agreed loopholes.


You'll have my upvote when you (or someone else) show that this actually works, both for inputs that have a most common word, and for inputs that don't. =) (I can't test it, unfortunately)
Stewie Griffin

@StewieGriffin i think the programe misbehaves with sentences with equi-frequence words i will fix that
Abr001am

1

05AB1E, 22 21 20 bytes

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

Explanation:

ž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.

Note: If you're fine with trailing newlines in the output for when you're not supposed to output anything, remove the ? at the end to save a byte.

Note #2: The program will not work with a single word, but I doubt this would be a problem. If you want to fix this, replace # with ð¡ for an extra byte.

05AB1E uses CP-1252 as the charset, not UTF-8.

Try it online!


1

Perl, 60 56 55 54 bytes

Includes +3 for -p

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

If a word cannot be just a number you can also drop the a for a score of 53.


Does the hyphen in the -anE not count? It does on the other answer (+2 bytes for -p flag)...
George Gibson

@GeorgeGibson No, see meta.codegolf.stackexchange.com/questions/273/…. The hyphen, the space and the E do not count. The other answer would normally only have to do +1 bytes for -p, but his solution has ' so it cannot be seen as an extension of -e or -E. So he should in fact count +3 (not +2) since he should count the space and the hyphen (but every extra option would only be +1).
Ton Hospel

@TomHospel Oh, right.
George Gibson

Is this considered valid given the apostrophe rule? [\pL\d-] looks like it could be shrunken down to [\w-] (unless we care about underscores) but either version will report that instead of that's or thats for test 4. Otherwise, you need to add 4 bytes to insert \x27 in that character class (unless you have a better way of adding an apostrophe).
Adam Katz

@AdamKatz The definition of 'word' changed quite a bit while this was running and I never fully adopted the last version. But to keep you happy I created a fixed (and shorter) version :-). And yes, I do care about underscores
Ton Hospel

0

PowerShell (v4), 117 bytes

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

The first part is easy enough:

  • $input is ~= stdin
  • Regex replace irrelevant characters with nothing, keep newlines so we don't mash two words from the end of a line and the beginning of the next line into one by mistake. (Nobody else has discussed multiple lines, could golf -2 if the input is always a single line).
  • Regex split, Group by frequency (~= Python's collections.Counter), Sort to put most frequent words at the end.
  • PowerShell is case insensitive by default for everything.

Handling if there isn't a most frequent word:

  • Take the last two items [-2,-1] into $y and $z;
  • an N-item list, where N>=2, makes $y and $z the last two items
  • a 1-item list makes $y the last item and $z null
  • an Empty list makes them both null

Use the bool-as-array-index fake-ternary-operator golf (0,1)[truthyvalue], nested, to choose "", $z or $y as output, then take .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 bytes

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 (-p flag) = 86 bytes

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

Using:

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

Your -p flag should invoke a penalty of 3 bytes. The rules are roughly: Each commandline flag is +1 byte since that is how many extra bytes you need to extend your free -e'code' style commandline. So normally -p is only +1 byte. But here your code has ' so it cannot be run simply from the commandline without escaping. So no combining with -e and the - and the space before the p are extra and must be counted too
Ton Hospel

@TonHospel Fixed.
Denis Ibaev

This is actually 84 + 1 (-p flag) if you invoke it on the command line as perl -pe'…' (made available by removing the ' as noted in the first comments)
Adam Katz

0

Python, 158 bytes

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

Takes its input like this:

g("Bird is the word")

Should match all the requirements, although it does fail on empty strings, is it necessary to check for those? Sorry for the delay.

Advice / feedback / black magic tips for saving bytes are always welcome


Hi, and welcome to PPCG! We score code-golf challenges by the number of bytes in the answer. I went ahead and edited it for you with the correct information.
Rɪᴋᴇʀ

2
Welcome to PPCG! Unfortunately, your submission does not satisfy all the requirements of this challenge as, first of all, it's NOT case insensitive. For instance, it will NOT count occurrences of the word That as occurrences of the word that since the former begins with an uppercase T and the latter begins with a lowercase t. Also, this does NOT remove all other forms of punctuation except hyphens (-) and, optionally, apostrophes (') and as a result, this would NOT work for the fourth test case given in the question.
R. Kap

1
Also, this does NOT output nothing if there is no most frequent word. For instance, using the third test case (This sentence has no most frequent word.) as an example, your function outputs [('This', 1)], when it should instead be outputting nothing. I could go on and on about more issues, so I would recommend fixing them as soon as you can.
R. Kap

Will do soon, when I have time
Wouldn't You Like To Know

This is incorrect. The character class \w includes underscores.
mbomb007

0

Tcl 8.6, 196 bytes

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

(Alas, I can't figure out how to get it any smaller than that...)

Explanation

It uses several obscure Tcl idioms to do stuff.

  • [join [read stdin] " "] — input string→list of whitespace-separated words
  • lmap ... — iterate over every element of that list. (Shorter than foreach and effectually identical since the result is discarded.)
  • [regsub ... [string tolower ...]] — Convert the string to lowercase and strip all characters except for word characters and the hyphen.
  • [dict incr d ...] — Create/modify a dictionary/word→count histogram.
  • set y ... — Sort the dictionary values, take the largest one, and return all (key,value) pairs corresponding to it.
  • if... — There must be exactly two elements: a single (key,value) pair, else there is nothing to print.
  • puts... — Print the key in the key value pair, if any. (No word has spaces.)

You can play with it using CodeChef.



0

Rexx, 109 128 122 bytes

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

Pretty printed...

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

I don't think this handles all cases of tied most frequent words - see (new) last test case - I made similar mistake.
philcolbourn

Hopefully, that's fixed it now
aja

0

bash, 153 146 131 154 149 137 bytes

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

Operation:

declare an associative array F of integers (declare -iA F)

f is a function that, given a word parameter $1, increments frequency count for this word (T=++F[$1]) and compares to max count so far (M).

If equal, the we have a tie so we will not consider this word to be most frequent (I=)

If greater than max count so far (M), then set max count so far to frequency count of this word so far (M=$T) and remember this word (I=$1)

End function f

Read a line (read L) Make lowercase (L=${L,,}) Remove any character except a-z, 0-9, dash(-) and space (L=${L//[^- a-z0-9]}) Make a sequence of bash statements that calls f for each word (printf -vA "f %s;" $L). This is saved to variable A. eval A and print result (eval $a;echo$I)

Output:

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: FIXED I have a bug that is not revealed in these test cases. If input is

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

then my code should output nothing.

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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.