Classifique os elementos distintos de uma lista em ordem decrescente por frequência


12

Escreva uma função que pegue uma lista ou matriz e retorne uma lista dos elementos distintos, classificados em ordem decrescente por frequência.

Exemplo:

Dado:

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

Valor de retorno esperado:

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

Código-golfe ou código-desafio?
Marinus

Código de golfe. Isso foi um erro. Apenas corrija
belvi

Respostas:


13

APL (14)

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

Esta é uma função que leva uma lista, por exemplo:

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

Explicação:

  • ∘.≡⍨⍵: compare cada elemento da matriz com outro elemento da matriz, fornecendo uma matriz
  • +⌿: soma as colunas da matriz, fornecendo quantas vezes cada elemento ocorre
  • : fornece índices de ordem descendente
  • ⍵[... ]: reordenar pelos índices fornecidos
  • : obtenha os elementos exclusivos

3
E, de alguma forma, eles chamam de passar dessa linguagem concisa e espirituosa para Java "progresso"? (-:
hippietrail

8

Python 3 - 47 43; Python 2-40 39

Para Python 3:

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

Para Python 2:

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

Demo:

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

1
Eu estava tentando postar o mesmo, mas aqui está uma modificação. f=lambda n:sorted(set(n),cmp,n.count,1)39 caracteres
VOCÊ

1
Hmm, eu não sabia que você podia passar uma cmpfunção não-None e uma keyfunção. Legal.
Blckknght

1
Um pouco mais curto:f=lambda n:sorted(set(n),key=n.count)[::-1]
grc 03/01

Obrigado @grc, o smiley alienígena salva alguns caracteres no caso Python 3.
precisa saber é o seguinte


4

Mathematica (26 37.)

Com 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 versão mais antiga em uso. Postar como outra resposta?
Yves Klett

Eu adicionei a sua, se você não se importa ...
garej

@garej. Obrigado, excelente solução!
Yves Klett

3

Perl 6 (36 bytes, 35 caracteres)

»pode ser substituído por >>, se você não puder lidar com UTF-8. Tenho quase certeza de que isso poderia ser mais curto, mas a Bagclasse é relativamente estranha em seu comportamento (infelizmente) e não é realmente completa, pois é relativamente nova (mas pode contar argumentos). {}declara uma função anônima.

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

Saída de amostra (do 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

Ruby: 34 37. personagens

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

(editado: a solução anterior de 30 caracteres era o corpo da função)


Você pode aparar alguns caracteres com f=->a{a.sort_by{|z|-a.count(z)}&a}. O &faz um uniq.
histocrat

3

GolfScript, 14 caracteres (19 como função nomeada, também 14 como programa completo)

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

Esse código pega uma matriz na pilha e classifica seus elementos exclusivos em ordem decrescente pelo número de ocorrências. Por exemplo, se a matriz de entrada for:

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

então a matriz de saída será

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

Nota: O código acima é uma sequência simples de instruções. Para transformá-lo em uma função nomeada, envolva-o entre chaves e atribua-o a um nome, como em:

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

Como alternativa, para transformar o código em um programa completo que leia uma lista da entrada padrão (usando a notação de lista mostrada acima) e a imprima na saída padrão, ~adicione e acrescente `ao código. O [. pode ser omitido nesse caso (já que sabemos que não haverá mais nada na pilha), para que o programa de 14 caracteres resultante seja:

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

Como funciona?

  • :asalva uma cópia da matriz original na variável apara uso posterior.

  • .| calcula a união do conjunto da matriz consigo, eliminando duplicatas como efeito colateral.

  • { }$classifica a matriz deduplicada usando as chaves de classificação personalizadas calculadas pelo código dentro dos chavetas. Esse código utiliza cada elemento da matriz, usa a subtração da matriz para removê-lo da matriz de entrada original salva ae conta o número de elementos restantes. Assim, os elementos são classificados em ordem decrescente de frequência.

Ps. Veja aqui a versão original de 30 caracteres.


Eu acho que isso [a\])^deve ser equivalente a [.;]a\-. Classificar por número de elementos não correspondentes é uma boa ideia.
Peter Taylor

Infelizmente, não: ^recolhe duplicados, -não. (E ITYM (, não ).) Funcionaria , [a\](\-mas não salvaria nenhum personagem.
Ilmari Karonen

2

R: 23 caracteres

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

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

Mas ele usa o atalho não tão bom de Tpara TRUE...


1

se isso poderia caber aqui: 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

vê-lo em ação


1
Por que o CTE? select name from #t1 group by name order by count(*) desc
precisa saber é

1

PHP, 63 62 61 caracteres

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

Demo:

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

ter um olhar array_count_values()... Isso é tudo que você tem que usar (inclusive arsort())
bwoebi

array_count_values()não exclui valores duplicados nem os ordena, como posso ver.
Vereos

Apaga as duplicatas ... Ele só não requisitá-los ... => arsort
bwoebi

@bwoebi Você está certo. Infelizmente, escrever dessa maneira é 1 caractere a mais do que esta resposta.
Tim Seguine

Por que o caminho é array_count_valuesmais longo? <?$u=array_count_values($_GET);arsort($u);print_r($u);são 54 bytes na minha opinião
Jörg Hülsermann 2/17

1

Ruby: 59 caracteres

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

Exemplo de execução:

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 caracteres

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

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

f@names

{Corça, Harry, João, Dick}


1

JavaScript (ECMAScript5): 118 113 caracteres

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/


Com o Harmony funções de seta gordura : f=n=>{m={};n.forEach(e=>m[e]=m[e]+1||1);return Object.keys(m).sort((a,b)=>m[b]-m[a])}. (Atualmente apenas no Firefox).
manatwork

Você pode usar m[n[i]]=-~m[n[i]]para incrementar e não precisa de {} s no corpo do loop.
Neil

1

Haskell - 53 Personagens

import Data.List
import Data.Ord

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

Explicação: as duas primeiras linhas são importações necessárias, a próxima linha de código é a assinatura do tipo (geralmente não é necessária), a função real é a última linha. A função classifica a lista por sua ordem natural, agrupa elementos iguais em listas, classifica a lista de listas por tamanho decrescente e pega o primeiro elemento de cada lista.

comprimento total incluindo importações: 120

sem importações mas com assinatura de tipo: 86

função em si: 53


1

Clojure: 43 caracteres

Função:

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

Demo (em substituição):

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

para atender às especificações de E / S, preciso de 120 caracteres

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

código mais curto puro, pegando um item por linha e imprimindo um item por linha, preciso apenas de 55 caracteres

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

0

C #: 111 caracteres

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

(dentro de uma 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);
}

Corça

atormentar

John

Dick

Uma solução simples usando o LINQ.


Você também pode remover o .ToList () , uma vez que a seqüência numeradas através da foreach
Adam Speight

Isso é verdade, mas então eu teria que mudar o tipo de retorno para IEnumerable <string> .
paavohtl


0

Scala (71)

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

Ungolfed:

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

0

J, 8 bytes

~.\:#/.~

Uso

Os nomes são armazenados como uma matriz de seqüências de caracteres em caixa.

   '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│
└───┴─────┴────┴────┘

Explicação

~.\:#/.~   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 bytes (possivelmente não concorrente)

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

Isso pode usar os recursos do CJam após o lançamento deste desafio. Estou com preguiça de verificar.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.