Conte as palavras em um texto e exiba-as
O código deve receber um texto de entrada (não obrigatório, pode ser qualquer arquivo, stdin, string para JavaScript, etc):
A saída deve conter as palavras com seu número de ocorrência, classificadas pelo número de ocorrências em ordem decrescente:
Observe que 31 é uma palavra; portanto, uma palavra é qualquer coisa alfanumérica; o número não está atuando como separador; portanto, por exemplo, é 0xAFqualificado como uma palavra. Separadores serão qualquer coisa que não seja alfanumérica, incluindo .(ponto) e -(hífen), portanto, i.e.ou pick-me-upresultariam em 2, respectivamente, 3 palavras. Deve ser sensível a maiúsculas e minúsculas Thise thisincluir duas palavras diferentes, 'também seria um separador wouldne tserão 2 palavras diferentes dewouldn't .
Escreva o código mais curto no seu idioma de escolha.
Resposta correta mais curta até agora:
grep e coreutils - 42 bytes
O caso importa (isto é, é Thiso mesmo que thise tHIs)?
Se algo não alfanumérico conta como separador, são wouldn't2 palavras ( wouldne t)?
@Gareth Deve fazer distinção entre maiúsculas e minúsculas Thise thisseria de fato duas palavras diferentes, iguais wouldne t.
Se não seriam duas palavras, não deveria ser "seria" e "nt", já que é a abreviação de não seria, ou isso é muito mais nazista?
@TeunPronk Eu tento simplificar, colocar algumas regras incentivará as exceções a estarem em ordem com a gramática, e há muitas exceções por aí. Ex em inglês i.e.é uma palavra, mas se deixarmos todos os pontos no ponto final de frases serão tomadas, mesmo com aspas ou plicas, etc.
grep e coreutils 44 42
Use a opção que não diferencia maiúsculas de minúsculas e regex mais curto. Obrigado Tomas.
Sendo essa quase exatamente a resposta de McEllroy ao livro de Knuth, Literate Programming . A única diferença é que isso não inclui um tubo headno final.
Este foi praticamente o meu primeiro pensamento também.
'\ W +' também não funcionaria?
41 caracteres :grep -io \[A-Z0-9]*|sort|uniq -c|sort -nr
Tomas @: Adicionado isso à resposta, obrigado. Eu saí em proteção para o asterisco, porque ele estava expandindo nomes de arquivos em algumas conchas.
O que é muito bom, pois o java é uma linguagem muito não-golfe.
Execute a partir da linha de comando:
Regex incorreto para divisão. Deveria ser"[^\\W_]"
— n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̷̨̰́̀ĥ̷̷̳̰̀ĥ̷̳
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳, o String.split(String regex)método usa um padrão que corresponde ao delimitador para dividir. Então, por exemplo, "aababba".split("b")renderia a matriz {"aa", "a", "", "a"}. Minha [^\\w\\d]expressão regular significa "um caractere nem nas classes de caracteres de palavra nem de dígito". [^\\W_]é "um caractere que não é um sublinhado nem está na classe de caracteres que não são palavras" e corresponderia a qualquer caractere de palavra, exceto o sublinhado.
Desculpe, meu comentário anterior estava incorreto. \winclui \d, portanto, \dé redundante. \winclui sublinhado, que deve ser considerado um separador de acordo com a pergunta. Portanto, o regex correto para divisão deve ser "[\\W_]+".
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ ok, obrigado; Eu consertei o problema.
⎕D,⎕A,⎕UCS 96+⍳26: números, letras maiúsculas, letras minúsculas
(I←⍞)∊: ler entrada, armazenar I, ver quais são alfanuméricos
Z←I⊂⍨: dividir Iem grupos de caracteres alfanuméricos, armazenar emZ
+⌿∘.≡⍨Z: para cada elemento Z, veja com que frequência ele ocorre
Z,⍪: corresponde a cada elemento em Z pares com quantas vezes ocorre
G←⊃∪↓: selecione apenas os pares únicos, armazene em G
⍒,1↓⍉G: obtenha índices classificados para as ocorrências
G[... ;]: reordene as linhas de acordo Gcom os índices fornecidos
o que ... o ... f .....
— Ozh 30/01
É por isso que tenho pesadelos.
@Thebluefish: O APL foi projetado a partir de uma notação, com a intenção de que, assim como a matemática, uma notação concisa libera você para pensar com clareza. Novamente, como a matemática, quando você vê essa notação pela primeira vez, você tende a pensar que não é clara, mas as línguas sempre parecem complexas para começar. Seria mais fácil se não fosse tudo na mesma linha, embora ...
o que quer que você invente no APL, vejo apenas lixo unicode, setas apontando nas direções e um pinheiro de cabeça para baixo. que é pior que J
Pode ser mais curto com ⎕s( help.dyalog.com/latest/Content/Language/System%20Functions/… ) e o novo operador principal ( help.dyalog.com/latest/Content/Language/Primitive%20Operators/… ):g⌷⍨⊂⍒2⌷⍉g←{⍺,≢⍵}⌸('\w+'⎕s'\0')⍞
C #: 153c 144c 142c 111c 115c 118c 114c 113c
(via LINQPad no modo "C # Statements", sem incluir a string de entrada)
Versão 1: 142c
Versão 2: 114c
( [\w]inclui _, o que está incorreto ! ; [A-z]inclui [ \ ] ^ _ `; resolver [^_\W]+)
Resultados: (como versão 1)
— jimbobmcgee
A propósito, para a versão 2, sua versão não-golfada não corresponde à sua versão para golfe. E como você está usando uma string literal, você pode escrever@"[^_\W]"
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ - corrigiu o erro de digitação e removeu o extra `` para uma economia de 1 caractere - obrigado !!
R, 58 caracteres
Isso é mais curto (49 caracteres) sort(table(gsub("[[:punct:]]","",scan(,""))),d=T). Infelizmente, ambas as soluções não funcionam corretamente wouldn't.
perl6: 49 caracteres
Penteie a entrada para correspondência de itens \w+, coloque a lista resultante de palavras em umBag , peça seus pares e classifique-os por valor negativo. (A estrela *é o que quer que seja , não é multiplicação aqui)
— Ayiko
Perl 6 me assusta.
Toda vez que penso em um recurso interessante de linguagem, procuro por ele e está no Perl6 em algum lugar. É por isso que está demorando muito ...
Você pode aparar 6 caracteres usando .wordsem vez de .comb(/\w+/):)
— Mouq
@ Muq: infelizmente .wordsnão retira o :ou .da entrada conforme necessário :(
— Ayiko 15/02/14
-1. _não deve ser incluído em uma palavra na declaração do problema.
Agora funciona com nova linha:
Isso não funciona quando há novas linhas ou mais de um espaço consecutivo no texto.
@ klingt.net corrigido.
— Daniero 30/01
A entrada é aceita como argumento de linha de comando, por exemplo:
Saída para a sequência de amostras:
diz entrada é o que você deseja. para que você possa obtê-lo como parâmetro de linha de comando usando$argv[1]
— Einacio 29/01
@Einacio boa chamada.
-1. Sublinhado _não deve ser incluído em uma palavra.
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ corrigido.
— Primo 29/03
$ s é uma variável que contém a sequência de entrada.
— microbiano
[\W]não é bom o suficiente - está correspondendo a um espaço no meu teste. E não é ordenada por descendente contagem ...
$s -split"[\W]"|group -ca|where{$_.Name -ne ""}|sort{-$_.Count}você fica mais perto (com custos, é claro)
Opa, perdi a parte da triagem. Corrigirei minha resposta em breve.
— microbian
alternativamente:$s -split"\W+"|group -ca |sort count -des
— Nacimota
-split"\W+"está combinando uma sequência vazia entre o último .e o final da sequência; também \W+corresponde a _tecnicamente não permitido
— jimbobmcgee 30/01
Recomendações adicionadas de @primo e @protist
E quanto à classificação?
— Daniero 29/01
@daniero, excelente ponto! Isso agora classifica!
Eu acho que é o mais conciso possível. Se você não se importa com um aviso de descontinuação, não é necessário espaço entre gee for. Além disso, o <=>operador pode ser substituído por -.
@primo Ahhh, em -vez de <=>ser um gênio, não tenho certeza se isso está nas dicas de golfe do segmento Perl. Vou atualizar isso mais tarde, obrigado!
Hey @protist, também \winclui números ( perl -e 'print for"a 1 2 3 4 b"=~/\w/g'impressões a1234b), mas seu mecanismo de iteração das palavras salva outro caractere, então eu atualizarei. Obrigado!
(não incluindo a sequência de entrada)
(com adereços para @microbian para o grupo -ca)
Versão 1 (108 caracteres)
Versão 2 (102 caracteres)
Versão 3 (105 caracteres)
Versão 4 (94 caracteres)
Versão 5 (sem alerta; 87 caracteres)
Versão 6 (100 caracteres)
— Escova dental
Você pode mudar _[a]e _[b]para _.ae _.b. Mudar também /\w+/g,_={}para _=/\w+/gproduzirá o mesmo resultado.
@eithedog Obrigado! No entanto, não posso mudar _[a]de ser _.aporque ele tenta acessar a propriedade "a"de _, não a propriedade a.
— Escova de dentes
ah, correto - o pedido não será mantido. Continue :)
Oh, eu não percebi sua resposta .. legal. Mas .. está Object.keysse tornando global no ES6? Sua resposta parece assumir isso, mas não me lembro de ter visto isso como programado para o ES6.
@ FireFly Não consigo encontrar nenhuma documentação, mas funciona bem no Firefox. Não testei no Chrome / Opera / IE.
regex alterado de [^\w]+para [^\d\p{L}]+para resolver o problema com sublinhado
sem primeira linha, 82 caracteres
— Kamil Mikolajczyk
nu_bernão é alfanumérico. Este shouls ser 2 palavras
— triturador
Por que usar em nu_bervez de number?
Fui enganado por algumas outras postagens;) agora removi o "_" da entrada, mas corrigi o regex para lidar com isso #
Embora gawk asorttrabalhe em matrizes associativas, aparentemente não preserva os valores do índice, necessitando dasort
Uma solução gawk um pouco maior, porém pura, usada PROCINFOpara definir a ordem de classificação padrão para o array associativo (parece exigir um gawk relativamente recente -> 4.x?)
— chave de aço
Oooooh. Eu não sabia sobre o PROCINFO. Como se eu precisasse de outra desculpa para usar o awk na minha vida. Maldito seja!
@dmckee TBH Eu não conhecia o PROCINFO até começar a bisbilhotar - eu estava convencido de que havia uma maneira de fazer o tipo de forma nativa - apenas uma pena que os identificadores sejam tão longos;)
— steeldriver
Nos velhos tempos, simplesmente não havia uma maneira. O que leva a coisas como essa minha antiga resposta .
Javascript - 132 126 caracteres!
(Código JS mais curto)
Melhorou a regex e algumas edições.
<= // make s = "Quão brilhante é este dia, não é, é"
=> [['é', 3],
['Como', 1],
['brilhante', 1],
['this', 1],
['day', 1],
['isn', 1] ,
['t', 1]]
Antigo - 156 143 141 140 132 caracteres
Deu uma primeira tentativa no golfe. Feedback apreciado.
— Gaurang Tandon
EcmaScript 6, 115 100 87 (sem prompt e alerta)
— teh_senaus
You don't need var . Also, you can move a={} inside prompt - prompt(a={}). You can also drop Object. and change w=>a[w]=a[w]+1||1 to w=>a[w]=-~a[w]
Very nice. Beats the working Python one now :)
Same as for @toothbrush's answer - moving the declaration of a from prompt to regexp will spare two more chars.
It's nice and clean. Good job!
-1. Underscore _ should not be included in a word.
Maybe split(/\W+/) instead of scan (untested)?
@Howard Thanks. \W excludes _ so that had to be fixed, but it still saved 2 characters (then I added 20 to fix the sorting that I had neglected).
Shouldn't be sorted in reverse (a=gets.split(/[_\W]+/)).uniq.map{|w|[w,a.count(w)]}.sort_by(&:last).reverse.map{|x|p x}
@EduardFlorinescu Nah. reverse is way too verbose ;) Btw, it's not fair changing the question.
If you see in the output sample it was sorted descended only that I forgot to specify it.
— mattnewport
You should definitely insert some sort of explanation; that way we can understand your code.
Added a degolfed version and some explanation.
— Azwr
The solution is nice but the output is not sorted.
What do you mean by sorted? Thanks for the comment.
\w matches [a-zA-Z0-9_]. Your entire regex can be replaced by r'\w+'. Also, the x variable is not needed, just use raw_input() as the second parameter to findall.
By sorted, the OP means that the words that appear most often need to be listed first. Also, your program should include a print statement (i.e. print map(...), otherwise it's not a complete program.
I don't have time to sort it right now :( I'm in a hurry , thanks for the suggestions and comments.
The sort should be by the number. of occurrences so you should be first.
@EduardFlorinescu Silly me... I'll fix it later.
@EduardFlorinescu fixed
++o[a]||1 => -~o[a]
— nyi
— Zachary Vance
— Alex Reinking
— nightTrevors
I've no knowledge of q but is the regex [0-z] ASCII-based? If it is, wouldn't it also include ASCII chars 58-64? Because those are : ; < = > ? @.
Great catch jimbob, thanks
You're welcome; only spotted because I found the same in C#. Sadly, same with [A-z], which matches ASCII 91-96, which are `[ \ ] ^ _ ``
ah right you are, nice little ascii lesson right there!
I just discovered [^_\W]+ for mine, which should be "exclude non-word characters and underscore", if your syntax supports the \W class...
Separators will be anything that is not alpha-numeric - You only split on whitespace.
— Landarzar
Doesn't fulfill the condition that non-alphanumeric should be separator.
If you assumed the string was in some variable s, as some other answers do, you could lose 6 characters by replacing input().
@PhilH well. you are right, but I would never read that out of the requirements. sure the "string for JavaScript"-part might suggest it, but I cannot, with a clear conscience, interpret a string-variable as a valid "input". But you are right. that would shorten it even more. :P
Well this depends on the definition of alpha-numeric. In Python, "\w" is defined for accepting alpha-numeric chars. You might be correct but a with this kind of interpretation of the rules, my solution keeps being correct. :)