En sık kullanılan kelime nedir?


26

En sık kullanılan kelime nedir?

Bir cümle verildiğinde, programınız yol boyunca ilerlemeli, her kelimenin frekanslarını sayarak daha sonra en çok kullanılan kelimeyi vermelidir. Bir cümlenin sabit bir uzunluğu olmadığı için çok uzun sürebilir, kodunuz mümkün olduğunca kısa olmalıdır.

Kurallar / Gereksinimler

  • Her gönderim tam bir program veya işlev olmalıdır. Eğer bu bir fonksiyon ise, fonksiyon çağrısını sadece programın altına eklemek zorunda kalarak çalıştırılabilir olmalıdır. Başka herhangi bir şey (örn. C'deki başlıklar) dahil edilmelidir.
  • Diliniz için ücretsiz bir tercüman / derleyici bulunmalıdır.
  • Mümkünse, programınızın test edilebileceği bir siteye bağlantı sağlayın.
  • Programınız hiçbir şey yazmamalı STDERR.
  • Programınız giriş yapmalıdır STDIN(veya kendi dilinizde en yakın alternatif).
  • Standart boşluklar yasaktır.
  • Programınız harf duyarsız olmalıdır ( tHe, Theve thetüm deyince katkıda the).
  • En sık kullanılan kelime yoksa (bkz. Test durumu # 3), programınız hiçbir şey vermemelidir.

'Kelimenin' tanımı:

Giriş metnini boşluklara bölerek kelimelerin listesini alırsınız. Girdi hiçbir zaman düz boşluklardan başka bir beyaz boşluk içermez (özellikle yeni satır yok). Ancak, son sözler sadece alfanümerik (az, AZ, 0-9), tire (-) ve kesme işareti (') içermelidir. Bunu, diğer tüm karakterleri kaldırarak veya sözcük ayırma işlemini yapmadan önce boşlukla değiştirerek yapabilirsiniz. Kuralların önceki sürümleriyle uyumlu kalmak için kesme işaretlerinin dahil edilmesi gerekmez.

Test Kılıfları

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

Not: Üçüncü ve yedinci test durumlarının çıktısı yoktur, dördüncü seçenekten birini seçebilirsiniz.

puanlama

Programlar baytlara göre puanlanır. Normal karakter seti UTF-8'dir, başka bir tane kullanıyorsanız lütfen belirtin.

Meydan bittiğinde, en az bayt olan program ( adlandırılır ) kazanacak.

gönderimler

Cevabınızın göründüğünden emin olmak için, lütfen aşağıdaki Markdown şablonunu kullanarak cevabınızı bir başlık ile başlatın:

# Language Name, N bytes

Gönderinizin Nbüyüklüğü nerede ? Puanınızı artırmak varsa, olabilir onları içinden vurarak, başlığa eski hesapları tutmak. Örneğin:

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

Başlığınıza birden fazla sayı eklemek istiyorsanız (örneğin, puanınız iki dosyanın toplamı olduğundan veya tercüman bayrağı cezalarını ayrı ayrı listelemek istediğiniz için), gerçek puanın başlıktaki son sayı olduğundan emin olun :

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

Dil adını, daha sonra büyük afiş snippet'inde görünecek bir bağlantı da yapabilirsiniz:

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

Liderler Sıralaması

Burada hem düzenli bir lider tablosu hem de kazananların dile göre genel bir bakışı oluşturmak için bir Stack Snippet'i var.


2
Yorumlar uzun tartışmalar için değildir; bu konuşma sohbete taşındı .
Doorknob

1
Yeni 'kelime' tanımınıza bakıldığında, buradaki en yaygın kelime don't d'ont dont a anedir? Olurdu dont?
DJMcMayhem

@DrGreenEggsandHamDJ Kesme işaretini kaldıran bir gönderiminiz varsa dont,. Eğer değilse a,. ancak çoğu başvuru yapar ve bu nedenle dontdoğru cevaptır.
George Gibson

1
Çıktı büyük / küçük harf duyarlı mı? Peki ipv6son test durumu için geçerli çıktı?
kirbyfan64sos

1
Ekstra bir test durumu faydalı olabilir: "Kelimelerin bulunduğu bu cümle en fazla iki eşit kelimeye sahiptir" -> <nothing>
philcolbourn

Yanıtlar:


6

Pyke, 26 25 bayt

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

Burada dene!

Veya 23 22 bayt (rekabet etmeyen, yanlışsa yığını öldüren yere düğüm ekle)

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

Burada dene!

Veya noktalama işaretleriyle 23 bayt (Sanırım bu rekabet ediyor mu? Taahhüt düzenlemeden önceydi)

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

Burada dene!

Veya 12 bayt (kesinlikle rekabet etmeyen)

l1.cj.#jR/)e

Burada dene!

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

23 baytlık cevabınız, korunan tek noktalama işareti -ve '(tire ve kesme işareti) olsaydı rekabet ederdi .
George Gibson

Yalnızca bir kelimenin sonunda olmayan noktalama işaretlerini korur
Mavi,

Oh, tamam (Pyke'i anlamıyorum). Sanırım o zaman yarışıyor ...
George Gibson

1
@GeorgeGibson 23 byte sürümünün rekabet etmediğinden eminim - standart boşluklar altında olabilir. Ayrıca (m) herhangi bir kimsenin Pyke'yi anlamalarını beklemiyorum, kendi dilim olarak yapıyorum
Blue

Tamam o zaman. Bence yine de hala kazanıyorsun, bu yüzden önemli değil.
George Gibson


11

Pyth - 23 30 bayt

Rakam ve tire eklemek için daha iyi bir yol olmalı, ancak şu anda bunu düzeltmek istiyorum.

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

Test Takımı .


1
Gözden geçirilmiş kurallar, basamakların ve kısa çizgilerin korunmasını gerektirir.
Dennis,

@ GeorgeGibson düzeltildi.
Maltysen

6

Octave, 115 94 bayt

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

Kullanarak en sık kullanılan kelime olmayan durum için hesaplar try. Bu durumda hiçbir şey çıkarmaz ve istisnayı bulana kadar "ara verir".

Luis Mendo'nun önerisi sayesinde tasarruf edilen 21 (!) Bayt ( modeen yaygın kelimeyi elde etmek için üçüncü çıktıyı kullanarak ).


Orijinal cevabımı gönderdiğimden beri kurallar biraz değişti. Daha sonra regex'e bakacağım.


1
Beni yenersin, şimdi başka bir şey düşünürsün.
Abr001,

Uygula modeüzerinde cbelki de? Üçüncü çıktısı, eğer doğru hatırlıyorsam tüm bağlı değerleri verir
Luis Mendo

115 bayt sayıyorum.
Conor O'Brien,

İntikamınızın olması gerektiğine inanıyorum ['\w\d]. Bunlar ASCII’de büyük ve küçük harflerin arasında olmadıkça, bu durumda beni görmezden gelin çünkü kullanışlı bir masam yok.
Fon Monica'nın Davası

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

5

Perl 6, 80 bayt

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

Cevabı iki bölüme ayıralım ...

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

givenbir kontrol ifadesidir ( ifveya gibi for). Perl 6'da, ek olarak izin verilir. ( a if 1veya buradaki gibi foo given 3). givenkonusunu (sağ taraf) sol tarafındaki özel değişkene koyar $_.

"Konu" nun kendisi alt harfleri (lc , başlıklar ( words) kelimesi ( ) ile bölünür , değerleri bir Torbaya yerleştirir (oluşum sayısı ile ayarlanır), ardından değere göre sıralar (DESC). Yana sortsadece listelerde kullanmayı bilen, Bagbir dönüşür Listait PairBurada s.

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

basit bir koşullu ( ?? !!yerine Perl 6'da kullanılır ? :).

$_ > 1

Sadece listenin birden fazla eleman içerdiğini kontrol edin.

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

Erişimler $_kısaltılabilir ... Değişken belirtilmeden. .aaynen öyle $_.a. Yani bu etkili bir şekilde "her iki üst öğenin de aynı sayıda oluşumunu yapması" - - Öyleyse, '' (boş dize) 'yi basarız.

Aksi takdirde, üst öğenin anahtarını (sayı) yazdırırız: .[0].key .


7
Yarım İngiliz, yarım hat gürültüsü gibi. Şaşırtıcı.
kedi

1
komik görünüyor OO tarzı özellikleri ingilizce-y: P
Ven

2
Ayrıca, Perl 5'ten daha fazla İngilizce içerirken, Perl 5'ten daha az okunabilir olmayı başarır . D:
cat

1
@ cat düzeltildi - şimdi tamamen okunamıyor olmalı
Ven

5
value??!!(bu üçlü bir operatör olduğunu biliyorum, sadece eğlenceli)
kedi


4

JavaScript (ES6), 155 bayt

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)

@ Blue'nun Python cevabı dayanarak.


Regex değiştirme sayıları düşüyor gibi görünüyor ve IPv6 test durumu kıracak, doğru mu?
TessellatingHeckler

Arasında @TessellatingHeckler tanımı kelime Aslında soruyu okumak yana değişen ama şimdi cevabımı güncelledik.
Neil

4

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

( +17 bayt, çünkü görünüşe göre diğerlerinden daha sık kelimeler olsa bile, fakat aynı sıklıkta olsalar bile, hiçbir şey hala iade edilmemelidir. )

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

Şimdi tüm şartları yerine getirmeli. Bu gönderim, en az 1 kelimenin girdi olduğunu varsayar.

Çevrimiçi Deneyin! (Ideone)

Ayrıca, eğer bir tane istersen, işte benim fonksiyonumun yaklaşık 43 bayt pahasına herhangi bir normal ifadeden yoksun başka bir versiyonudur, bu yine de rekabetçi değildir, bu yüzden bunun önemi yoktur. Az önce buraya getirdim:

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

Bu Yeni Sürümü Çevrimiçi Deneyin! (Ideone)


Meydan okuma yorumlarından, "diğerlerinden daha sık, ancak aynı sıklıkta iki kelime varsa", çıktı "hiçbir şey" dir.
RootTwo

@RootTwo Sabit! :)
R. Kap,

@TessellatingHeckler Bunlar farklı kelimeler. That'sbir daralma olduğunu that is, oysa thatsgerçekten bir kelime değildir.
R. Kap,

@TessellatingHeckler Bu yorumun bir kanıtını bana verebilir misin? Çünkü yazıdaki tüm yorumları gözden geçiriyorum ve böyle bir yorum görmüyorum.
R. Kap,

4

Ruby, 94 92 102 bayt

Hızlı gitmeliyim (FGITW answer) Kelimeyi tüm büyük harflerle veya nilen sık kullanılan kelime yoksa döndürür .

Şimdi yeni özelliklere güncellendi, sanırım. Ancak, byte sayısı aynı olduğu için biraz golf başardı!

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

@ cat evet, 'çünkü bu sefer FGITW'ydim
Value Ink


3

JavaScript (ES6), 99 bayt

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

Sqlserver 2008, 250 bayt

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

Çevrimiçi deneyin!

Sqlserver 2016, 174 bayt

Bu örnek gibi veriler işlenemiyor (eşittir 3 kelime olarak sayılıyor):

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

Değişken yaklaşımdan hoşlanmıyorum çünkü bu tür bir hile yapıyor :) Bir girdi -> hiçbir şey ya da hiçbir şey, set tabanlı bir yaklaşımla daha uzun olması gerekiyor, çünkü GROUP BY, LEFT JOIN, or PARTITION BYSPLIT fonksiyonunda yerleşik olan herhangi bir SQL Server eklemelisiniz . Ungolfed demo mümkün olduğunca kısa yapmaktan çekinmeyin.
lad2025

@ lad2025 çok teşekkürler, 2016'dan beri hiçbir özellik bilmiyordu. SPLIT_STRING kesinlikle çok geç kalmış bir özellik. Betiği split kullanarak aşağı indirmeye çalıştım, 174'e indirdim, ancak "= = =" gibi bir metni filtreleyemeyecek
174'e indirdim

3

PostgreSQL, 246 , 245 bayt

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  

Çıktı:

enter image description here

İlgilenen varsa giriş yapın:

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


Normalde kullanırdım MODE() WITHIN GROUP(...)ve çok daha kısa olacak, ancak ihlal edecek:

En sık kullanılan kelime yoksa (bkz. Test durumu # 3), programınız hiçbir şey vermemelidir.


DÜZENLE:

Taşıma ':

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

Çıktı:

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

sizin kadar düşük alamadım, sqlserver henüz ayrık bir yapıya sahip değil. Ancak seçilen kısım daha kısadır.
t-clausen.dk

@ GeorgeGibson Tabii, sabit + canlı demo ekledi.
lad2025

@ lad2025 Sohbette genel olarak anlaşarak, yaptığınız şey artık gerekli değil, geri dönmekte özgürsünüz.
George Gibson

@GeorgeGibson Yup, düzenleme çok açık olacak. Canlı demo şu an çalışıyor, cevap yazdığımda sqlfiddle cevap vermiyordu.
lad2025

2

R, 115 bayt

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

Bu, bir dizgeyi kabul eden ve tek bir sözcük diğerlerinden daha sık görülürse bir dize döndüren bir işlevdir NULL. Aramak için değişkene atayın.

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 bayt

Kurallar değişmeye devam ediyor ...

T`L`l
[^-\w ]

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

!`[-\w]+$

Çevrimiçi deneyin!

Test odası.



@ CᴏɴᴏʀO'Bʀɪᴇɴ Teşekkürler, düzeltildi.
Sızdıran Rahibe

1
Ve sen onu 11 byte kadar golfledin. etkileyici
Conor O'Brien

Ayrıca "Eski kafalı adam, eski kafalı bir pasta yedi."
t-clausen.dk

Bu da doğru görünmüyor ( aen sık kullanılan kelime olmayı
umuyor

2

Python, 132 bayt

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]

Yukarıdaki kod, girişin en az iki kelime içerdiğini varsayar.


Bu regex'i sevmeliyim, tho.
Mavi

Bu yanlış. Karakter sınıfı \walt çizgi içerir.
mbomb007

1

PHP, 223 bayt

$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

Assumes more than 2 words. Getting rid of punctuation destroyed me...

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.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.