Classificar números representados em uma base desconhecida


13

Dada uma lista de strings, classifique a lista como números sem saber qual base é usada. Os valores dos dígitos também são desconhecidos (é possível que '1'> '2').

Como os valores dos dígitos são desconhecidos, use a Lei de Benford (ou Lei dos Primeiros Dígitos) para determinar o valor relativo dos dígitos. Para distribuições que seguem a Lei de Benford, os dígitos com valores mais baixos aparecem como um dígito inicial com mais frequência do que os dígitos com valores mais altos.

Regras

  • Isso é
  • A lista de strings pode vir de uma fonte de sua escolha (stdin, variável, arquivo, usuário, etc.)
  • As cadeias são limitadas a caracteres ASCII.
  • Os caracteres que não aparecem como um caractere à esquerda têm os valores mais altos. (suponha que não haja zeros e classifique estritamente pela frequência inicial).
  • Os caracteres que aparecem como dígitos iniciais no mesmo número de vezes que os outros caracteres têm o mesmo peso.

Exemplo

não triados

['c','ca','ac','cc','a','ccc','cx','cz','cy']

Classificado

['c','a','cc','ca','cz','cy','cx','ac','ccc']

Nota: No exemplo, 'cz', 'cy'e 'cx'pode aparecer como a 5ª, 6ª e 7ª elementos em qualquer ordem, desde os dígitos 'x', 'y'e 'z'têm o mesmo peso.


"Strings são limitadas a caracteres ASCII." Seu exemplo mostra apenas alfanuméricos (na verdade, apenas caracteres alfabéticos). Você quer dizer todos os caracteres ASCII ou apenas [0-9a-zA-Z] e as letras minúsculas contam o mesmo ou diferentemente dos caracteres maiúsculos?
Joshua Taylor

Todos os caracteres ASCII devem ser suportados e maiúsculas e minúsculas são diferentes.
Rynant

Respostas:


7

Python, 59 108 112

sorted(a,None,lambda x:(-len(x),map(zip(*a)[0].count,x)),1)

A entrada é fornecida como a lista ae esta expressão produz a lista classificada (+2 caracteres para atribuir a uma variável). Isso classifica a lista no sentido inverso, por comprimento negado e, em seguida, por frequência.


+1 Bem feito. Não achava que poderia ser feito espaço eficientemente em expressão única.
see

Agradável! Eu não sabia zipcom None. Embora não funcione no Python 3, o que seria usado itertools.zip_longest.
Rynant 12/06

Nonenão pode ser comparado com números inteiros no Python 3, portanto falharia de qualquer maneira.
N

@nneonneo Certo, fillvalueteria que ser definido como algo menor que o menor valor.
Rynant 12/06

E eu pensei que sabia algo sobre python - não. Você poderia explicar seu código um pouco mais detalhadamente? Eu ficaria muito feliz - novato python aqui.
flawr

3

Ruby, 65

f=->a{a.sort_by{|s|[s.size,s.chars.map{|c|a.count{|t|t[0]!=c}}]}}

Classifica lexicograficamente o tamanho da string e, em seguida, a frequência de cada caractere como não o dígito inicial.


0

Java (261)

void s(String[]s){int[]a=new int[128];for(String t:s)a[t.charAt(0)]++;java.util.Arrays.sort(s,(o,p)->{int j=o.length()-p.length();if(j!=0)return j;for(int i=0;i<Math.min(o.length(),p.length());i++){j=a[p.charAt(i)]-a[o.charAt(i)];if(j!=0)return j;}return 0;});}

void s(String[] s) {
    int[] a = new int[128];
    for (String t : s) {
        a[t.charAt(0)]++;
    }
    java.util.Arrays.sort(s, (o, p) -> {
        int j = o.length() - p.length();
        if (j != 0) {
            return j;
        }
        for (int i = 0; i < Math.min(o.length(), p.length()); i++) {
            j = a[p.charAt(i)] - a[o.charAt(i)];
            if (j != 0) {
                return j;
            }
        }
        return 0;
    });
}

Os métodos pegam uma matriz de seqüências de caracteres e classificam a matriz no lugar. Nada gosta na implementação, mas utiliza as expressões lambda adicionadas ao Java 8.


0

Javascript (E6) 147

F=i=>(f={},i.map(x=>(f[x[0]]=-~f[x[0]])),i.map(x=>[x,[...x].map(y=>1e9-~f[y]+'')]).sort((a,b,d=a[0].length-b[0].length)=>d||a[1]<b[1]).map(x=>x[0]))

Limite

Valores de frequência de até 1000000000: para classificação, os valores de frequência são mesclados em uma grande cadeia acolchoada

Ungolfed

F=i=>(
  f={}, //init frequency map
  i.map(x => (f[x[0]]=-~f[x[0]])), // build frequency map
  i.map(x => [x, [...x].map(y=>1e9-~f[y]+'')]) // add frequency info to each element of input list
 .sort((a,b,d=a[0].length-b[0].length)=>d || a[1]<b[1]) // then sort by lenght and frequency
 .map( x => x[0]) // throw away frequency info
)

O Sidenote X-~ aumenta em 1, mesmo que o número original X seja indefinido ou NaN

Uso

F(['c','ca','ac','cc','a','ccc','cx','cz','cy'])

Resultado: ["c", "a", "cc", "ca", "cx", "cz", "cy", "ac", "ccc"]

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.