Trier les nombres représentés dans une base inconnue

13

Étant donné une liste de chaînes, triez la liste sous forme de nombres sans savoir quelle base est utilisée. Les valeurs des chiffres sont également inconnues (il est possible que '1'> '2').

Étant donné que les valeurs des chiffres sont inconnues, utilisez la loi de Benford (ou la loi du premier chiffre) pour déterminer la valeur relative des chiffres. Pour les distributions qui suivent la loi de Benford, les chiffres de faible valeur apparaissent plus fréquemment comme chiffre de tête que les chiffres de valeur supérieure.

Règles

  • C'est du
  • La liste des chaînes peut provenir d'une source de votre choix (stdin, variable, fichier, utilisateur, etc.)
  • Les chaînes sont limitées aux caractères ASCII.
  • Les caractères qui n'apparaissent pas comme un caractère de tête ont les valeurs les plus élevées. (supposez qu'il n'y a pas de zéros et triez strictement par fréquence de tête.)
  • Les caractères qui apparaissent en tant que chiffres de tête le même nombre de fois que les autres caractères sont pondérés de manière égale.

Exemple

Non trié

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

Triés

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

Remarque: Dans l'exemple, 'cz', 'cy'et 'cx'peut apparaître comme la 5e, 6e et 7e éléments dans un ordre quelconque étant donné que les chiffres 'x', 'y'et 'z'sont également pondérés.

Rynant
la source
"Les chaînes sont limitées aux caractères ASCII." Votre exemple ne montre que des caractères alphanumériques (en fait uniquement des caractères alphabétiques). Voulez-vous dire tous les caractères ASCII, ou seulement [0-9a-zA-Z], et les lettres minuscules comptent-elles de la même manière ou différemment des caractères majuscules?
Joshua Taylor
Tous les caractères ASCII doivent être pris en charge et les majuscules et les minuscules sont différents.
Rynant

Réponses:

7

Python, 59 108 112

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

L'entrée est fournie sous forme de liste a, et cette expression produit la liste triée (+2 caractères à affecter à une variable). Cela trie la liste en sens inverse par longueur annulée puis par fréquence.

nneonneo
la source
+1 Bien joué. Je ne pensais pas que cela pouvait être fait efficacement de l'espace en une seule expression.
seequ
Agréable! Je ne savais pas zipavec None. Bien que cela ne fonctionne pas en Python 3, ce qui serait utile itertools.zip_longest.
Rynant
Nonene peut pas être comparé à des entiers dans Python 3, donc il échouerait de toute façon.
nneonneo
@nneonneo Droite, fillvaluedevrait être définie sur quelque chose de moins que la plus petite valeur.
Rynant
Et je pensais que je savais quelque chose sur python - non. Pourriez-vous expliquer votre code un peu plus en détail? Je serais très heureux - débutant en python ici.
flawr
3

Rubis, 65

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

Trie lexicographiquement sur la taille de la chaîne, puis la fréquence de chaque caractère n'est pas le premier chiffre.

histocrate
la source
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;
    });
}

Les méthodes prennent un tableau de chaînes et trient le tableau en place. L'implémentation n'a rien d'extraordinaire, mais elle utilise les expressions lambda ajoutées à Java 8.

Ypnypn
la source
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

Valeurs de fréquence jusqu'à 1000000000: pour le tri, les valeurs de fréquence sont fusionnées dans une grande chaîne rembourrée

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

Incrément de Sidenote X-~ de 1 même si le nombre d'origine X n'est pas défini ou NaN

Usage

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

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

edc65
la source