Macar alfabetik sırası


19

Eski İspanyol alfabetik düzeninden çok daha fazla meydan okuma isteyenler için , Macar alfabesinin nasıl sıralandığına bir göz atalım.

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

Aslında q, w, xve yMacar deyişle kullanılmaz, ancak loanwords ve yabancı isimler için dahil edilir. Macar alfabesinin bir parçası olmayan (örneğin ñ) yabancı aksanlı karakterler , aksanlı olmayanlarla aynı önceliğe sahiptir, ancak bu meydan okuma için onları dikkate almayız.

Özetlenen kurallar:

  • Digraflar ( cs, szvb.) Ve trigraf ( ) dzskendi başlarına harf olarak kabul edilir.
cudar
cukor
cuppant
csalit
csata
  • Aynı digraph veya sesli üç harf bir kelime birbiri ardından iki kez doğrudan oluşursa, bunlar basitleştirilmiş şekilde yazılır sszyerine szsz, ddzsyerine dzsdzsancak alfabetik olmayan basitleştirilmiş düzen kullanılır. Örneğin kasza< kaszinó< kassza, çünkü kasszaolarak kullanılır k+ a+ sz+ sz+ asipariş uğruna. Bazen sözleşmesiz versiyonu bir kelimede, bileşik kelimeler durumunda bulabilirsiniz.
kasza
kaszinó
kassza
kaszt
nagy
naggyá
nagygyakorlat
naggyal
nagyít
  • iki sözcüğün büyük harf kullanımı olmadan tam olarak aynı olacağı durumlar hariç, büyük harf kullanımı önemli değildir, bu durumda küçük harf önceliklidir
jácint
Jácint
Zoltán
zongora
  • Aksanlı ünlülerin kısa ve uzun sürümleri aynı önceliğe sahip ( a - á, e -é, i - í, o - ó, ö - ő, u - ú ü - ű), tek istisna ile: iki kelime aksi tamamen aynı olurdu, kısa ünlü uzun sesli göre önceliği vardır. Not üstten çift noktalı (ile sesliler olduğunu öve ü) tamamen farklı karakterleridir ove u.
Eger
egér
író
iroda
irónia
kerek
kerék
kérek
szúr
szül
  • Kısa çizgiler veya boşluklar (örneğin, bileşik sözcüklerde, adlarda vb.) Tamamen yok sayılır
márvány
márványkő
márvány sírkő
Márvány-tenger
márványtömb

Görev

Programınız / işleviniz Macar alfabesinden (hem küçük hem de büyük harf) karakterlerden oluşan dizeler alır, ancak bir dize boşluk veya kısa çizgi içerebilir. Kolaylık olması açısından, eksi işareti (ASCII 45) kısa çizgi olarak kullanılabilir. Bazı karakterlerin (gibi ő) ASCII'nin bir parçası olmadığını unutmayın. Gerekli tüm karakterleri destekliyorsa, istediğiniz herhangi bir kodlamayı kullanabilirsiniz.

Hatları doğru şekilde sipariş etmeniz ve sonucu görüntülemeniz / geri göndermeniz gerekir.

Test için yukarıdaki örneklerin herhangi bir rastgele sıralı alt kümesini kullanabilirsiniz.

DÜZENLE:

Lütfen Macarca alfabetik sıralamayı zaten bilen yerleşik veya başka bir yol kullanmayın. Rekabeti anlamsız kılacak ve en iyi düzenli ifadeyi veya en iyi kod golf hilelerini bulmaktan tüm zorluğu alacaktı.

EDIT2:

Bir açıklama temizlemek için isaacg tarafından sorulan: "Her iki yönden iki yalnızca kısa sesli harflerin vs uzun harf farklılık ve dizeleri, ancak farklılık": hiçbir kural olmasına rağmen resmi belgede açıkça bu konuya değinmekte, bir örnek uzunluğuna puan içinde bulunan ünlü harflerin büyük harflerden daha önemli olduğunu gösterir.


@FryAmTheEggman Bunu nerede görüyorsun?
Morgan Thrapp

9
Adam, ben bile doğru alfabetik sırasını ezberlemek olamaz. Bunu nasıl programlayacağım? ;)
Andras Deak

1
Görünür bir digrafinin aslında iki harf olduğu malacsültveya başarısız olduğu bir count-fail counterexample bulmaya çalışıyorum nyílászáró. Acaba var mı (ama bunu kontrol etmek için bir kelime dağarcığına ihtiyacınız var, ki bu muhtemelen bu zorluğun bir parçası değil)
Andras Deak

1
Dzs içeren bir örnek yok
TheConstructor 11:16

Yanıtlar:


4

Perl, 250

İçin +11 içerir -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}<>

Kullanımları süslemeleri-sort-undecorate deyim (AKA Schwartzian Transform ) ve düzeyli sıralamayı düzeyi vardır:

  • L1: temel harfleri karşılaştırın, aksanları, durumu ve bazı noktalama işaretlerini yoksayın.
  • L2: temel harfleri ve aksanları karşılaştırır, büyük / küçük harfleri ve bazı noktalama işaretlerini yok sayar.
  • L3: baz harfleri, aksanları ve durumu karşılaştırır, bazı noktalama işaretlerini yok sayar.
  • Ln: bağ bozucu bayt seviyesi karşılaştırması.

Dahili olarak, (ASCII 0x1C Alan Ayırıcı - değeri bu meydan okuma için alfabedeki herhangi bir karakterden daha az olan) bir seviye ayırıcı olarak kullanılır.

Bu uygulamanın aralarında birçok sınırlaması vardır:

  • Yabancı karakterler için destek yok.
  • Sözleşmeli geminated (uzun) digraphs / üç karakterli ve ünsüz arasındaki belirsizliği değil + digraph / sesli üç harf, örneğin Can: könnyű olarak harmanlamak gerekir <k> <ö> <ny> <ny> <u> iken tizennyolc olarak harmanlamak gerekir <t> < i> <z> <n> <ny> <o> <l> <c> ; házszám 'address = ev (ház) numarası (szám)', <h><á><z><sz><á> <m> olarak ve * <h><á><zs> <z> olarak harmanlanmalıdır. <m> .
  • Anlaşmalı uzun digraflar için harmanlama tutarlı değildir (ancak stabildir): aynı seviyede belirsizleşiyoruz ( ssz < n szsz, ..., zszs < n zzs ); glibc kısa formları tam formlardan önce toplar ( ssz <szsz, ..., zzs <zszs ), YBÜ uzun formları L3 Case ve Variants'dan başlayarak kısa formlardan önce toplar ( szsz < 3 ssz , ..., zszs < 3 zzs )

Genişletilmiş sürüm:

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
  }<>

†. Bazı iyi bilinen çok seviyeli harmanlama algoritmaları, Unicode Harmanlama Algoritması (UCA, Unicode UTS # 10) , ISO 14651 ( ISO ITTF sitesinde mevcuttur ) ISO_30LL12'de LC_COLLATE parçalarıdır ( ISO / IEC JTC1 / SC35 / ÇG5 ev de ISO / IEC TR 14652 (mevcut obsoletes) , ISO / IEC JTC1 / SC22 / WG20 evde POSIX at) ve LC_COLLATE.

‡. Bunu doğru yapmak bir sözlük gerektirir. YBÜ tuhaf şekilde büyük harfle yazılmış gruplara kasılma / digraf olmayan / trigraf olmayan gibi davranır, örn: ccS < 3 CcS < 3 c Cs < 3 c CS < 3 C Cs < 3 cS < 3 cs < 3 Cs < 3 CS < 3 ccs < 3 Ccs < 3 CCS


Benim genişleme RegExp kullanarak bazı bayt kaydedebilmeniz gerekir.
Yapımcı

6

Java 8, 742 bayt

Sınıf tanımı sayılmazsa , işlevi syerine başka bir 3 bayt sortveya 16 bayt azaltabilir .

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");}}

Bu şekilde kullanılabilir:

new H().sort(list);

Test odası:

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;
}

verimli

[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");
    }
}

Java'nın Listtürünü ve order()işlevini kullanıyorum , ancak karşılaştırıcı tamamen benim.


Etkileyici! Liste türü belirleyicisini bırakabilmeniz ve <String>birkaç uyarının maliyetiyle birkaç karakteri kaydedebilmeniz gerektiğini düşünüyorum ?
Josh

@Josh nah, Java Objecto zaman a ve b türünü çıkardığı için iki döküm üretecekti . Muhtemelen bir class-generic-parametre genişletme tanımlayarak kurtulmak olabilir String. Ayrıca en kısa kod olmasını beklemiyorum. ;-)
TheConstructor 11:16

3

Python 3, 70

Shooqie sayesinde 8 bayt kurtardı.

Python'u seviyorum. : D

Dizelerin bir listesini bekler.

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

3
Bu standart bir boşluk değil mi?
vsz

1
@vsz Bildiğim kadarıyla değil. Yerleşik kullanımı birçok zorluğun bir parçasıdır.
Morgan Thrapp

1
@vsz Standart boşlukların standart olarak sayılması için yukarı-aşağı oy oranı çok düşüktür, bunu açıkça yasaklamanız gerekir.
FryAmTheEggman

1
Tamam, bitti. Açıkça yasaklamayı düşündüm, ancak tüm meydan okumayı tartışmalı bir nokta haline getireceği açık olsa da. Ben rahatsızlıktan dolayı özür dilerim.
vsz

1
from locale import*bayt çok kaydeder
shooqie
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.