Сортировка чисел представлена ​​в неизвестной базе

13

Учитывая список строк, сортируйте список как числа, не зная, какая база используется. Значения цифр также неизвестны (возможно, что '1'> '2').

Поскольку значения цифр неизвестны, используйте закон Бенфорда (или закон первой цифры), чтобы определить относительное значение цифр. Для распределений, которые следуют закону Бенфорда, цифры с более низкими значениями появляются в качестве лидирующей цифры чаще, чем цифры с более высокими значениями.

правила

  • Это
  • Список строк может быть получен из источника по вашему выбору (стандартный, переменная, файл, пользователь и т. Д.)
  • Строки ограничены символами ASCII.
  • Символы, которые не появляются в качестве ведущих символов, имеют самые высокие значения. (предположим, что нулей нет, и сортируйте строго по ведущей частоте.)
  • Символы, которые появляются в качестве начальных цифр столько раз, сколько другие символы, имеют одинаковый вес.

пример

несортированный

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

Сортировка

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

Примечание: В данном примере 'cz', 'cy'и 'cx'может появиться как 5 - й, 6 - й и 7 - элементы в любом порядке , так как цифры 'x', 'y'и 'z'имеют одинаковый вес.

Rynant
источник
«Строки ограничены символами ASCII». Ваш пример показывает только буквенно-цифровые символы (на самом деле только буквенные символы). Вы имеете в виду все символы ASCII или просто [0-9a-zA-Z], и буквы в нижнем регистре считаются одинаковыми или отличными от символов в верхнем регистре?
Джошуа Тейлор
Все символы ASCII должны поддерживаться, и прописные и строчные буквы различны.
Rynant

Ответы:

7

Питон, 59 108 112

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

Ввод предоставляется в виде списка a, и это выражение создает отсортированный список (+2 символа для назначения переменной). Это сортирует список в обратном порядке по отрицательной длине, а затем по частоте.

nneonneo
источник
+1 Отлично сделано. Не думал, что это можно сделать эффективно в одном выражении.
Seequ
Ницца! Я не знал о zipс None. Хотя это не работает в Python 3, который будет использовать itertools.zip_longest.
Rynant
Noneне может сравниться с целыми числами в Python 3, поэтому он все равно потерпит неудачу.
nneonneo
@nneonneo Правильно, fillvalueдолжно быть установлено что-то меньшее, чем наименьшее значение.
Rynant
И я подумал, что знаю кое-что о питоне - нет. Не могли бы вы объяснить свой код несколько более подробно? Я был бы очень счастлив - питон новичок здесь.
flawr
3

Руби, 65

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

Сортирует лексикографически по размеру строки, затем по частоте каждого символа, а не по первой цифре.

histocrat
источник
0

Ява (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;
    });
}

Методы принимают массив строк и сортируют массив на месте. Ничего особенного в реализации, но она использует лямбда-выражения, добавленные в Java 8.

Ypnypn
источник
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]))

предел

Значения частоты до 1000000000: для сортировки значения частоты объединяются в большую дополненную строку

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
)

Увеличение Sidenote X-~ на 1, даже если исходное число X не определено или NaN

использование

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

Выход: ["c", "a", "cc", "ca", "cx", "cz", "cy", "ac", "ccc"]

edc65
источник