Trier les éléments distincts d'une liste par ordre décroissant par fréquence


12

Écrivez une fonction qui prend une liste ou un tableau et renvoie une liste des éléments distincts, triés par ordre décroissant par fréquence.

Exemple:

Donné:

["John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John"]

Valeur de retour attendue:

["Doe","Harry","John","Dick"]

Code-golf ou code-challenge?
marinus

Code-golf. C'était une erreur. Juste le corriger
belvi

Réponses:


13

APL (14)

{∪⍵[⍒+⌿∘.≡⍨⍵]}

Il s'agit d'une fonction qui prend une liste, par exemple:

      names
 John  Doe  Dick  Harry  Harry  Doe  Doe  Harry  Doe  John 
      {∪⍵[⍒+⌿∘.≡⍨⍵]} names
 Doe  Harry  John  Dick

Explication:

  • ∘.≡⍨⍵: comparer chaque élément du tableau à chaque autre élément du tableau, donnant une matrice
  • +⌿: additionne les colonnes de la matrice, donnant combien de fois chaque élément apparaît
  • : donner des indices de type descendant
  • ⍵[... ]: réorganiser par les indices donnés
  • : obtenez les éléments uniques

3
Et pourtant, d'une manière ou d'une autre, ils appellent le passage de ce langage spirituel concis au «progrès» Java? (-:
hippietrail

8

Python 3 - 47 43; Python 2-40 39

Pour Python 3:

f=lambda n:sorted(set(n),key=n.count)[::-1]

Pour Python 2:

f=lambda n:sorted(set(n),cmp,n.count,1)

Démo:

>>> names = ["John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John"]
>>> f(names)
['Doe', 'Harry', 'John', 'Dick']

1
J'essayais de poster le même, mais voici une modification. f=lambda n:sorted(set(n),cmp,n.count,1)39 personnages
VOUS du

1
Hmm, je ne savais pas que vous pouviez passer à la fois une fonction non nulle cmpet une keyfonction. Cool.
Blckknght

1
Un peu plus court:f=lambda n:sorted(set(n),key=n.count)[::-1]
grc

Merci @grc, le smiley extraterrestre enregistre certains personnages dans le cas Python 3.
Blckknght


4

Mathematica (26 37)

Avec n = {"John", "Doe", "Dick", "Harry", "Harry", "Doe", "Doe", "Harry", "Doe", "John"}:

Last/@Gather@n~SortBy~Length//Reverse

{"Doe", "Harry", "John", "Dick"}


Mathematica V10 + (26) :

Keys@Sort[Counts[n],#>#2&]

@garej ancienne version utilisée. Poster comme autre réponse?
Yves Klett

Je l'ai ajouté au vôtre si cela ne vous dérange pas ...
garej

@garej. Merci, excellente solution!
Yves Klett

3

Perl 6 (36 octets, 35 caractères)

»peut être remplacé par >>, si vous ne pouvez pas gérer UTF-8. Je suis presque sûr que cela pourrait être plus court, mais la Bagclasse est relativement étrange dans son comportement (malheureusement), et n'est pas vraiment complète, car elle est relativement nouvelle (mais elle peut compter des arguments). {}déclare une fonction anonyme.

{(sort -*.value,pairs bag @_)».key}

Exemple de sortie (de Perl 6 REPL):

> my @names = ("John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John")
John Doe Dick Harry Harry Doe Doe Harry Doe John
> {(sort -*.value,pairs bag @_)».key}(@names)
Doe Harry John Dick

3

Rubis: 34 37 personnages

f=->a{a.sort_by{|z|-a.count(z)}&a}

(édité: la solution précédente de 30 caractères était le corps de la fonction)


Vous pouvez couper quelques caractères avec f=->a{a.sort_by{|z|-a.count(z)}&a}. Le &fait un uniq.
histocrate

3

GolfScript, 14 caractères (19 comme fonction nommée, également 14 comme programme complet)

:a.|{[.]a\-,}$

Ce code prend un tableau sur la pile et trie ses éléments uniques par ordre décroissant par nombre d'occurrences. Par exemple, si le tableau d'entrée est:

["John" "Doe" "Dick" "Harry" "Harry" "Doe" "Doe" "Harry" "Doe" "John"]

alors le tableau de sortie sera

["Doe" "Harry" "John" "Dick"]

Remarque: Le code ci-dessus est une simple séquence d'instructions. Pour la transformer en fonction nommée, enveloppez-la entre accolades et affectez-la à un nom, comme dans:

{:a.|{[.]a\-,}$}:f;

Alternativement, pour transformer le code en un programme complet qui lit une liste à partir de l'entrée standard (en utilisant la notation de liste illustrée ci-dessus) et l'imprime sur la sortie standard, ~ajoutez et ajoutez `au code. Le [. peut être omis dans ce cas (puisque nous savons qu'il n'y aura rien d'autre sur la pile), de sorte que le programme résultant à 14 caractères sera:

~:a.|{]a\-,}$`

Comment ça marche?

  • :aenregistre une copie du tableau d'origine dans la variable apour une utilisation ultérieure.

  • .| calcule l'union définie du tableau avec lui-même, éliminant les doublons comme effet secondaire.

  • { }$trie le tableau dédoublonné à l'aide des clés de tri personnalisées calculées par le code à l'intérieur des accolades. Ce code prend chaque élément du tableau, utilise la soustraction du tableau pour le supprimer du tableau d'entrée d'origine enregistré dans a, et compte le nombre d'éléments restants. Ainsi, les éléments sont triés par ordre décroissant de fréquence.

Ps. Voir ici pour la version originale de 30 caractères.


Je pense que cela [a\])^devrait être équivalent à [.;]a\-. Trier par nombre d'éléments non correspondants est une bonne idée.
Peter Taylor

Hélas, non: ^effondre les doublons, -non. (Et ITYM (, non ).) Fonctionnerait , [a\](\-mais ne sauverait aucun caractère.
Ilmari Karonen

2

R: 23 caractères

n <- c("John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John")

names(sort(table(n),T))
## [1] "Doe"   "Harry" "John"  "Dick" 

Mais il utilise le raccourci pas si sympa de Tto TRUE...


1

si cela pouvait convenir ici: In sql-server

create table #t1 (name varchar(10))
insert into #t1 values ('John'),('Doe'),('Dick'),('Harry'),('Harry'),('Doe'),('Doe'),('Harry'),('Doe'),('John')


select name from #t1 group by name order by count(*) desc

OU

with cte as
(

select name,count(name) as x from #t1 group by name
)

select name from cte order by x desc

le voir en action


1
Pourquoi le CTE? select name from #t1 group by name order by count(*) desc
manatwork du

1

PHP, 63 62 61 caractères

function R($a){foreach($a as$v)$b[$v]++;arsort($b);return$b;}

Démo:

$c = array("John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John");
$d = print_r(R($c));

Array ( [Doe] => 4 [Harry] => 3 [John] => 2 [Dick] => 1 )

jetez un oeil à array_count_values()… C'est tout ce que vous avez à utiliser (y compris arsort())
bwoebi

array_count_values()ne supprime pas les valeurs dupliquées, ni les ordonne, comme je peux le voir.
Vereos

Il supprime les doublons… Il ne les commande tout simplement pas… => arsort
bwoebi

@bwoebi Vous avez raison. Malheureusement, l'écrire de cette façon est 1 caractère plus long que cette réponse.
Tim Seguine du

Pourquoi le chemin est-il array_count_valuesplus long? <?$u=array_count_values($_GET);arsort($u);print_r($u);sont 54 octets à mon avis
Jörg Hülsermann

1

Ruby: 59 caractères

f=->n{n.group_by{|i|i}.sort_by{|i|-i[1].size}.map{|i|i[0]}}

Exemple d'exécution:

irb(main):001:0> f=->n{n.group_by{|i|i}.sort_by{|i|-i[1].size}.map{|i|i[0]}}
=> #<Proc:0x93b2e10@(irb):2 (lambda)>

irb(main):004:0> f[["John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John"]]
=> ["Doe", "Harry", "John", "Dick"]

1

Mathematica, 39 caractères

f = Reverse[First /@ SortBy[Tally@#, Last]] &

names = {"John", "Doe", "Dick", "Harry", "Harry",
         "Doe", "Doe", "Harry", "Doe", "John"};

f@names

{Biche, Harry, John, Dick}


1

JavaScript (ECMAScript5): 118 113 caractères

function f(n){m={}
for(i in n){m[n[i]]=m[n[i]]+1||1}
return Object.keys(m).sort(function(a,b){return m[b]-m[a]})}

http://jsfiddle.net/mblase75/crg5B/


Avec Harmony fonctions fléchées de la graisse : f=n=>{m={};n.forEach(e=>m[e]=m[e]+1||1);return Object.keys(m).sort((a,b)=>m[b]-m[a])}. (Actuellement uniquement dans Firefox.)
Manatwork

Vous pouvez utiliser m[n[i]]=-~m[n[i]]pour incrémenter et vous n'avez pas besoin de {} autour du corps de la boucle.
Neil

1

Haskell - 53 personnages

import Data.List
import Data.Ord

f :: (Eq a, Ord a) => [a] -> [a]
f=map head.(sortBy$flip$comparing length).group.sort

Explication: les deux premières lignes sont des importations nécessaires, la ligne de code suivante est la signature de type (généralement pas nécessaire), la fonction réelle est la dernière ligne. La fonction trie la liste par son ordre naturel, regroupe les éléments égaux en listes, trie la liste des listes par taille décroissante et prend le premier élément de chaque liste.

longueur totale, importations comprises: 120

sans importations mais avec signature de type: 86

fonctionner lui-même: 53


1

Clojure: 43 caractères

Une fonction:

#(keys(sort-by(comp - val)(frequencies %)))

Démo (en repl):

user=> (def names ["John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John"])
#'user/names
user=> (#(keys(sort-by(comp - val)(frequencies %))) names)
("Doe" "Harry" "John" "Dick")

0

Perl

pour répondre aux spécifications d'E / S données, j'ai besoin de 120 caractères

s!"([^"]+)"[],]!$a{$1}++!e while(<>);print 'MostOccuring = [',join(',',map{qq("$_")}sort{$a{$a}<=>$a{$b}}keys %a),"]\n"

code le plus court en prenant un élément par ligne et en imprimant un élément par ligne, je n'ai besoin que de 55 caractères

$a{$_}++ while(<>);print sort{$a{$a}<=>$a{$b}}keys %a)

0

C #: 111 caractères

List<string>M(List<string>l){return l.GroupBy(q=>q).OrderByDescending(g=>g.Count()).Select(g=>g.Key).ToList();}

(à l'intérieur d'une classe)

var names = new List<string> {"John", "Doe", "Dick", "Harry", "Harry", "Doe", "Doe", "Harry", "Doe", "John"};
foreach(var s in M(names))
{
    Console.WriteLine(s);
}

Biche

Harry

John

Queue

Une solution simple utilisant LINQ.


Vous pouvez également supprimer le .ToList () , car la séquence est énumérée via foreach
Adam Speight

C'est vrai, mais je devrais alors changer le type de retour en IEnumerable <string> .
paavohtl


0

Scala (71)

(x.groupBy(a=>a)map(t=>(t._1,t._2.length))toList)sortBy(-_._2)map(_._1)

Non golfé:

def f(x:Array[String]) =
  (x.groupBy(a => a) map (t => (t._1, t._2.length)) toList) 
    sortBy(-_._2) map(_._1)

0

J, 8 octets

~.\:#/.~

Usage

Les noms sont stockés sous forme de tableau de chaînes encadrées.

   'John';'Doe';'Dick';'Harry';'Harry';'Doe';'Doe';'Harry';'Doe';'John'
┌────┬───┬────┬─────┬─────┬───┬───┬─────┬───┬────┐
│John│Doe│Dick│Harry│Harry│Doe│Doe│Harry│Doe│John│
└────┴───┴────┴─────┴─────┴───┴───┴─────┴───┴────┘
   f =: ~.\:#/.~
   f 'John';'Doe';'Dick';'Harry';'Harry';'Doe';'Doe';'Harry';'Doe';'John'
┌───┬─────┬────┬────┐
│Doe│Harry│John│Dick│
└───┴─────┴────┴────┘

Explication

~.\:#/.~   Input: A
    #/.~   Finds the size of each set of identical items (Frequencies)
~.         List the distinct values in A
           Note: the distinct values and frequencies will be in the same order
  \:       Sort the distinct values in decreasing order according to the frequencies
           Return the sorted list implicitly

0

CJam, 15 octets (éventuellement non concurrents)

q~$e`{0=W*}$1f=

Cela peut utiliser les fonctionnalités CJam après la publication de ce défi. Je suis trop paresseux pour vérifier.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.