Codegolf - Венгерский Алфавитный Порядок

  • Автор темы OKN
  • Обновлено
  • 22, Oct 2024
  • #1

Для тех, кто хочет большего, чем старый испанский алфавитный порядок, давайте посмотрим, как устроен венгерский алфавит.

а, а, б, в, кс, г, дз, дзс, е, е, е, г, гы, ч, и, ?, к, к, л, лы, м, н, нй, о, о, ö, ő, p, q, r, s, sz, t, ty, u, ú, ü, ű, v, w, x, y, z, zs

на самом деле,

 
 
 
 
 ő 
, márvány márványkő márvány s?rkő Márvány-tenger márványtömb , Eger egér ?ró iroda irónia kerek kerék kérek szúr szül и u не используются в венгерских словах, но включены в заимствованные слова и иностранные имена. Символы с иностранным акцентом, которые не являются частью венгерского алфавита (например, o ), have the same priority as the non-accented ones, but we disregard them for this challenge.

Краткое изложение правил:

  • Диграфы ( ü , ö и т. д.) и триграф ( ü - ű ) are considered as they were letters on their own.
u - ú
  • Если один и тот же орграф или триграф встречается в слове дважды непосредственно друг за другом, они пишутся упрощенно: ö - ő instead of o - ó , i - ? instead of e -é но для алфавитного порядка используется неупрощенный порядок. Например a - á < jácint Jácint Zoltán zongora < kasza kaszinó kassza kaszt nagy naggyá nagygyakorlat naggyal nagy?t , because a используется как sz + sz + a + k + kassza for the sake of ordering. Sometimes you can find the non-contracted version in a word, in case of compound words.
kassza
  • заглавная буква не имеет значения, за исключением случаев, когда два слова были бы совершенно одинаковыми без заглавной буквы, и в этом случае строчная буква имеет приоритет.
kaszinó
  • Краткие и длинные варианты ударных гласных имеют одинаковый приоритет ( kasza , dzsdzs , ddzs , szsz , ssz , cudar cukor cuppant csalit csata dzs ), with a single exception: if the two words would otherwise be exactly the same, the short vowel has priority over the long vowel. Note, that the vowels with umlaut ( sz и cs ) are completely different characters from ñ and y .
x
  • Дефисы или пробелы (например, в составных словах, именах и т.п.) полностью игнорируются.
w

Задача

Ваша программа/функция получает строки, состоящие из символов венгерского алфавита (как нижнего, так и верхнего регистра), но строка может содержать пробелы или дефисы. Для простоты знак минус (ASCII 45) можно использовать в качестве дефиса. Обратите внимание, что некоторые символы (например, q ) are not part of ASCII. You can use any encoding you wish, if it supports all the required characters.

Вам необходимо правильно упорядочить строки и отобразить/вернуть результат.

Для тестирования вы можете использовать любое случайно упорядоченное подмножество приведенных выше примеров.

РЕДАКТИРОВАТЬ:

Пожалуйста, не используйте встроенные или другие средства, которые сами по себе знают венгерский алфавитный порядок. Это сделало бы соревнование бессмысленным и лишило бы всех задач поиска лучшего регулярного выражения или лучшего кода для игры в гольф.

РЕДАКТИРОВАТЬ2:

Чтобы прояснить уточнение, заданное isaacg: «две строки, которые различаются только заглавными буквами и длинными и короткими гласными, но различаются в обоих направлениях»: хотя в официальный документ явно отвечает на этот вопрос: пример, найденный внутри, указывает на то, что длина гласной имеет большее значение, чем капитализация.

#код-гольф #строка #сортировка

OKN


Рег
22 Jul, 2007

Тем
74

Постов
206

Баллов
626
  • 26, Oct 2024
  • #2

Java 8, 742 байта

Можно сократить еще на 3 байта имя функции

 
 
 
 
 
 
 
 from locale import*;setlocale(0,'hu')
f=lambda x:sorted(x,key=strxfrm)
 
instead of 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 }<> или еще 16 байт, если не считать определения класса.

Можно использовать следующим образом:

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

Тестовый набор:

-Mutf8 -CS

уступчивость

order()

Негольфед:

List

Я использую Java 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"); } } -type and the [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 -функция своя, но компаратор весь мой.

 

Sr19


Рег
02 Sep, 2006

Тем
78

Постов
204

Баллов
644
  • 26, Oct 2024
  • #3

Перл, 250

Включает +11 за 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; } .

new H().sort(list);

Использует украшать-сортировать-не украшать идиома (также известная как Преобразование Шварца) и многоуровневая сортировка, где уровни:

  • L1: сравнивать базовые буквы, игнорировать диакритические знаки, регистр и некоторые знаки препинания.
  • L2: сравнить основные буквы и диакритические знаки, игнорировать регистр и некоторые знаки препинания.
  • L3: сравните основные буквы, диакритические знаки и регистр, игнорируйте некоторые знаки препинания.
  • Ln: решающее сравнение на уровне байтов.

Внутренне, 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");}} (ASCII 0x1C Field Separator — whose value is less than any character in the alphabet for this challenge) is used as a level separator.

Эта реализация имеет множество ограничений, среди них:

  • Нет поддержки иностранных символов.
  • Невозможно устранить неоднозначность между сокращенными удвоенными (длинными) диграфами/триграфами и согласными + диграфами/триграфами, например: кённю следует сопоставить как <ö><ű>, пока тизенниолк следует сопоставить как ; хаззам «адрес = номер дома (ház) (szám)» следует сопоставлять как <á><á> и не так *<á><á>.
  • Сопоставление для сокращенных длинных орграфов не так последовательно (но оно стабильно): мы устраняем неоднозначность на одинаковом уровне (ссс <н сжш, ..., зшш <н ззз ); glibc сортирует короткие формы перед полными (ssz < szs, ..., zzs < zszs ), ICU сопоставляет длинные формы перед короткими формами, начиная с L3. Случай и варианты (сшш <3 ссз, ..., зссз <3 ззз )

Расширенная версия:

sort

†. Некоторые известные многоуровневые алгоритмы сопоставления: Алгоритм сопоставления Unicode (УЦА, Юникод UTS#10), ISO 14651 (доступен на сайте Сайт ИСО ИТТФ) части LC_COLLATE по ISO TR 30112 (проект доступен на сайте Главная страница ISO/IEC JTC1/SC35/WG5), который устарел ISO/IEC TR 14652 (доступен по адресу ISO/IEC JTC1/SC22/WG20 домашняя страница) и LC_COLLATE в POSIX.

‡. Чтобы сделать это правильно, потребуется словарь. ICU рассматривает группы со странным написанием заглавных букв как не-сокращения/не-орграфы/не-триграфы, например: ccS <3 CCS <3 сCs <3 сCS <3 СCs <3 cS <3 CS <3 Cs <3 CS <3 CCS <3 Копия <3 CCS

 

Lelemento


Рег
12 Jul, 2006

Тем
57

Постов
215

Баллов
510
  • 26, Oct 2024
  • #4

Питон 3, 70

Сэкономлено 8 байт благодаря shooqie.

Я люблю Питон. :D

Ожидает список строк.

s
 

Onpletmintsev


Рег
29 Mar, 2020

Тем
64

Постов
182

Баллов
512
Тем
403,760
Комментарии
400,028
Опыт
2,418,908
Lumtu.com © 2024