Le code doit prendre en entrée un texte (non obligatoire peut être n'importe quoi fichier, stdin, chaîne pour JavaScript, etc.):
This is a text and a number: 31.
La sortie doit contenir les mots avec leur nombre d'occurrences, triés par le nombre d'occurrences dans l'ordre décroissant:
a:2
and:1
is:1
number:1
This:1
text:1
31:1
Notez que 31 est un mot, donc un mot est quelque chose d'alpha-numérique, le nombre n'agit pas comme des séparateurs donc par exemple se 0xAF
qualifie comme un mot. Les séparateurs seront tout ce qui n'est pas alphanumérique, y compris .
(point) et -
(trait d'union), i.e.
ou pick-me-up
donnerait respectivement 2 ou 3 mots. Devrait être sensible à la casse, This
et this
serait deux mots différents, '
serait également séparateur ainsi wouldn
et t
sera 2 mots différents dewouldn't
.
Écrivez le code le plus court dans la langue de votre choix.
Réponse correcte la plus courte à ce jour:
This
le même quethis
ettHIs
)?wouldn't
2 mots (wouldn
ett
)?This
etthis
serait en effet deux mots différents, identiqueswouldn
ett
.i.e.
est un mot mais si nous laissons le point tous les points à la fin des phrases seront prises, même avec des guillemets ou des guillemets simples, etc.Réponses:
grep et coreutils
4442Tester:
Résulte en:
Mise à jour
la source
head
à la fin.grep -io \[A-Z0-9]*|sort|uniq -c|sort -nr
Java 8: 289
Ce qui est plutôt bien, car java est une langue très non golfique.
Non golfé:
Exécutez à partir de la ligne de commande:
la source
"[^\\W_]"
String.split(String regex)
méthode prend un modèle qui correspond au délimiteur à fractionner. Ainsi, par exemple,"aababba".split("b")
donnerait le tableau{"aa", "a", "", "a"}
. Mon expression régulière[^\\w\\d]
signifie «un caractère ni dans le mot ni dans les classes de caractères numériques».[^\\W_]
est à la place «un caractère qui n'est ni un trait de soulignement ni dans la classe non-caractère de mot» et correspondrait à n'importe quel caractère de mot à l'exception du trait de soulignement.\w
comprend\d
,\d
est donc redondant.\w
comprend un trait de soulignement, qui doit être considéré comme un séparateur selon la question. Donc, le regex correct pour le fractionnement devrait être"[\\W_]+"
.APL (57)
par exemple
Explication:
⎕D,⎕A,⎕UCS 96+⍳26
: chiffres, lettres majuscules, lettres minuscules(I←⍞)∊
: lire les entrées, les stockerI
, voir lesquelles sont alphanumériquesZ←I⊂⍨
: diviséI
en groupes de caractères alphanumériques, stocké dansZ
+⌿∘.≡⍨Z
: pour chaque élément dansZ
, voyez à quelle fréquence il se produitZ,⍪
: faire correspondre chaque élément parZ
paire avec le nombre de fois où il se produitG←⊃∪↓
: sélectionner uniquement les paires uniques, stocker dansG
⍒,1↓⍉G
: obtenir des indices triés pour les occurrencesG[
...;]
: réorganiser les lignes deG
par les indices donnésla source
⎕s
( help.dyalog.com/latest/Content/Language/System%20Functions/… ) et le nouvel opérateur clé ( help.dyalog.com/latest/Content/Language/Primitive%20Operators/… ):g⌷⍨⊂⍒2⌷⍉g←{⍺,≢⍵}⌸('\w+'⎕s'\0')⍞
C #:
153c144c142c111c115c118c114c113c(via LINQPad en mode "Instructions C #", sans inclure la chaîne d'entrée)
Version 1: 142c
Non golfé:
Résultats:
Version 2: 114c
(
[\w]
comprend_
, ce qui est incorrect !;[A-z]
inclut[ \ ] ^ _ `
; s'installer[^_\W]+
)Non golfé:
Résultats: (comme version 1)
la source
@"[^_\W]"
R, 58 caractères
Usage:
la source
sort(table(gsub("[[:punct:]]","",scan(,""))),d=T)
. Malheureusement, les deux solutions ne fonctionnent pas correctementwouldn't
.perl6: 49 caractères
Peignez les entrées pour la correspondance des éléments
\w+
, mettez la liste de mots résultante dans unBag
, demandez leurs paires et triez-les par valeur négative. (C'est*
une étoile quelle qu'elle soit , ce n'est pas la multiplication ici)sortie:
la source
.words
au lieu de.comb(/\w+/)
:).words
ne supprime pas le:
ou.
de l'entrée comme requis :(_
ne doit pas être inclus dans un mot sous l'énoncé du problème.Python
10197Fonctionne maintenant avec newline:
la source
PHP - 84 octets
L'entrée est acceptée comme argument de ligne de commande, par exemple:
Sortie pour l'exemple de chaîne:
la source
$argv[1]
_
ne doit pas être inclus dans un mot.PowerShell (40)
$ s est une variable qui contient la chaîne d'entrée.
la source
[\W]
n'est pas assez bon - il correspond à un espace dans mon test. Et ce n'est pas ordonné par nombre décroissant ...$s -split"[\W]"|group -ca|where{$_.Name -ne ""}|sort{-$_.Count}
vous rapproche (avec des frais, bien sûr)$s -split"\W+"|group -ca |sort count -des
-split"\W+"
correspond à une chaîne vide entre la dernière.
et la fin de la chaîne;\W+
correspond également à_
ce qui n'est techniquement pas autoriséPerl 69
Ajout de recommandations de @primo et @protist
la source
ge
etfor
. L'<=>
opérateur peut également être remplacé par-
.-
au lieu de<=>
son génie, je ne suis pas sûr que ce soit sur les conseils de golf pour le fil Perl. Je mettrai cela à jour plus tard, merci!\w
comprend également des chiffres (perl -e 'print for"a 1 2 3 4 b"=~/\w/g'
imprimésa1234b
), mais votre mécanisme d'itération des mots enregistre un autre caractère, donc je vais mettre à jour. Merci!Powershell:
5755536257(sans inclure la chaîne d'entrée)
résultats:
(avec accessoires à @microbian pour le groupe -ca)
la source
EcmaScript 6
Version 1 (108 caractères)
Version 2 (102 caractères)
Version 3 (105 caractères)
Version 4 (94 caractères)
Version 5 (sans alerte; 87 caractères)
Version 6 (100 caractères)
Sortie:
la source
_[a]
et_[b]
vers_.a
et_.b
. Le fait de passer également/\w+/g,_={}
à_=/\w+/g
produira le même résultat._[a]
pour être_.a
parce qu'il essaie d'accéder à la propriété"a"
de_
, pas à la propriétéa
.Object.keys
devient-il mondial dans ES6? Votre réponse semble supposer cela, mais je ne me souviens pas avoir vu cela comme prévu pour ES6.Groovy
7782changé l'expression régulière de
[^\w]+
à[^\d\p{L}]+
afin de résoudre le problème avec le soulignementsans première ligne, 82 caractères
sortie:
la source
nu_ber
n'est pas alphanumérique. Cela devrait être 2 motsnu_ber
au lieu denumber
?GNU awk + coreutils:
7169Bien que
gawk asort
fonctionnant sur des tableaux associatifs, il ne préserve apparemment pas les valeurs d'index, ce qui nécessitesort
GNU awk 4.x:
10093Une solution gawk légèrement plus grande mais pure utilisant
PROCINFO
pour définir l'ordre de tri par défaut pour le tableau associatif (semble nécessiter un gawk relativement récent -> 4.x?)la source
_
ne doit pas être inclus dans un mot.Javascript -
132126 caractères!(Code JS le plus court)
Amélioration de l'expression régulière et de certaines modifications.
Non golfé
Old -
156143141140132 caractèresA fait un premier essai au golf. Commentaires appréciés.
la source
EcmaScript 6,
11510087 (sans rapide et alerte)Thanks to @eithedog:
With prompt and alert (100):
Run it in Firefox.
la source
var
. Also, you can movea={}
insideprompt
-prompt(a={})
. You can also dropObject.
and changew=>a[w]=a[w]+1||1
tow=>a[w]=-~a[w]
a
from prompt to regexp will spare two more chars._
should not be included in a word.Ruby
588265Test run:
Edit 58->80: Ok, I was way off. I forgot to sort the words by occurrences. Also,
Array#uniq
is not an enumerator, but uses a given block to compare elements, so passingputs
to it didn't filter out duplicates (not that it says that we should).la source
split(/\W+/)
instead ofscan
(untested)?\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).reverse
(a=gets.split(/[_\W]+/)).uniq.map{|w|[w,a.count(w)]}.sort_by(&:last).reverse.map{|x|p x}
reverse
is way too verbose ;) Btw, it's not fair changing the question.F# - 169
Degolfed:
Output when called from fsi:
Update: Some explanation as requested in the comments.
Uses set functions to generate an array of non alphanumeric characters in the input to pass to String.Split, then uses sequence functions to filter out empty strings, generate word counts and print the result.
Some golfing tricks: Adds an empty string to the function argument s to force type inference of the argument as a string rather than explicitly declaring the type. Uses Seq.where rather than Seq.filter to save a few characters (they are synonyms). Mixes forward pipe and ordinary function application in an attempt to minimize characters. Uses currying and (op) syntax to treat <> ~- and <|| operators as regular functions to avoid declaring lambdas to filter empty strings, sort by descending count and print tuples.
la source
Python - 95 ( now 87 thanks to @primo)
Sample input :
Sample output :
Any improvement sugestion would be appreciated
la source
\w
matches[a-zA-Z0-9_]
. Your entire regex can be replaced byr'\w+'
. Also, thex
variable is not needed, just useraw_input()
as the second parameter tofindall
.print
statement (i.e.print map(...
), otherwise it's not a complete program.JavaScript
160144 (Edited: to meet requirements)Unminified:
Logs each word to console in order, passing the following string:
s="This is sam}}ple text 31to test the effectiveness of this code, you can clearly see that this is working-as-intended, but you didn't doubt it did you?.";
Outputs:
I don't have the heart to use
alert()
.la source
you
should be first._
should not be included in a word.++o[a]||1
=>-~o[a]
k [71 chars]
Any other character except alphanumeric chars will be considered as delimiter.
example
example
la source
Javascript (135)
Unminified:
Loops over every possible number of matches in descending order, and outputs words with that number of occurrences. Just to be horrible.
Notes: Alert would have reduced the length some. Strictly speaking alphanumeric should be
[^\W_]
la source
Haskell (153 = 104 code + 49 import)
Pretty straight-forward, totally composed function... no argument even necessary! This is my first golf, so go easy, maybe? :)
Output:
la source
q (50)
edit: fixed accidentally matching ascii 58-64 and 91-96
la source
q
but is the regex[0-z]
ASCII-based? If it is, wouldn't it also include ASCII chars 58-64? Because those are: ; < = > ? @
.[A-z]
, which matches ASCII 91-96, which are `[ \ ] ^ _ ``[^_\W]+
for mine, which should be "exclude non-word characters and underscore", if your syntax supports the\W
class...Pure Bash (no external programs), 164
This is longer than I'd hoped, but I wanted to see if the necessary counting and sorting (in the right direction) could be done purely with
bash
arrays (associative and non-associative):Save as a script file,
chmod +x
, and run:la source
AWK
Does the job without gawkish extensions:
If printing "count: word" instead, it would be a bit shorter but I wanted to mimic the given example output...
la source
Tcl, 99 bytes
Try it online!
la source
Python 2.X (108 - Characters)
Python 3.X (106 - Characters)
la source
Separators will be anything that is not alpha-numeric
- You only split on whitespace.Haskell - 137
la source
Python 3 - 76
The requirement of splitting on non-alphanumeric chars unfortunately extends the code by 19 chars. The output of the following is shown correctly. If you are not sure, add a
.most_common()
after the.Counter(...)
.In/Output
Given the input of
This is a text and a number: 31.
you get following output:I tried it with other values like
to ensure, the output-order does not rely on the key's value/hash. This example produces:
But as I said,
print(i('collections').Counter(i('re').findall('\w+',input())).most_common())
would return the results as an definitly ordered list of tuples.Python 3 - 57 (if a space would be enough for splitting :P)
la source
_
should not be included in a word.