Qual é a palavra mais frequente?

26

Qual é a palavra mais frequente?

Dada uma frase, seu programa deve passar por ela, contando as frequências de cada palavra e, em seguida, produzir a palavra mais usada. Como uma sentença não possui um comprimento fixo e pode ser muito longa, seu código deve ser o mais curto possível.

Regras / Requisitos

  • Cada envio deve ser um programa ou função completo. Se for uma função, deve ser executável, bastando adicionar a chamada de função na parte inferior do programa. Qualquer outra coisa (por exemplo, cabeçalhos em C) deve ser incluída.
  • Deve haver um intérprete / compilador gratuito disponível para o seu idioma.
  • Se possível, forneça um link para um site onde seu programa possa ser testado.
  • Seu programa não deve escrever nada para STDERR.
  • Seu programa deve receber informações STDIN(ou a alternativa mais próxima em seu idioma).
  • As brechas padrão são proibidas.
  • Seu programa deve fazer distinção entre maiúsculas e minúsculas ( tHe, Thee thetodos contribuem para a contagem de the).
  • Se não houver uma palavra mais frequente (consulte o caso de teste nº 3), seu programa não produzirá nada.

Definição de uma 'palavra':

Você obtém a lista de palavras dividindo o texto de entrada em espaços. A entrada nunca conterá nenhum outro tipo de espaço em branco além dos espaços simples (em particular, não há novas linhas). No entanto, as palavras finais devem conter apenas alfanuméricos (az, AZ, 0-9), hífens (-) e apóstrofes ('). Você pode fazer isso removendo todos os outros caracteres ou substituindo-os pelo espaço antes de dividir a palavra. Para permanecer compatível com versões anteriores das regras, não é necessário incluir apóstrofos.

Casos de teste

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: O terceiro e o sétimo casos de teste não têm saída; você pode escolher um no quarto.

Pontuação

Os programas são pontuados de acordo com os bytes. O conjunto de caracteres usual é UTF-8; se você estiver usando outro, especifique.

Quando o desafio terminar, o programa com o mínimo de bytes (chamado ) vencerá.

Submissões

Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:

# Language Name, N bytes

onde Nestá o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:

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

Se você quiser incluir vários números no cabeçalho (por exemplo, porque sua pontuação é a soma de dois arquivos ou você deseja listar as penalidades do sinalizador de intérpretes separadamente), verifique se a pontuação real é o último número no cabeçalho:

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

Você também pode transformar o nome do idioma em um link que será exibido no snippet da tabela de classificação:

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

Entre os melhores

Aqui está um snippet de pilha para gerar uma classificação regular e uma visão geral dos vencedores por idioma.

George Gibson
fonte
2
Comentários não são para discussão prolongada; esta conversa foi movida para o bate-papo .
Maçaneta
1
Então, dada a sua nova definição de 'palavra', qual é a palavra mais comum aqui don't d'ont dont a a? Seria dont?
DJMcMayhem
@DrGreenEggsandHamDJ Se você tiver um envio que remova apóstrofos dont,. Se não a,. mas a maioria dos envios sim, e por isso donté uma resposta correta.
George Gibson
1
A saída diferencia maiúsculas de minúsculas? Então, a ipv6saída é válida para o último caso de teste?
Kirbyfan64sos
1
Um caso de teste extra pode ser útil: "Esta frase com palavras tem no máximo duas palavras iguais e mais frequentes". -> <nada> #
philcolbourn

Respostas:

6

Pyke, 26 25 bytes

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

Experimente aqui!

Ou 23 22 bytes (não-competidor, adicione um nó onde mata a pilha se falso)

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

Experimente aqui!

Ou com pontuação, 23 bytes (acho que isso concorre? Confirmar antes da edição)

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

Experimente aqui!

Ou 12 bytes (definitivamente não competitivo)

l1.cj.#jR/)e

Experimente aqui!

l1           -     input.lower()
  .c         -    punc_split(^)
    j        -   j = ^
     .#   )  -  sort(V(i) for i in ^)
       jR/   -   j.count(i)
           e - ^[-1]
Azul
fonte
Sua resposta de 23 bytes competiria se a única pontuação preservada fosse -e '(hífen e apóstrofo).
George Gibson
Ele só preserva pontuação que não está no final de uma palavra
Azul
Oh, ok (eu não entendo Pyke). Eu acho que compete então ...
George Gibson
1
@GeorgeGibson Tenho certeza de que a versão de 23 bytes não compete - ela pode estar sob brechas padrão. Também eu não espero que (m) quaisquer pessoas a compreender Pyke, eu estou fazendo isso como minha própria língua
Azul
Tudo bem então. Eu acho que você ainda ganha de qualquer maneira, então isso realmente não importa.
George Gibson
11

Pitão - 23 30 bytes

Tem que haver uma maneira melhor de incluir dígitos e hífens, mas eu só quero consertar isso agora.

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

Conjunto de Teste .

Maltysen
fonte
1
As regras revisadas exigem a preservação de dígitos e hífens.
Dennis
@GeorgeGibson corrigido.
Maltysen 16/05/19
6

Oitava, 115 94 bytes

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

Contas para o caso sem a palavra mais frequente usando try. Nesse caso, ele não gera nada e "faz uma pausa" até capturar a exceção.

Economizou 21 (!) Bytes graças à sugestão de Luis Mendo (usando a terceira saída de modepara obter a palavra mais comum).


As regras mudaram bastante desde que postei minha resposta original. Vou examinar o regex mais tarde.

Stewie Griffin
fonte
1
você me venceu, vai pensar em outra coisa agora.
Abr001am 08/05/19
Aplicar modeem ctalvez? Sua terceira saída fornece todos os valores vinculados, se bem me lembro
Luis Mendo
Eu conto 115 bytes.
Conor O'Brien
Eu acredito que seu regex deve ser ['\w\d]porque você precisa preservar apóstrofos e dígitos. A menos que essas estejam entre maiúsculas e minúsculas no ASCII, nesse caso, me ignore porque não tenho uma tabela à mão.
Fund 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 bytes

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

Vamos dividir a resposta em duas partes ...

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

givené uma declaração de controle (como ifou for). No Perl 6, eles são permitidos como correções posteriores. ( a if 1, ou como aqui foo given 3). givencoloca seu tópico (lado direito) na variável especial $_do lado esquerdo.

O próprio "tópico" em minúsculas ( lc), divide-se por palavra ( words), coloca os valores em um saco (definido com o número de ocorrências) e depois classifica por valor (DESC). Como sortsó sabe operar em listas, o Bagé transformado em um Listdos Pairaqui.

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

uma condicional simples ( ?? !!são usadas no Perl 6, em vez de ? :).

$_ > 1

Apenas verifica se a lista possui mais de um elemento.

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

Os acessos $_podem ser encurtados ... Não especificando a variável. .aé exatamente como $_.a. Portanto, isso é efetivamente "os dois principais elementos têm o mesmo número de ocorrências" - nesse caso, imprimimos '' (a sequência vazia).

Caso contrário, vamos imprimir a chave do elemento superior (a contagem): .[0].key.

Ven
fonte
7
É como meio inglês, meio ruído de linha. Surpreendente.
gato
1
é engraçado como são os recursos do estilo OO que parecem em inglês: P
Ven 8/16
2
Também consegue ser menos legível que o Perl 5 enquanto contém mais inglês que o Perl 5. D:
cat
1
@cat fixa-lo - deve ser totalmente ilegível agora
Ven
5
value??!!(eu sei que é um operador ternário, é só entreter)
gato
4

05AB1E , 30 bytes

Código:

lžj¨„ -«Ãð¡©Ùv®yQOˆ}®¯MQÏDg1Q×

Usa a codificação CP-1252 . Experimente online! .

Adnan
fonte
Hmm?
TessellatingHeckler
3
@TessellatingHeckler Leva apenas uma linha de entrada. A menos que você use repetidamente o Icomando, 05AB1E levará apenas o necessário.
George Gibson
4

JavaScript (ES6), 155 bytes

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)

Baseado na resposta Python do @ Blue.

Neil
fonte
Sua substituição de regex parece diminuir números e interromperá o caso de teste do IPv6, certo?
TessellatingHeckler
@TessellatingHeckler A definição da palavra mudou desde que li originalmente a pergunta, mas atualizei minha resposta agora.
Neil
4

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

( +17 bytes, porque, aparentemente, mesmo que haja palavras mais frequentes que as demais, mas elas tenham a mesma frequência, nada deve ser retornado. )

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

Agora deve satisfazer todas as condições. Este envio pressupõe que pelo menos 1 palavra seja inserida.

Experimente Online! (Ideona)

Além disso, se você quiser uma, aqui está outra versão da minha função sem expressões regulares ao custo de cerca de 43 bytes, embora essa seja de qualquer maneira não competitiva, portanto, isso realmente não importa. Acabei de colocá-lo aqui para o inferno:

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

Experimente esta nova versão online! (Ideona)

R. Kap
fonte
Dos comentários do desafio "se houver duas palavras que são mais frequentes que as demais, mas com a mesma frequência", a saída é 'nada'.
RootTwo
@RootTwo Fixed! :)
R. Kap
@TessellatingHeckler Essas são palavras diferentes. That'sé uma contração porque that isconsiderando thatsnão é realmente uma palavra.
R. Kap
@TessellatingHeckler Você pode me dar alguma prova desse comentário? Porque eu estou revisando todos os comentários da postagem e não vejo esse comentário.
R. Kap
4

Ruby, 94 92 102 bytes

Preciso ir rápido (resposta do FGITW). Retorna a palavra em letras maiúsculas ou nilse não houver uma palavra mais frequente.

Agora atualizado para novas especificações, eu acho. No entanto, eu consegui um pouco de golfe, então a contagem de bytes é a mesma!

->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}
Value Ink
fonte
5
Gotta go fast?
Cat
@cat yeah, porque eu estava no FGITW desta vez
Value Ink
3

Pitão, 32 bytes

p?tlJeM.MhZrS@Ls++\-GUTcrz0d8ksJ

Suíte de teste.

Freira Furada
fonte
3

JavaScript (ES6), 99 bytes

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>

George Reith
fonte
3

Sqlserver 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

Experimente online!

Sqlserver 2016, 174 bytes

Não foi possível manipular dados como este exemplo (contando os iguais como 3 palavras):

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
t-clausen.dk
fonte
Eu não gosto de abordagem variável, porque é meio trapaceira :) Uma entrada -> nada ou algo, com uma abordagem baseada em conjunto, ela deve ser mais longa, porque você precisa adicionar GROUP BY, LEFT JOIN, or PARTITION BYfunções adicionais do Anyway SQL Server incorporadas na SPLIT. Demonstração Ungolfed fique à vontade para torná-lo o mais curto possível.
lad2025
@ lad2025 muito obrigado, não conhecia nenhum recurso de 2016. SPLIT_STRING certamente é um recurso muito atrasado. Eu tentei jogar o script no split usando split,
baixei
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  

Saída:

insira a descrição da imagem aqui

Entrada se alguém estiver interessado:

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 eu usaria MODE() WITHIN GROUP(...)e será muito mais curto, mas violará:

Se não houver uma palavra mais frequente (consulte o caso de teste nº 3), seu programa não produzirá nada.


EDITAR:

Manuseio ':

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

Saída:

╔═══════════════════════════════════════════════════════════════════════════════════════════════╦═══════════════╗
║                                              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            ║
╚═══════════════════════════════════════════════════════════════════════════════════════════════╩═══════════════╝
lad2025
fonte
não pôde chegar tão baixo quanto você, o sqlserver ainda não foi construído em divisão. No entanto, a parte selecionada é mais curta.
t-clausen.dk
@GeorgeGibson Claro, corrigido + adicionado demonstração ao vivo.
lad2025
@ lad2025 De comum acordo no bate-papo, o que você fez não é mais necessário, fique à vontade para voltar.
George Gibson
@GeorgeGibson Sim, a edição será muito clara. A demonstração ao vivo está funcionando agora, quando escrevi a resposta sqlfiddle não estava respondendo.
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

Esta é uma função que aceita uma string e retorna uma string se uma única palavra aparecer com mais frequência do que outras NULL. Para chamá-lo, atribua-o a uma variável.

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
    }
}
Alex A.
fonte
2

Retina, 97 bytes

As regras continuam mudando ...

T`L`l
[^-\w ]

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

!`[-\w]+$

Experimente online!

Suíte de teste.

Freira Furada
fonte
2
Falha nesta entrada.
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ Obrigado, corrigido.
Freira vazando
1
E você jogou 11 bytes ._. impressionante
Conor O'Brien
Também falha em "O homem à moda comeu um bolo à moda antiga".
t-clausen.dk
Isso também não parece certo (esperando aser a palavra mais comum)
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]

O código acima pressupõe que a entrada tenha pelo menos duas palavras.

RootTwo
fonte
Tenho que amar esse regex, tho.
Azul
Isto está incorreto. A classe de caracteres \winclui sublinhados.
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]:'')):'');
MonkeyZeus
fonte
1

Python 2, 218 bytes

Pressupõe mais de 2 palavras. Livrar-se da pontuação me destruiu ...

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''
Azul
fonte
Isso tira ',-etc?
Tim
@ Tim Não, eu fiz esse desafio antes que as regras fossem totalmente elaboradas. Vai mudar.
Azul
Você pode atribuir o resultado de sorteduma tupla em vez de precisar indexar manualmente na matriz?
819 Neil
@ Neil você quer dizer apenas obter o primeiro e o segundo itens para comparação em vez de toda a matriz? Eu não sei como fazer isso #
Blue
1

Matlab (225)

  • Regras alteradas: /

.

      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
  • Caixa de ferramentas é necessária para executar isso.

  • Como isso funciona, um dos privilégios mais agradáveis ​​do regex substitui no matlab: ele executa tokens em campo, chamando funções ambientais externas parametrizadas pelos tokens capturados no ambiente interno; portanto, qualquer sequência de "Word_A Word_B .."é substituída por números inteiros "A0 A1 A2 B0 B1 B2 ..."onde o primeiro número inteiro é a assinatura Numerica ascii da palavra, o segundo é o índice inicial, o terceiro é o índice terminando, estes dois últimos números inteiros não reduplicate em toda a seqüência para que eu tirei essa vantagem para transpô-la para uma matriz, em seguida, o modo que, em seguida, procurar o resultem nessa matriz, portanto os índices inicial / final serão seguidos.

  • Editar: após alterar alguns detalhes, o programa é chamado de função por um parâmetro de string.


Com 20 bytes salvos graças ao @StewieGriffin, 30 bytes adicionaram críticas a brechas acordadas em comum.

Abr001am
fonte
Você receberá meu voto positivo quando você (ou outra pessoa) mostrar que isso realmente funciona, tanto para entradas com a palavra mais comum quanto para entradas que não. =) (Eu não posso testá-lo, infelizmente)
Stewie Griffin
@StewieGriffin Eu acho que o misbehaves programe com frases com palavras equi-frequence i vai corrigir isso
Abr001am
1

05AB1E , 22 21 20 bytes

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

Explicação:

ž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 você estiver bem com as novas linhas à direita na saída para quando não deve produzir nada, remova a ?no final para salvar um byte.

Nota 2: O programa não funcionará com uma única palavra, mas duvido que isso seja um problema. Se você quiser corrigir isso, substitua #com ð¡para um byte extra.

05AB1E usa CP-1252 como o conjunto de caracteres, não UTF-8.

Experimente online!

Okx
fonte
1

Perl, 60 56 55 54 bytes

Inclui +3 para -p

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

Se uma palavra não puder ser apenas um número, você também pode largar a a53 para obter uma pontuação.

Ton Hospel
fonte
O hífen no -anEnão conta? Ele faz na outra resposta (2 bytes para -pflag) ...
George Gibson
@GeorgeGibson Não, consulte meta.codegolf.stackexchange.com/questions/273/… . O hífen, o espaço e o Enão contam. A outra resposta normalmente precisaria apenas de +1 para -p, mas a solução dele tem, 'portanto, não pode ser vista como uma extensão de -eou -E. Portanto, ele deve contar de fato +3 (não +2), pois deve contar o espaço e o hífen (mas todas as opções extras seriam apenas +1).
Ton Hospel
@ TomHospel Oh, certo.
George Gibson
Isso é considerado válido, dada a regra do apóstrofo? [\pL\d-]parece que ele pode ter sido reduzido a [\w-](a menos que nos importemos com sublinhados), mas qualquer versão reportará em thatvez de that'sou thatspara o teste 4. Caso contrário, você precisará adicionar 4 bytes para inserir \x27nessa classe de caracteres (a menos que você tenha uma maneira melhor de adicionar um apóstrofo).
Adam Katz
@AdamKatz A definição de 'word' mudou bastante enquanto isso estava em execução e eu nunca adotei completamente a última versão. Mas, para mantê-lo feliz, criei uma versão fixa (e mais curta) :-). E sim, eu me importo com sublinhados
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

A primeira parte é fácil:

  • $input é ~ = stdin
  • O Regex substitui caracteres irrelevantes por nada, mantém novas linhas para que não misturemos duas palavras do final de uma linha e do início da próxima em uma por engano. (Ninguém mais discutiu várias linhas, poderia jogar com -2 se a entrada for sempre uma única linha).
  • Regex dividido, Grouppor frequência (~ = coleções do Python.Counter), Sortpara colocar as palavras mais frequentes no final.
  • O PowerShell não diferencia maiúsculas de minúsculas por padrão para tudo.

Manipulação se não houver uma palavra mais frequente:

  • Pegue os dois últimos itens [-2, -1] em $ ye $ z;
  • uma lista de itens N, em que N> = 2, torna $ ye $ z os dois últimos itens
  • uma lista de 1 item torna $ y o último item e $ z nulos
  • uma lista vazia os torna nulos

Use o golfe falso-ternário-operador do índice bool-como-array-index (0,1)[truthyvalue], aninhado, para escolher "", $ z ou $ y como saída e, em seguida, use .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
TessellatingHeckler
fonte
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)
Blab
fonte
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 ( -psinalizador) = 86 bytes

++$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
Denis Ibaev
fonte
Sua -pbandeira deve invocar uma penalidade de 3 bytes. As regras são aproximadamente: Cada sinalizador de linha de comando tem +1 byte, pois são quantos bytes extras você precisa para estender seu -e'code'estilo de linha de comando livre . Então normalmente -pé de apenas um byte. Mas aqui o seu código possui, 'para que não possa ser executado simplesmente a partir da linha de comando sem escapar. Portanto, nenhuma combinação com -ee o -espaço antes do psão extras e devem ser contados também
Ton Hospel
@TonHospel Fixed.
Denis Ibaev 10/05
Esta é realmente 84 + 1 ( -pflag) se você invocá-lo na linha de comando como perl -pe'…'(disponibilizado pela remoção da 'conforme observado nos primeiros comentários)
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())]

Recebe sua entrada assim:

g("Bird is the word")

Deve corresponder a todos os requisitos, embora falhe em cadeias vazias, é necessário verificar esses requisitos? Desculpe o atraso.

Dicas de conselhos / feedback / magia negra para salvar bytes são sempre bem-vindos

Você não gostaria de saber
fonte
Olá, e bem-vindo ao PPCG! Classificamos os desafios do código-golfe pelo número de bytes na resposta. Fui em frente e editei para você com as informações corretas.
Rɪᴋᴇʀ
2
Bem-vindo ao PPCG! Infelizmente, seu envio não atende a todos os requisitos desse desafio, pois, em primeiro lugar, NÃO é sensível a maiúsculas e minúsculas. Por exemplo, NÃO contará ocorrências da palavra Thatcomo ocorrências da palavra, thatpois a primeira começa com maiúscula Te a segunda com minúscula t. Além disso, isso NÃO remove todas as outras formas de pontuação, exceto hífens ( -) e, opcionalmente, apóstrofes ( ') e, como resultado, isso NÃO funcionaria no quarto caso de teste fornecido na pergunta.
R. Kap
1
Além disso, isso NÃO gera nada se não houver uma palavra mais frequente. Por exemplo, usando o terceiro caso de teste ( This sentence has no most frequent word.) como exemplo, sua função é exibida [('This', 1)], quando, em vez disso, não deveria estar produzindo nada. Eu poderia continuar falando sobre mais problemas, então recomendo corrigi-los o mais rápido possível.
R. Kap
Farei em breve, quando tiver tempo
Você não gostaria de saber
Isto está incorreto. A classe de caracteres \winclui sublinhados.
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]"

(Infelizmente, não consigo descobrir como obtê-lo menor do que isso ...)

Explicação

Ele usa vários idiomas obscuros do Tcl para fazer coisas.

  • [join [read stdin] " "] - string de entrada → lista de palavras separadas por espaços em branco
  • lmap ... - itere sobre todos os elementos dessa lista. (Mais curto foreache efetivamente idêntico, pois o resultado é descartado.)
  • [regsub ... [string tolower ...]] - Converta a string em minúscula e retire todos os caracteres, exceto os caracteres da palavra e o hífen.
  • [dict incr d ...] - Crie / modifique um dicionário / palavra → conte o histograma.
  • set y ... - Ordene os valores do dicionário, pegue o maior e retorne todos os pares (chave, valor) correspondentes a ele.
  • if... - Deve haver exatamente dois elementos: um único par (chave, valor), caso contrário não há nada para imprimir.
  • puts... - Imprima a chave no par de valores-chave, se houver. (Nenhuma palavra tem espaços.)

Você pode jogar usando o CodeChef .

Dúthomhas
fonte
182
sergiol
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

Muito impresso ...

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
aja
fonte
Não acho que isso lide com todos os casos de palavras mais frequentes vinculadas - veja (novo) último caso de teste - cometi um erro semelhante.
Philcolbourn
Felizmente, isso já foi corrigido agora
aja 16/05
0

bash, 153 146 131 154 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

Operação:

declare uma matriz associativa F de números inteiros (declare -iA F)

f é uma função que, dado um parâmetro de palavra $ 1, incrementa a contagem de frequências para esta palavra (T = ++ F [$ 1]) e se compara à contagem máxima até o momento (M).

Se for igual, temos um empate para não considerarmos essa palavra mais frequente (I =)

Se for maior que a contagem máxima até agora (M), defina a contagem máxima até agora para a contagem de frequência dessa palavra até agora (M = $ T) e lembre-se dessa palavra (I = $ 1)

Função final f

Leia uma linha (leia L) Torne minúsculas (L = $ {L ,,}) Remova qualquer caractere, exceto az, 0-9, traço (-) e espaço (L = $ {L // [^ - a-z0- 9]}) Faça uma sequência de instruções bash que chame f para cada palavra (printf -vA "f% s;" $ L). Isso é salvo na variável A. eval A e resultado da impressão (eval $ a; echo $ I)

Saída:

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: CORRIGIDO Eu tenho um bug que não é revelado nesses casos de teste. Se a entrada for

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

então meu código não deve produzir nada.

Eu tenho uma correção, mas parece ter atingido um erro do bash ... Recebo um comportamento muito estranho: M não é declarado um número inteiro: ++ F [$ 1] == M (depois de algumas palavras repetidas) aumenta os dois F [$ 1 ] e M !! - meu erro.

philcolbourn
fonte
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

Experimente online

Emite a palavra mais comum como minúscula. Não inclui apóstrofes porque "não é necessário que apóstrofos sejam incluídos".

statistics.mode requer Python 3.4

Infelizmente, nenhuma saída para stderré permitida ou seria muito menor.

mbomb007
fonte
Você não tem permissão para imprimir STDERR, a menos que este programa não produza nenhum erro de saída?
Okx
Seu novo programa não suporta hífens! Eu tentei a entradai- test i-
Okx
Corrigido tudo. Ainda curto.
mbomb007
0

R, 96 bytes

19 bytes mais curtos que a resposta R existente , com uma abordagem um pouco diferente.

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

Lê do stdin, para que a entrada seja automaticamente separada por espaços. Convertemos para minúsculas e usamos gsubpara remover todos os não alfanuméricos (mais -e '). Contamos as instâncias de cada palavra tablee salvamos o resultado em t. Em seguida, verificamos se há mais de 1 no máximo t(verificando se há mais de um elemento igual a max(t). Se houver, retornamos a string vazia ''. Caso contrário, retornamos a palavra correspondente ao máximo em t.

rturnbull
fonte