Ordenar números representados en una base desconocida


13

Dada una lista de cadenas, clasifique la lista como números sin saber qué base se utiliza. Los valores de los dígitos también son desconocidos (es posible que '1'> '2').

Como los valores de los dígitos son desconocidos, use la Ley de Benford (o la Ley del primer dígito) para determinar el valor relativo de los dígitos. Para las distribuciones que siguen la Ley de Benford, los dígitos de menor valor aparecen como un dígito principal con mayor frecuencia que los dígitos de mayor valor.

Reglas

  • Esto es
  • La lista de cadenas puede provenir de una fuente de su elección (stdin, variable, archivo, usuario, etc.)
  • Las cadenas están limitadas a caracteres ASCII.
  • Los personajes que no aparecen como personajes principales tienen los valores más altos. (suponga que no hay ceros, y ordene estrictamente por frecuencia principal).
  • Los caracteres que aparecen como dígitos iniciales el mismo número de veces que otros caracteres se ponderan por igual.

Ejemplo

Sin clasificar

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

Ordenados

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

Nota: En el ejemplo, 'cz', 'cy'y 'cx'puede aparecer como el 5, 6 y 7 º elementos en cualquier orden, ya que los dígitos 'x', 'y'y 'z'tienen el mismo valor.


"Las cadenas están limitadas a caracteres ASCII". Su ejemplo solo muestra caracteres alfanuméricos (en realidad solo caracteres alfabéticos). ¿Te refieres a todos los caracteres ASCII, o simplemente [0-9a-zA-Z], y las letras minúsculas cuentan igual o diferente a las mayúsculas?
Joshua Taylor

Todos los caracteres ASCII deben ser compatibles, y mayúsculas y minúsculas son diferentes.
Rynant

Respuestas:


7

Pitón, 59 108 112

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

La entrada se proporciona como la lista a, y esta expresión produce la lista ordenada (+2 caracteres para asignar a una variable). Esto ordena la lista en reversa por longitud negada y luego por frecuencia.


+1 Bien hecho. No pensé que se podría hacer espacio de manera eficiente en una sola expresión.
seequ

¡Agradable! No sabía acerca zipde None. Aunque no funciona en Python 3, que usaría itertools.zip_longest.
Rynant

Noneno se puede comparar con los enteros en Python 3, por lo que fallará de todos modos.
nneonneo

@nneonneo Right, fillvaluedebería establecerse en algo menor que el valor más pequeño.
Rynant

Y pensé que sabía algo sobre python, no. ¿Podría explicar su código un poco más detallado? Estaría muy feliz - Python novato aquí.
flawr

3

Rubí, 65

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

Se ordena lexicográficamente según el tamaño de la cadena, luego la frecuencia de cada carácter como no el 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;
    });
}

Los métodos toman una matriz de cadenas y clasifican la matriz en su lugar. La implementación no tiene nada de lujoso, pero sí utiliza las expresiones lambda agregadas a 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]))

Límite

Valores de frecuencia de hasta 1000000000: para ordenar, los valores de frecuencia se fusionan en una gran cadena acolchada

Sin golf

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
)

Sidenote X-~ incrementa en 1 incluso si el número original X no está definido o NaN

Uso

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

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.