ハンガリー語のアルファベット順


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

実際には、qwxおよびyハンガリー語の単語で使用されていないが、彼らは外来語と外国名に含まれています。ハンガリー語のアルファベットの一部ではない外国語のアクセント付き文字(などñ)は、アクセントなしの文字と同じ優先順位を持っていますが、この課題については無視します。

要約されたルール:

  • ダイグラフ(csszなど)およびトリグラフ(dzs)は、それ自体が文字であると見なされます。
cudar
cukor
cuppant
csalit
csata
  • :同じ有向グラフまたはトリグラフは言葉でお互いの直後に2回出現する場合、それらは簡略化された方法で書かれているssz代わりにszszddzs代わりのdzsdzsが、非単純化順序が使用されているアルファベット順のため。例えばkasza、< kaszinó、< kassza、ためkasszaとして使用されるk+ a+ sz+ sz+ a発注のために。複合語の場合、単語で非契約バージョンを見つけることができます。
kasza
kaszinó
kassza
kaszt
nagy
naggyá
nagygyakorlat
naggyal
nagyít
  • 大文字化は問題ではありませんが、大文字化しないと2つの単語がまったく同じになる場合は例外です。
jácint
Jácint
Zoltán
zongora
  • アクセント母音の短い及び長いバージョンが同じ優先度を有する(a - áe -éi - ío - óö - őu - ú ü - ű)、単一の例外を除いて2つの単語が他とまったく同じであるならば、短母音は長母音優先を有します。ウムラウト(öおよびü)を持つ母音は、oおよびから完全に異なる文字であることに注意してくださいu
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からの説明をクリアするには:「大文字と長母音のみが異なり、両方の点で異なる2つの文字列」:公式文書のこの質問に明示的に対処する規則はありませんが、長さを指す例が見つかりました母音は大文字よりも重要です。


@FryAmTheEggmanどこで見ますか?
モーガンスラップ

9
男、たちの適切なアルファベット順を暗記することさえできません。これをどのようにプログラムしますか?;)
アンドラスディーク

1
私は明白な有向グラフが実際のような二文字、あるバインド・ツー・失敗反例、思い付くしようとしてきましたmalacsültnyílászáró。何かありますか(しかし、それを確認するには語彙が必要です。これはおそらくこの課題の一部ではありません)
アンドラス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 シュワルツ変換)、およびマルチレベルソートレベルがあり、:

  • L1:ベース文字を比較し、発音区別符号、大文字小文字、句読点を無視します。
  • L2:ベース文字と発音区別記号を比較し、大文字と小文字の区切りを無視します。
  • L3:ベース文字、発音区別記号、大文字小文字を比較し、句読点を無視します。
  • Ln:タイブレークのバイトレベル比較。

内部的には、(ASCII 0x1Cフィールドセパレーター—値はこのチャレンジのアルファベットのどの文字よりも小さい)レベルセパレーターとして使用されます。

この実装には、次のような多くの制限があります。

  • 外国文字はサポートされていません。
  • 契約geminated(ロング)有向グラフ/トライグラフ、および子音の間に明確ではない+有向グラフ/トリグラフは、例えばすることができます:könnyűはと照合する必要があります<K> <ö> <NY> <NY> <U> 、一方でtizennyolcはと照合すべき<T> < i> <z> <e> <n> <ny> <o> <l> <c> ; házszám 'address = house(ház)number(szám)'は、* <h> <á> <zs> <z>ではなく、<h> <á> <z> <sz> <á> <m>として照合する必要があります<á> <m>
  • 契約の長い二重字の照合順序が(それは安定している)が一貫していない:私たちは同じレベルで明確に(SSZ < N szsz、...、zszs < N zzs)。glibcは、フルフォーム(ssz <szsz、...、zzs <zszs)の前に短いフォームを照合します。ICUは、 L3 Case and Variantsszsz < 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 Collat​​ion Algorithm(UCA、Unicode UTS#10)、ISO 14651(ISO ITTFサイトで入手可能)、ISO TR 30112のLC_COLLATEパーツ(ISO / IEC JTC1 /で入手可能なドラフト)SC35 / WG5 home)これは、ISO / IEC TR 14652(ISO / IEC JTC1 / SC22 / WG20 homeで利用可能)およびPOSIXのLC_COLLATE を廃止します。

‡。これを正しく行うには辞書が必要です。ICUは、奇妙に大文字化されたグループを非収縮/非有向グラフ/非三重グラフとして扱います。例: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


私の拡張RegExpを使用して、いくつかのバイトを保存できるはずです。
TheConstructor

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

ゴルフをしていない:

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のList-typeとorder()-functionを使用していますが、コンパレータはすべて私のものです。


印象的!リストタイプ指定子をドロップして<String>、いくつかの警告を犠牲にして数文字を保存できるはずだと思いますか?
ジョシュ

@Josh nah、JavaがObjectaおよびbのタイプとして推測するので、2つのキャストを生成します。Stringただし、クラス汎用パラメーター拡張を定義することはおそらく避けられます。また、私は最短のコードを持つことを期待していません。;-)
TheConstructor

3

Python 3、70

shooqieのおかげで8バイト節約されました。

私はPythonが大好きです。:D

文字列のリストが必要です。

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

3
これは標準的な抜け穴ではありませんか?
-vsz

1
@vsz私の知る限りではない。組み込みの使用は、多くの課題の一部です。
モーガンスラップ

1
@vsz標準の抜け穴投稿の投票率が低すぎて標準としてカウントされないため、明示的に禁止する必要があります。
FryAmTheEggman

1
了解しました。私は明示的にそれを禁止することを検討しましたが、私はそれが挑戦全体を論争点にすることは明らかであるべきですが。ご不便をおかけして申し訳ありません。
VSZ

1
from locale import*多くのバイトを節約
shooqie
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.