Sortuj liczby reprezentowane w nieznanej bazie

13

Biorąc pod uwagę listę ciągów, posortuj listę jako liczby, nie wiedząc, która baza jest używana. Wartości cyfr również nie są znane (możliwe, że '1'> '2').

Ponieważ wartości cyfr są nieznane, użyj prawa Benforda (lub prawa pierwszej cyfry), aby określić względną wartość cyfr. W przypadku dystrybucji zgodnych z prawem Benforda cyfry o niższej wartości pojawiają się jako cyfra wiodąca częściej niż cyfry o wyższej wartości.

Zasady

  • To jest
  • Lista ciągów może pochodzić z wybranego przez ciebie źródła (standard, zmienna, plik, użytkownik itp.)
  • Ciągi znaków są ograniczone do znaków ASCII.
  • Postacie, które nie pojawiają się jako bohater wiodący, mają najwyższe wartości. (zakładając, że nie ma zer i sortuj ściśle według częstotliwości wiodącej).
  • Znaki, które pojawiają się jako cyfry wiodące tyle samo razy, co inne znaki, są ważone jednakowo.

Przykład

Nieposortowany

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

Posortowane

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

Uwaga: W tym przykładzie 'cz', 'cy'a 'cx'może pojawić się jako 5., 6. i 7. elementów w dowolnej kolejności od cyfr 'x', 'y'i 'z'są równo ważone.

Rynant
źródło
„Ciągi znaków są ograniczone do znaków ASCII”. Twój przykład pokazuje tylko alfanumeryczne (właściwie tylko znaki alfabetyczne). Czy masz na myśli wszystkie znaki ASCII, czy po prostu [0-9a-zA-Z] i czy małe litery liczą tyle samo lub inaczej niż wielkie litery?
Joshua Taylor
Wszystkie znaki ASCII powinny być obsługiwane, a wielkie i małe litery są różne.
Rynant

Odpowiedzi:

7

Python, 59 108 112

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

Dane wejściowe są dostarczane jako lista a, a to wyrażenie tworzy posortowaną listę (+2 znaki do przypisania do zmiennej). To sortuje listę w odwrotnej kolejności według zanegowanej długości, a następnie według częstotliwości.

nneonneo
źródło
+1 Ładnie wykonane. Nie sądziłem, że można to zrobić w przestrzeni efektywnie w pojedynczym wyrażeniu.
patrz
Ładny! Nie wiedziałem o zipz None. Chociaż nie działa w Pythonie 3, którego by użył itertools.zip_longest.
Rynant
Nonenie można porównać do liczb całkowitych w Pythonie 3, więc i tak się nie powiedzie.
nneonneo
@nneonneo Racja, fillvaluemusiałaby być ustawiona na coś mniejszego niż najmniejsza wartość.
Rynant
I myślałem, że wiem coś o python - nie. Czy możesz wyjaśnić swój kod nieco bardziej szczegółowo? Byłbym bardzo szczęśliwy - tutaj jest początkujący python.
flawr
3

Ruby, 65

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

Sortuje leksykograficznie według wielkości łańcucha, a następnie częstotliwości każdego znaku jako nie cyfry wiodącej.

histocrat
źródło
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;
    });
}

Metody pobierają tablicę ciągów i sortują tablicę na miejscu. W implementacji nie ma nic wymyślnego, ale korzysta on z wyrażeń lambda dodanych do Java 8.

Ypnypn
źródło
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]))

Limit

Wartości częstotliwości do 1000000000: do sortowania wartości częstotliwości są łączone w duży, wyściełany ciąg

Nie golfił

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
)

X-~Przyrost sidenotyczny o 1, nawet jeśli pierwotny numer X jest niezdefiniowany lub NaN

Stosowanie

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

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

edc65
źródło