ลำดับตัวอักษรฮังการี


19

สำหรับผู้ที่ต้องการความท้าทายมากขึ้นจากนั้นตามลำดับตัวอักษรภาษาสเปนเก่าลองมาดูกันว่าตัวอักษรฮังการีได้รับคำสั่งอย่างไร

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

จริงq, w, xและyไม่ได้ใช้ในคำฮังการี แต่พวกเขาจะรวมคำยืมและชื่อต่างประเทศ อักขระที่เน้นเสียงต่างประเทศซึ่งไม่ได้เป็นส่วนหนึ่งของตัวอักษรฮังการี (เหมือนñ) มีลำดับความสำคัญเท่ากันกับอักขระที่ไม่เน้นเสียง แต่เราไม่สนใจพวกเขาสำหรับความท้าทายนี้

กฎสรุป:

  • Digraphs ( cs,, szฯลฯ ) และ trigraph ( dzs) ถือเป็นตัวอักษรด้วยตนเอง
cudar
cukor
cuppant
csalit
csata
  • ถ้าเดี่ยวเดียวกันหรือ trigraph เกิดขึ้นสองครั้งโดยตรงหลังจากแต่ละอื่น ๆ ในคำที่พวกเขาจะเขียนในทางที่ง่าย: sszแทนszsz, ddzsแทนdzsdzsแต่สำหรับลำดับตัวอักษรคำสั่งที่ไม่ง่ายที่จะใช้ ตัวอย่างเช่นkasza< kaszinó< kasszaเพราะkasszaจะใช้เป็นk+ a+ sz+ sz+ aเพื่อประโยชน์ในการสั่งซื้อ บางครั้งคุณสามารถค้นหารุ่นที่ไม่ได้ทำสัญญาในคำในกรณีของคำประสม
kasza
kaszinó
kassza
kaszt
nagy
naggyá
nagygyakorlat
naggyal
nagyít
  • การใช้อักษรตัวพิมพ์ใหญ่ไม่สำคัญยกเว้นว่าคำสองคำจะเหมือนกันทุกประการโดยไม่ต้องใช้อักษรตัวพิมพ์ใหญ่ในกรณีใดอักษรตัวพิมพ์เล็กจะมีความสำคัญ
jácint
Jácint
Zoltán
zongora
  • รุ่นสั้นและระยะยาวของสระสำเนียงมีความสำคัญเดียวกัน ( a - á, e -é, i - í, o - ó, ö - ő, u - ú ü - ű) โดยมีข้อยกเว้นเดียว: ถ้าคำสองคำนี้มิฉะนั้นจะเหมือนกันที่สระเสียงสั้นจะมีความสำคัญมากกว่าสระเสียงยาว ทราบว่าสระที่มีเครื่องหมาย ( öและü) เป็นตัวละครที่แตกต่างอย่างสิ้นเชิงจากและou
Eger
egér
író
iroda
irónia
kerek
kerék
kérek
szúr
szül
  • เครื่องหมายขีดกลางหรือช่องว่าง (ตัวอย่างเช่นในคำประสมชื่อ ฯลฯ ) จะถูกละเว้นอย่างสมบูรณ์
márvány
márványkő
márvány sírkő
Márvány-tenger
márványtömb

งาน

โปรแกรม / ฟังก์ชั่นของคุณได้รับสตริงซึ่งประกอบด้วยอักขระจากตัวอักษรฮังการี (ทั้งตัวพิมพ์เล็กและตัวพิมพ์ใหญ่) แต่สตริงอาจมีช่องว่างหรือยัติภังค์ เพื่อความเรียบง่ายสัญลักษณ์ลบ (ASCII 45) สามารถใช้เป็นเครื่องหมายยัติภังค์ โปรดทราบว่าตัวละครบางตัว (เช่นő) ไม่ได้เป็นส่วนหนึ่งของ ASCII คุณสามารถใช้การเข้ารหัสใด ๆ ที่คุณต้องการหากรองรับอักขระที่ต้องการทั้งหมด

คุณต้องเรียงลำดับบรรทัดอย่างถูกต้องและแสดง / คืนผลลัพธ์

คุณสามารถใช้ชุดย่อยที่สุ่มตามตัวอย่างด้านบนเพื่อทำการทดสอบ

แก้ไข:

โปรดอย่าใช้วิธีการในตัวหรือวิธีอื่นใดที่ทราบถึงการเรียงลำดับตัวอักษรฮังการีด้วยตัวเอง มันจะทำให้การแข่งขันไม่มีจุดหมายและรับความท้าทายทั้งหมดจากการค้นหานิพจน์ปกติที่ดีที่สุดหรือเทคนิคการตีกอล์ฟที่ดีที่สุด

EDIT2:

เมื่อต้องการล้างการชี้แจงที่ถามโดย isaacg: "สองสตริงที่แตกต่างกันเพียงการใช้อักษรตัวใหญ่และเสียงสระยาวกับเสียงสระสั้น แต่แตกต่างกันในทั้งสองวิธี": แม้ว่าจะไม่มีกฎในเอกสารทางราชการตอบคำถามนี้อย่างชัดเจน ของเสียงสระมีความสำคัญมากกว่าตัวพิมพ์ใหญ่


@FryAmTheEggman คุณเห็นที่ไหน
Morgan Thrapp

9
ผู้ชายฉันไม่สามารถจำลำดับตัวอักษรที่เหมาะสมของเราได้ ฉันจะเขียนโปรแกรมนี้ได้อย่างไร ;)
Andras Deak

1
ฉันได้รับการพยายามที่จะเกิดขึ้นกับการที่ถูกผูกไว้เพื่อล้มเหลว counterexample ที่เดี่ยวชัดเจนเป็นจริงตัวอักษรสองตัวเช่นหรือmalacsült nyílászáróฉันสงสัยว่ามีหรือไม่ (แต่คุณต้องการคำศัพท์เพื่อตรวจสอบซึ่งสันนิษฐานว่าไม่ได้เป็นส่วนหนึ่งของความท้าทายนี้)
Andras Deak

1
ไม่มีตัวอย่างที่มี dzs
TheConstructor

คำตอบ:


4

Perl, 250

รวม 11 -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}<>

ใช้ตกแต่ง-เรียง undecorateสำนวน (AKA Schwartzian Transform ) และหลายเรียงลำดับที่ระดับคือ:

  • L1: เปรียบเทียบตัวอักษรฐานละเว้นเครื่องหมายกำกับออกเสียงตัวพิมพ์เล็กและใหญ่และเครื่องหมายวรรคตอน
  • L2: เปรียบเทียบตัวอักษรฐานและการกำกับออกเสียงละเว้นตัวพิมพ์ใหญ่และเครื่องหมายวรรคตอน
  • L3: เปรียบเทียบตัวอักษรฐานการกำกับเสียงและตัวพิมพ์เล็กละเว้นเครื่องหมายวรรคตอน
  • Ln: การเปรียบเทียบระดับไบต์แบบแยกย่อย

ภายใน(ASCII 0x1C ตัวคั่นฟิลด์ - ซึ่งมีค่าน้อยกว่าอักขระใด ๆ ในตัวอักษรสำหรับความท้าทายนี้) ใช้เป็นตัวคั่นระดับ

การใช้งานนี้มีข้อ จำกัด มากมายในหมู่พวกเขา:

  • ไม่รองรับอักขระต่างประเทศ
  • ไม่สามารถแยกแยะความแตกต่างระหว่าง digraphs / trigraphs ที่ยาว (ยาว) และตัวพยัญชนะ + digraph / trigraph เช่น: könnyűควรเรียงเป็น<k><ö><ny> <ny> <ű>ในขณะที่tizennyolcควรเรียงเป็น<t> < i> <z> <e> <n> <ny> <o> <l> <c> ; házszám 'address = house (ház) number (sáám)' ควรจัดเรียงเป็น<h><á><z><sz><á> <m>และไม่ใช่ as * <h><á><zs> <z> <a> <ม>
  • การจัดเรียงสำหรับ digraphs ที่มีสัญญายาวนั้นไม่สอดคล้องกัน (แต่มั่นคง): เราแก้ปัญหาในระดับเดียวกัน ( ssz < n szsz, ... , zszs < n zzs ); glibc collates แบบสั้นก่อนแบบเต็ม ( ssz <szsz, ... , zzs <zszs ), ICU ตรวจสอบรูปแบบยาวก่อนที่รูปแบบสั้นเริ่มต้นที่ L3 Case และ Variants ( szsz < 3 ssz, ... , zszs < 3 zzs )

รุ่นขยาย:

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

† อัลกอริทึมการเรียงหลายระดับที่รู้จักกันดีคืออัลกอริธึมการเรียง Unicode (UCA, Unicode UTS # 10) , ISO 14651 (มีให้ที่ไซต์ ISO ITTF ) ชิ้นส่วน LC_COLLATE ที่ ISO TR 30112 (ร่างที่ISO / IEC JTC1 SC35 / WG5 home ) ซึ่งเลิกใช้ ISO / IEC TR 14652 (มีให้ที่บ้านISO / IEC JTC1 / SC22 / WG20 ) และ LC_COLLATE ที่ POSIX

‡ การทำเช่นนี้ถูกต้องจะต้องใช้พจนานุกรม ถือว่า ICU วิจิตรพิสดารกลุ่มทุนเป็นที่ไม่ใช่การหดตัว / ไม่ใช่ digraphs-/ ไม่ใช่ trigraphs-เช่น: CCS < 3 CCS < 3Cs < 3CS < 3 C Cs < 3 Cs < 3 cs < 3 Cs < 3 CS < 3 ccs < 3 Ccs < 3 CCS


คุณควรจะสามารถบันทึกไบต์โดยใช้ RegExp ส่วนขยายของฉัน
สร้าง

6

Java 8, 742 ไบต์

สามารถลดขนาดได้อีก 3 ไบต์การตั้งชื่อฟังก์ชั่นsแทนsortหรืออีก 16 ไบต์ถ้าไม่นับคำจำกัดความของคลาส

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

สามารถใช้สิ่งนี้:

new H().sort(list);

การทดสอบในตัว:

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

ยอมให้

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

ฉันใช้จาวาList- ประเภทและorder()ฟังก์ชั่นของมัน แต่ตัวเปรียบเทียบเป็นของฉันทั้งหมด


ที่น่าประทับใจ! ฉันคิดว่าคุณน่าจะสามารถวางตัวระบุชนิดรายการ<String>และบันทึกอักขระสองสามตัวที่ค่าใช้จ่ายของคำเตือนบางอย่างได้หรือไม่
Josh

@Josh nah มันจะสร้างสอง casts โดย Java จะอนุมานObjectว่าเป็นประเภท a และ b แล้ว ฉันอาจจะได้ออกไปกำหนดพารามิเตอร์ class-generic- การขยายStringแม้ว่า นอกจากนี้ฉันไม่ได้คาดหวังว่าจะมีรหัสสั้นที่สุด ;-)
TheConstructor

3

Python 3, 70

บันทึก 8 ไบต์ด้วย shooqie

ฉันรักหลาม : D

คาดหวังรายการของสตริง

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

3
นี่ไม่ใช่ช่องโหว่มาตรฐานใช่หรือไม่
vsz

1
@ vsz ไม่เท่าที่ฉันรู้ การใช้บิวด์อินเป็นส่วนหนึ่งของความท้าทายมากมาย
Morgan Thrapp

1
@ vsz มันมีอัตราส่วนขึ้น - ลง - ลงต่ำเกินไปในช่องโหว่มาตรฐานที่จะนับเป็นมาตรฐานคุณจะต้องแบนอย่างชัดเจน
FryAmTheEggman

1
ตกลงทำมัน ฉันพิจารณาห้ามอย่างชัดเจน แต่ฉันคิดว่ามันควรจะชัดเจนว่ามันจะทำให้ความท้าทายทั้งหมดเป็นจุดที่สงสัย ฉันขอโทษสำหรับความไม่สะดวก.
vsz

1
from locale import*บันทึกจำนวนมากไบต์
shooqie
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.