Ordine alfabetico ungherese


19

Per coloro che desiderano molte più sfide rispetto al vecchio ordine alfabetico spagnolo , diamo un'occhiata a come viene ordinato l'alfabeto ungherese.

a, á, b, c, cs, d, dz, dzs, e, é, f, g, gy, h, i, í, j, k, l, ly, m, n, ny, o, ó, ö, ő, p, q, r, s, sz, t, ty, u, ú, ü, ű, v, w, x, y, z, zs

in realtà, q, w, xe ynon sono utilizzati in parole ungheresi, ma sono inclusi per prestiti linguistici e nomi stranieri. I personaggi accentati stranieri che non fanno parte dell'alfabeto ungherese (come ñ), hanno la stessa priorità di quelli non accentati, ma li ignoriamo per questa sfida.

Le regole, riassunte:

  • Digrammi ( cs, sz, ecc) e il trigramma ( dzs) sono considerati come se fossero lettere per conto proprio.
cudar
cukor
cuppant
csalit
csata
  • Se lo stesso digrafo o trigrafo si verifica due volte direttamente uno dopo l'altro in una parola, vengono scritti in modo semplificato: sszinvece di szsz, ddzsinvece dzsdzsche per l'ordine alfabetico, viene utilizzato l'ordine non semplificato. Ad esempio kasza< kaszinó< kassza, poiché kasszaviene utilizzato come k+ a+ sz+ sz+ aper motivi di ordine. A volte puoi trovare la versione non contratta in una parola, nel caso di parole composte.
kasza
kaszinó
kassza
kaszt
nagy
naggyá
nagygyakorlat
naggyal
nagyít
  • le maiuscole non contano, con l'eccezione quando le due parole sarebbero esattamente le stesse senza maiuscole, nel qual caso la lettera minuscola ha la priorità
jácint
Jácint
Zoltán
zongora
  • Le versioni corte e lunghe di vocali accentate hanno la stessa priorità ( a - á, e -é, i - í, o - ó, ö - ő, u - ú ü - ű), con una sola eccezione: se le due parole sarebbero altrimenti esattamente lo stesso, la vocale corta ha priorità sulla vocale lunga. Nota che le vocali con umlaut ( öe ü) sono caratteri completamente diversi da oe u.
Eger
egér
író
iroda
irónia
kerek
kerék
kérek
szúr
szül
  • I trattini o gli spazi (ad esempio, in parole composte, nomi, ecc.) Sono completamente ignorati
márvány
márványkő
márvány sírkő
Márvány-tenger
márványtömb

L'obiettivo

Il tuo programma / funzione riceve stringhe, composte da caratteri dell'alfabeto ungherese (sia minuscole che maiuscole), ma una stringa può contenere spazi o trattini. Per semplicità, il segno meno (ASCII 45) può essere usato come un trattino. Nota che alcuni caratteri (come il ő) non fanno parte di ASCII. È possibile utilizzare qualsiasi codifica desiderata, se supporta tutti i caratteri richiesti.

Devi ordinare le linee correttamente e visualizzare / restituire il risultato.

Per il test è possibile utilizzare qualsiasi sottoinsieme ordinato in modo casuale degli esempi precedenti.

MODIFICARE:

Si prega di non utilizzare alcun modo incorporato o altro che conosca già l'ordine alfabetico ungherese da solo. Renderebbe inutile la competizione e prenderebbe tutta la sfida di trovare la migliore espressione regolare o i migliori trucchi per giocare a golf.

EDIT2:

Per chiarire un chiarimento chiesto da isaacg: "due stringhe che differiscono solo per capitalizzazione e vocali lunghe e corte, ma differisce in entrambi i modi": Sebbene nessuna regola nel documento ufficiale affronti esplicitamente questa domanda, un esempio trovato all'interno di punti alla lunghezza della vocale che ha più importanza della capitalizzazione.


@FryAmTheEggman Dove lo vedi?
Morgan Thrapp,

9
Amico, non riesco nemmeno a memorizzare il nostro giusto ordine alfabetico. Come lo programmerò? ;)
Andras Deak l'

1
Ho cercato di trovare un controesempio legato al fallimento, in cui un apparente digraph è in realtà due lettere, come malacsülto nyílászáró. Mi chiedo se ce ne siano (ma avresti bisogno di un vocabolario per verificarlo, che presumibilmente non fa parte di questa sfida)
Andras Deak

1
Non c'è alcun esempio contenente dzs
TheConstructor il

Risposte:


4

Perl, 250

Include +11 per -Mutf8 -CS .

use Unicode::Normalize;$r="(?=cs|zs|dz|sz|[glnt]y)";print map/\PC*
/g,sort map{$d=$_;s/d\Kd(zs)|(.)\K$r\2(.)/\L$+\E$&/gi;s/d\Kzs/~$&/gi;s/$r.\K./~$&/gi;s/(\p{Ll}*)(\w?)\s*-*/\U$1\L$2/g;$c=$_;$b=$_=NFD lc;y/̈̋/~~/d;join$;,$_,$b,$c,$d}<>

Utilizza il linguaggio decora-decora-decorato (AKA Schwartzian Transform ) e l'ordinamento multilivello , dove i livelli sono:

  • L1: confronta le lettere di base, ignora i segni diacritici, il caso e alcuni segni di punteggiatura.
  • L2: confronta lettere di base e segni diacritici, ignora il caso e alcuni segni di punteggiatura.
  • L3: confronta lettere di base, segni diacritici e maiuscole, ignora alcuni segni di punteggiatura.
  • Ln: confronto a livello di byte di rottura.

Internamente, (ASCII 0x1C Field Separator - il cui valore è inferiore a qualsiasi carattere dell'alfabeto per questa sfida) viene utilizzato come separatore di livello.

Questa implementazione ha molte limitazioni, tra cui:

  • Nessun supporto per personaggi stranieri.
  • Non è possibile distinguere tra digrafi / trigrafi gemellati (lunghi) contratti e consonanti + digraph / trigraph, ad esempio: könnyű dovrebbe fascicolare come <k><ö><ny> <ny> <ű> , mentre tizennyolc dovrebbe fascicolare come <t> < i> <z> <e> <n> <ny> <o> <l> <c> ; házszám 'address = house (ház) number (szám)' dovrebbe essere fascicolato come <h><á><z><sz><á> <m> e non come * <h><á><zs> <z> <á> <m> .
  • Le regole di confronto per digrafi lunghi contratti non sono così coerenti (ma sono stabili): non chiariamo lo stesso livello ( ssz < n szsz, ..., zszs < n zzs ); glibc raccoglie le forme brevi prima delle forme complete ( ssz <szsz, ..., zzs <zszs ), ICU raccoglie le forme lunghe prima delle forme brevi a partire da L3 Case e Varianti ( szsz < 3 ssz, ..., zszs < 3 zzs )

Versione estesa:

use Unicode::Normalize;

$r="(?=cs|zs|dz|sz|[glnt]y)";   # look-ahead for digraphs

print map/\PC*\n/g,             # undecorate
  sort                          # sort
  map{                          # decorate

          $d=$_;                # Ln: identical level

          # expand contracted digraphs and trigraphs
          s/d\Kd(zs)|(.)\K$r\2(.)/\L$+\E$&/gi;

          # transform digraphs and trigraphs so they 
          #  sort correctly
          s/d\Kzs/~$&/gi;s/$r.\K./~$&/gi;

          # swap case, so lower sorts before upper
          # also, get rid of space, hyphen, and newline
          s/(\p{Ll}*)(\w?)\s*-*/\U$1\L$2/g;

          $c=$_;                # L3: Case

          $b=$_=NFD lc;         # L2: Diacritics

          # transform öő|üű so they sort correctly
          # ignore diacritics (acute) at this level
          y/\x{308}\x{30b}\x{301}/~~/d;

                                # L1: Base characters
          join$;,$_,$b,$c,$d
  }<>

†. Alcuni noti algoritmi di confronto multilivello sono Unicode Collation Algorithm (UCA, Unicode UTS # 10) , ISO 14651 (disponibile sul sito ISO ITTF ) LC_COLLATE parti su ISO TR 30112 (bozza disponibile su ISO / IEC JTC1 / SC35 / WG5 home ) che oscura ISO / IEC TR 14652 (disponibile nella ISO / IEC JTC1 / SC22 / WG20 home ) e LC_COLLATE in POSIX.

‡. Fare questo correttamente richiederebbe un dizionario. La terapia intensiva considera i gruppi stranamente capitalizzati come non contrazioni / non digrafi / non trigrafi, ad esempio: ccS < 3 CcS < 3 c Cs < 3 c CS < 3 C Cs < 3 cS < 3 cs < 3 Cs < 3 CS < 3 cc < 3 cc < 3 CCS


Dovresti essere in grado di salvare alcuni byte usando la mia espansione RegExp.
TheConstructor

6

Java 8, 742 byte

Potrebbe ridurre di altri 3 byte denominando la funzione sanziché sorto altri 16 byte se non si considera la definizione di classe.

public class H{String d="cs|dzs?|gy|ly|sz|ty|zs";void sort(java.util.List<String>l){l.sort((a,b)->{String o="-a-á-b-cs-dzs-e-é-f-gy-h-i-í-j-k-ly-m-ny-o-ó-ö-ő-p-q-r-sz-ty-u-ú-ü-ű-v-w-x-y-zs-";int i=c(r(a),r(b),r(o));return i!=0?i:(i=c(a,b,o))!=0?i:b.charAt(0)-a.charAt(0);});}String r(String a){for(int i=0;i<8;i++)a=a.toLowerCase().replace("ááéíóőúű".charAt(i),"aaeioöuü".charAt(i));return a;}int c(String a,String b,String o){a=n(a);b=n(b);while(!"".equals(a+b)){int i=p(a,o),j=p(b,o);if(i!=j)return i-j;a=a.substring(i%4);b=b.substring(j%4);}return 0;}int p(String a,String o){a=(a+1).replaceAll("("+d+"|.).*","-$1");return o.indexOf(a)*4+a.length()-1;}String n(String a){return a.toLowerCase().replaceAll("(.)(?=\\1)("+d+")| |-","$2$2");}}

Può essere usato in questo modo:

new H().sort(list);

Test-Suite:

public static void main(String[] args) {
    test(Arrays.asList("cudar", "cukor", "cuppant", "csalit", "csata"));
    test(Arrays.asList("kasza", "kaszinó", "kassza", "kaszt", "nagy", "naggyá", "nagygyakorlat", "naggyal",
            "nagyít"));
    test(Arrays.asList("jácint", "Jácint", "Zoltán", "zongora"));
    test(Arrays.asList("Eger", "egér", "író", "iroda", "irónia", "kerek", "kerék", "kérek", "szúr", "szül"));
    test(Arrays.asList("márvány", "márványkő", "márvány sírkő", "Márvány-tenger", "márványtömb"));
}

private static void test(final List<String> input) {
    final ArrayList<String> random = randomize(input);
    System.out.print(input + " -> " + random);
    new H().sort(random);
    System.out.println(" -> " + random + " -> " + input.equals(random));
}

private static ArrayList<String> randomize(final List<String> input) {
    final ArrayList<String> temp = new ArrayList<>(input);
    final ArrayList<String> randomOrder = new ArrayList<>(input.size());
    final Random r = new Random();
    for (int i = 0; i < input.size(); i++) {
        randomOrder.add(temp.remove(r.nextInt(temp.size())));
    }
    return randomOrder;
}

cedevole

[cudar, cukor, cuppant, csalit, csata] -> [csata, cudar, cuppant, csalit, cukor] -> [cudar, cukor, cuppant, csalit, csata] -> true
[kasza, kaszinó, kassza, kaszt, nagy, naggyá, nagygyakorlat, naggyal, nagyít] -> [naggyá, kassza, kaszinó, nagygyakorlat, nagyít, nagy, kaszt, kasza, naggyal] -> [kasza, kaszinó, kassza, kaszt, nagy, naggyá, nagygyakorlat, naggyal, nagyít] -> true
[jácint, Jácint, Zoltán, zongora] -> [Zoltán, jácint, zongora, Jácint] -> [jácint, Jácint, Zoltán, zongora] -> true
[Eger, egér, író, iroda, irónia, kerek, kerék, kérek, szúr, szül] -> [egér, Eger, kerék, iroda, író, kerek, kérek, szúr, irónia, szül] -> [Eger, egér, író, iroda, irónia, kerek, kerék, kérek, szúr, szül] -> true
[márvány, márványkő, márvány sírkő, Márvány-tenger, márványtömb] -> [márványtömb, márványkő, Márvány-tenger, márvány sírkő, márvány] -> [márvány, márványkő, márvány sírkő, Márvány-tenger, márványtömb] -> true

Ungolfed:

public class HungarianOrder {

    String d = "cs|dzs?|gy|ly|sz|ty|zs";

    void sort(java.util.List<String> l) {
        l.sort((a, b) -> {
            String o = "-a-á-b-cs-dzs-e-é-f-gy-h-i-í-j-k-ly-m-ny-o-ó-ö-ő-p-q-r-sz-ty-u-ú-ü-ű-v-w-x-y-zs-";
            int i = c(r(a), r(b), r(o));
            return i != 0 ? i
                    : (i = c(a, b, o)) != 0 ? i
                            : b.charAt(0) - a.charAt(0);
        });
    }

    // toLower + remove long accent
    String r(String a) {
        for (int i = 0; i < 8; i++)
            a = a.toLowerCase().replace("ááéíóőúű".charAt(i), "aaeioöuü".charAt(i));
        return a;
    }

    // iterate over a and b comparing positions of chars in o
    int c(String a, String b, String o) {
        a = n(a);
        b = n(b);
        while (!"".equals(a + b)) {
            int i = p(a, o), j = p(b, o);
            if (i != j)
                return i - j;
            a = a.substring(i % 4);
            b = b.substring(j % 4);
        }
        return 0;
    }

    // find index in o, then looking if following characters match
    // return is index * 4 + length of match; if String is empty or first character is unknown -1 is returned
    int p(String a, String o) {
        a = (a+1).replaceAll("("+d+"|.).*", "-$1");
        return o.indexOf(a) * 4 + a.length() - 1;
    }

    // expand ddz -> dzdz and such
    String n(String a) {
        return a.toLowerCase().replaceAll("(.)(?=\\1)("+ d +")| |-", "$2$2");
    }
}

Sto usando il Listtipo di Java e la order()sua funzione, ma il comparatore è tutto mio.


Degno di nota! Immagino che dovresti essere in grado di eliminare l'identificatore del tipo di elenco <String>e salvare alcuni caratteri al costo di alcuni avvisi?
Josh

@Josh nah, produrrebbe due cast come Java avrebbe dedotto Objectcome tipo di aeb. Probabilmente potrei comunque scappare definendo un parametro di classe generico che si estende String. Inoltre non mi aspetto di avere il codice più breve. ;-)
TheConstructor l'

3

Python 3, 70

Risparmiato 8 byte grazie a shooqie.

Adoro Python. : D

Si aspetta un elenco di stringhe.

from locale import*;setlocale(0,'hu')
f=lambda x:sorted(x,key=strxfrm)

3
Non è una scappatoia standard?
vsz

1
@vsz Non per quanto ne so. L'uso dei built-in fa parte di molte sfide.
Morgan Thrapp,

1
@vsz Ha un rapporto troppo basso verso l'alto o il basso sul post delle lacune standard per essere conteggiato come standard, dovresti vietarlo esplicitamente.
FryAmTheEggman,

1
Ok, fatto. Ho considerato di vietarlo esplicitamente, ma ho pensato che sarebbe ovvio che avrebbe reso l'intera sfida un punto controverso. Mi dispiace per l'inconveniente.
vsz

1
from locale import*salva un sacco di byte
shooqie
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.