1. C++ / Говнокод #27025

    −1

    1. 1
    2. 2
    3. 3
    bool CheckRepeat(int cur, int i, char* word) {
    	return (word[cur] != '\0') ? ((word[i] != '\0') ? ((word[cur] == word[i] && cur != i) ? true : CheckRepeat(cur, i + 1, word)) : CheckRepeat(cur + 1, 0, word)) : false;
    }

    Функция проверки слова на повторение букв.
    Задали в институте лабу, в требование входили рекурсия и экономия строк, подпрограммы такого плана понравились преподавателю.

    Запостил: G0_G4, 13 Октября 2020

    Комментарии (185) RSS

    • показать все, что скрытоvanished
      Ответить
    • Давайте флудить и троллить!
      bool checkRepeatImpl(const char *prev, const char *cur)
      {
          return *cur && (*cur == *prev || checkRepeatImpl(prev + 1, cur + 1));
      }
      
      bool checkRepeat(const char *word)
      {
          return word && *word && checkRepeatImpl(word, word + 1);
      }
      
      int main()
      {
          std::cout << checkRepeat("") << std::endl      // 0
              << checkRepeat("a") << std::endl           // 0
              << checkRepeat("aa") << std::endl          // 1
              << checkRepeat("aaa") << std::endl         // 1
              << checkRepeat("bab") << std::endl         // 0
              << checkRepeat("baab") << std::endl        // 1
              << checkRepeat("bbaaabb") << std::endl     // 1
              << checkRepeat("bbabc") << std::endl       // 1
              << checkRepeat("abcbb") << std::endl;      // 1
      
          return EXIT_SUCCESS;
      }
      Ответить
      • https://gcc.godbolt.org/z/617WYe
        checkRepeatImpl(char const*, char const*):
                movzx   eax, BYTE PTR [rsi]
                xor     r8d, r8d
                test    al, al
                je      .L1
        .L3:
                cmp     BYTE PTR [rdi], al
                jne     .L11
        .L7:
                mov     r8d, 1
        .L1:
                mov     eax, r8d
                ret
        .L11:
                movzx   eax, BYTE PTR [rsi+1]
                test    al, al
                je      .L6
                cmp     al, BYTE PTR [rdi+1]
                je      .L7
                movzx   eax, BYTE PTR [rsi+2]
                add     rsi, 2
                add     rdi, 2
                test    al, al
                jne     .L3
        .L6:
                xor     r8d, r8d
                mov     eax, r8d
                ret
        checkRepeat(char const*):
                test    rdi, rdi
                je      .L26
                movzx   edx, BYTE PTR [rdi]
                test    dl, dl
                je      .L26
                movzx   ecx, BYTE PTR [rdi+1]
                test    cl, cl
                je      .L26
                mov     eax, 1
                cmp     dl, cl
                je      .L12
                movzx   edx, BYTE PTR [rdi+2]
                test    dl, dl
                je      .L26
                cmp     cl, dl
                je      .L12
                movzx   ecx, BYTE PTR [rdi+3]
                test    cl, cl
                je      .L26
                cmp     dl, cl
                je      .L12
                movzx   edx, BYTE PTR [rdi+4]
                test    dl, dl
                je      .L26
                cmp     cl, dl
                je      .L12
                movzx   ecx, BYTE PTR [rdi+5]
                test    cl, cl
                je      .L26
                cmp     dl, cl
                je      .L12
                movzx   edx, BYTE PTR [rdi+6]
                test    dl, dl
                je      .L26
                cmp     cl, dl
                je      .L12
                lea     rsi, [rdi+7]
                add     rdi, 6
                jmp     checkRepeatImpl(char const*, char const*)
        .L26:
                xor     eax, eax
        .L12:
                ret

        Какой анролл в checkRepeat() )))
        А вот в Impl говнище какое-то.

        P. S. Особенно умиляет .L6. Кажется, компилятор немного ёбнулся.
        Ответить
      • А можно написать парсер грамматики в которой запрещены повторы и ему скармливать? Если невалидный текс значит и повторы есть
        Ответить
      • Там вроде не соседние буквы проверялись, а вообще все.
        Ответить
      • bool cc(const char *p, char c) { return *p ? p == c ? true : cc(p + 1, c) : false; }
        bool cr(const char *p) { return cc(p + 1, *p) || cr(p + 1); }
        bool checkRepeat(const char *p) { return p && *p && cr(p); }
        Ответить
        • bool cr(const char *p, const char *q = p + 1) { return *p && (*q ? *p == *q || cr(p, q + 1) : cr(p + 1)); }
          Ответить
        • bool cr(const char *p, const char *q = 0) {
              return q ? (*q ? *p == *q || cr(p, q + 1) : cr(p + 1)) : *p && cr(p, p + 1);
          }
          https://ideone.com/a2lStZ
          Ответить
        • Ответить
        • bool cr(const char *p, const char *q = 0) {
              return *p && (q || (q = p + 1)) && (*q ? *p == *q || cr(p, q + 1) : cr(p + 1));
          }
          https://ideone.com/egpRBW
          Ответить
        • bool cr(const char *p, char c = 0) {
              return *p && (*p == c || c && cr(p + 1, c) || cr(p + 1, *p));
          }
          https://ideone.com/ONM3RC

          Всё, пора завязывать с этим безумием.
          Ответить
          • bool cr(const char *p, char c = 0) {
                return *p && (c ? *p == c || cr(p + 1, c) : cr(p + 1, *p) || cr(p + 1));
            }
            Чтобы сложность всё-таки квадратичная была, а не экспоненциальная.
            Ответить
            • Многословно, зато O(N).
              #include <iostream>
              #include <cstdint>
               
              void checkRepeatImpl(const char *word, uint64_t *tsar)
              {
                  if (*word) {
                      tsar[*word++]++;
                      checkRepeatImpl(word, tsar);  // Реку-ку-курсия. Хвостовая!
                  }
              }
               
              bool checkRepeatImpl(const uint64_t *tsar, size_t idx = 0)
              {
                  return (idx < 256) && (tsar[idx] > 1 || checkRepeatImpl(tsar, idx + 1));
              }
               
              bool checkRepeat(const char *word)
              {
                  uint64_t tsar[256] = {};
                  checkRepeatImpl(word, tsar);
                  return checkRepeatImpl(tsar);
              }
               
              int main()
              {
                  std::cout << checkRepeat("") << std::endl      // 0
                      << checkRepeat("a") << std::endl           // 0
                      << checkRepeat("aa") << std::endl          // 1
                      << checkRepeat("abc") << std::endl         // 0
                      << checkRepeat("aaa") << std::endl         // 1
                      << checkRepeat("bab") << std::endl         // 1
                      << checkRepeat("baab") << std::endl        // 1
                      << checkRepeat("bbaaabb") << std::endl     // 1
                      << checkRepeat("bbabc") << std::endl       // 1
                      << checkRepeat("abcbb") << std::endl;      // 1
               
                  return EXIT_SUCCESS;
              }

              https://ideone.com/6jveEq
              Ответить
              • bool cr(const char *p, char *c) {
                	return c[*p] || *p && ++c[*p] && cr(p + 1, c);
                }
                
                bool checkRepeat(const char *word)
                {
                    char cache[256] {};
                    return cr(word, cache);
                }
                https://ideone.com/FyjeNl
                Ответить
                • Инженерный отдел сильно сбоит.
                  Ответить
                  • > контр-пример — «'a'*256».

                    Оно же сразу выйдет на c[*p], не? Там вообще бул можно, но на нём ++ не работает.
                    Ответить
                    • Подтверждаю.
                      Ответить
                    • Что за хуйню вы тут обсуждаете? В "PHP" нет никаких звёздочек.
                      Ответить
                  • constexpr bool cr(const char *p, std::array<char, 256> c = {}) {
                        return c[*p] || *p && ++c[*p] && cr(p + 1, c);
                    }
                    Во нахуй!

                    З.Ы. Правда массив копируется если не в компайлтайме :(
                    Ответить
                    • gcc-проблемы, шланг нормально свернул хвостовую рекурсию и кеш не копирует.
                      Ответить
              • > uint64_t tsar[256] = {};

                А теперь сделай для юникода ^___~
                Ответить
                • Под юникод всего 16 метров уйдёт. Ну или std::unordered_set вместо него, но это чит уже.
                  Ответить
                  • Я вообще не понимаю, зачем нужны какие-то "Юникоды", иные кодировки... Почему нельзя просто хранить буквы, цифры и прочие символы в чистом виде?
                    Ответить
                    • это как?))
                      В растровом варианте чтоль?
                      Ответить
                      • Ну вот в фантастических фильмах никто не пердолится с кодировками, подобрал произвольный носитель информации на помойке, вставил в компьютер и тут же прочитал. И форматов изображений там нет, любая картинка тут же отображается на экране.
                        Ответить
                      • Это - картинки. Я имею в виду именно хранение символов, как plain-текста, безо всяких ебучих кодировок.
                        Ответить
                  • У unordered set небось логарифмический доступ. Тогда уж проще за n (log n) отсортировать строку и пройтись один раз без буфера.
                    Ответить
                    • Амортизированный O(1) по идее, хешмапа всё-таки.
                      Ответить
                      • >Амортизированный
                        у жабоёбов есть шутка про
                        long hashCode() {
                          return 42;
                        }

                        эффектно превращающая 1 и N.

                        unordered_set так же?
                        Ответить
                        • Ну да, костылей типа дерева-внутри-хешмапы там вроде нет.
                          Ответить
                      • Мне кажется, конкретно в этой ситуации ты не получишь инсерт за O(1), т.к. большую часть времени вставляешь новые элементы (получил хит ­— сразу вышел). Пруфов не будет.
                        Ответить
                        • > не получишь инсерт за O(1), т.к. большую часть времени вставляешь новые элементы
                          А чому нi? Хэшмапа же, вставка дешёвая. Не то что в этих ваших «деревьях»: пройди вниз, да покрути налево, да покрути направо, да обменяй дядю с прадедом…
                          Ответить
                          • Реаллокации дорогие. Из-за них будет что-то в духе O(log(N)) на элемент.
                            Ответить
                            • Ну дык сделать hashmap.reserve(strlen(str)) и всё.
                              Ответить
                              • Х.з., а вдруг там гигабайт английского текста?

                                З.Ы. Хотя, если там больше 16МБ можно возвращать true не читая.
                                Ответить
                                • > Х.з., а вдруг там гигабайт английского текста?
                                  Так и запишем: O(N) по памяти…

                                  > З.Ы. Хотя, если там больше 16МБ можно возвращать true не читая.
                                  Это если ты Страйкер.
                                  Ответить
                                • Воспользовался принципом Дирихле?
                                  Ответить
                                • Неправда, может там 16МБ zalgo.
                                  Ответить
                                  • Т. е. надстрочные значки (акценты) не считаются за буквы?
                                    Ответить
                                    • > не считаются за буквы
                                      На опасную дорожку вступаем.
                                      Ответить
                                      • Кстати, в «Unicode» же есть композиция и декомпозиция. Немецкую букву «а умляут» можно записать двумя способами:
                                        1. Одним кодпоинтом: ä.
                                        2. Двумя кодпоинтами: ä (написали букву «a», а потом добавили надстрочный элемент).
                                        Ответить
                                        • >>> В стандарте Юникода определены четыре алгоритма нормализации текста: NFD, NFC, NFKD и NFKC.
                                          Ответить
                                          • А комбо-смайлики в духе негр+негр под эту нормализацию попадают или у них своя атмосфера?
                                            Ответить
                                          • а как же NSFW
                                            Ответить
                                          • Я думал, что это что-то страшное, а оказывается, NFKD и NFKC — это те же декомпозиция и композиция, только ещё альтернативные начертания (готический шрифт, буквы в кружочках) заменяем на основные начертания.

                                            Тем не менее, мне не всё ясно про декомпозицию. Если у буквы два акцента (во вьетнамском такое бывает (ờ, ề), то в каком порядке эти акценты ставить при декомпозиции?
                                            Ответить
                                            • Я думаю там в правилах декомпозиции все эти моменты описаны. Скорее всего у акцентов есть какой-то порядок в котором они навешиваются.
                                              Ответить
                                  • > zalgo

                                    Т.е. символы с разным "обвесом" мы считаем разными? А визуально одинаковые - одинаковыми. Ох бля, нафиг ты этот юникод притащил...
                                    Ответить
                                    • Интересно, возможен ли 16 мегабайтный символ.
                                      Ответить
                                      • > 16 мегабайтный символ.

                                        Боюсь, что большинство библиотек сольются гораздо раньше.
                                        Ответить
                          • > Не то что в этих ваших «деревьях»: пройди вниз, да покрути налево, да покрути направо

                            Ну да, при ресайзе всего-то надо выделить бóльший кусок памяти и перехешировать всё (или ебаться с поколениями). Ну или выделить сразу дохрена памяти, но тогда тупой массив будет быстрее.
                            Ответить
                      • поясни
                        Ответить
                        • В среднем втыкает за O(1) но на некоторых вставках тупит и лагает пока увеличивает буфера и пересчитывает хеши. Именно поэтому хешмапы не особо любят в реалтайм коде.
                          Ответить
                          • так вы про вставку или про доступ?
                            Ответить
                            • Ну а доступа тут почти не будет. На первом совпадении return true.
                              Ответить
                              • я не въезжаю, а O(1) на вставке обеспечивается тем, что там заранее выделенный массив и элемент тупо вставляется на последний занятый индекс + 1?
                                Ответить
                                • показать все, что скрытоvanished
                                  Ответить
                                  • хм, ок.

                                    и что будет, если someHashFunc вернёт 100500? аллокация?
                                    Ответить
                                    • Я думаю, шта память выделяеца заранее.

                                      например, я хочу N бакетов, и выделяю память, и так настраиваю свою функцию, чтобы она выдавала равномерно число от 0 до N-1.

                                      А в какой момент увеличиваеца -- Борманд ниже поснил
                                      Ответить
                                • От ключа считается хеш. Хеш делится по модулю текущего размера буфера. И в этот слот буфера втыкается значение. Если там уже что-то есть - не повезло, применяется какой-нибудь из вариантов разрешения коллизий.

                                  Обычно везёт. Но если мапа забилась процентов на 80, то коллизии начинаются всё чаще и чаще. Поэтому выделяется новый буфер раза в 1.5-2 больше и в него переносятся все значения из старого (с пересчётом их позиций, само собой). И дальше опять какое-то время всё работает быстро и почти за O(1).
                                  Ответить
                                  • понятно.

                                    для разрешения коллизий обычно по хешу сохраняются все экземпляры. если на хеше их несколько, то тогда сравнивают ещё как-то иначе (IComparable в общем). но это только одна из реализаций, как я понимаю
                                    Ответить
                                    • Да можно и без компарабл впринципе, а просто "Equals".
                                      В самом тупом варианте ты бежишь по списку всех, у кого хеши совпали, и ищешь нужный.
                                      Ответить
                    • Кстати, а как в коке сформулировать теорему в духе "для всех списков, в которых нет одинаковых элементов, checkRepeat возвращает false"?
                      Ответить
                      • Require Import List.
                        Import ListNotations.
                        
                        Inductive no_dupes {A : Type} : list A -> Prop :=
                        | no_dupes0 : no_dupes []
                        | no_dupes1 : forall a l, ~In a l -> no_dupes (a :: l).
                        
                        Definition checkRepeat {A} (l : list A) : bool.
                        ...
                        Defined.
                        
                        Theorem checkRepeatCorrect {A} : forall (l : list A), no_dupes l  <-> checkRepeat l = false.
                        Ответить
                        • P.S. это более строгое утверждение, которое говорит, что false возвращается _только_ когда в списке нет повторов, а не, скажем, всегда ^____~. "const false" подошло бы под оригинальное определение теоремы. Ну плюс, очевидно, это сформулировано для коковских списков, а не сишных. В доказательства про императивщину с кучей я не умею, там нужно iris вкуривать, а мне лень.
                          Ответить
                          • Ну я хотел рядом вторую теорему, что он возвращает true если повторы таки есть.

                            З.Ы. Такое ощущение, что после формулировки no_dupes писать реализацию checkRepeat уже бессмысленно. Разве что какую-то более оптимизированную версию.
                            Ответить
                            • Вообще говоря, стоит. Индуктивное определение ты не можешь взять и вычислить: т.е. для конкретной строки с его помощью ты фиг поймёшь, содержит ли она повторы или нет, придётся пилить доказательство. Это определение — способ описать все возможные строки без повторов, а не способ определить, есть ли повторы.
                              Ответить
                              • А не забыл ли ты no_dupes(l) после ~In a l?

                                А то получится, что в списке [1, 2, 2, 2] нет повторов.
                                Ответить
                                • Забыл. Главная проблема формальной верификации: скормишь ей мусор — получишь верифицированный мусор.

                                  P.S. Поэтому для подобных определений я обычно тесты пилю.
                                  Ответить
                                  • Ну всегда можно рядом традиционный юнит-тест через Example написать, чтобы спокойнее было.
                                    Ответить
                                    • Тесты не нужны.
                                      Ответить
                                      • А формальные доказательства?
                                        Ответить
                                        • Тем более. Ты что, не уверен в себе и не можешь написать код правильно?
                                          Ответить
                                          • Issue trackerы не нужны, потому что у меня нормально с памятью.

                                            Тесты и доказательства не нужны, потому что я в состоянии нормально написать код.

                                            По этой же причине не нужны QA. И статические анализаторы.

                                            Ничего этого не было у Дурова, когда он написал "Вконтакте".
                                            Ответить
                                            • >>>"Ничего этого не было у Дурова, когда он написал "Вконтакте"."

                                              Между прочим. И где Дуров? А где вы все?
                                              Ответить
                                              • А где Дуров, кстати?
                                                Ответить
                                                • Он богат, успешен, известен, читает ваши переписки, ему завидуют, на него хотят быть похожими. А резиденты "Говнокода"... Ой, всё...
                                                  Ответить
                                                  • Но ты так и не ответил, где он.
                                                    Переписок моих он не читает (я его говном не пользуюсь), а еще он живет один, в какой-то тьмутаракани, пива не пьет, мяса не ест, ужасно же. Не хотел бы я так
                                                    Ответить
                                                    • Он постоянно мигрирует.

                                                      >>>"он живет один, в какой-то тьмутаракани, пива не пьет, мяса не ест"

                                                      Ты уверен, что это был не пиздёж?
                                                      Ответить
                                                      • А зачем он постоянно мигрирует? Он в бегах? Прячется?
                                                        Бедный парень(( Я бы с ума сошел так жить.

                                                        >Ты уверен, что это был не пиздёж?
                                                        А зачем ему врать?
                                                        Ответить
                                                        • Бегает не бегает, а в лучших отелях всё-таки живёт, мир видит и в комфортабельных автомобилях разъезжает. А чего добился ты?

                                                          >>>"А зачем ему врать?"

                                                          Чтобы казаться не таким, как все.
                                                          Ответить
                    • P.S. Туплю. В случае длинной строки уже сам сорт память отожрёт.
                      Ответить
                      • Ну есть же inplace алгоритмы, которые не отожрут. Но строку после этого только выбрасывать, конечно.
                        Ответить
                        • Даже in-place алгоритмам обычно нужна память для хранения вспомогательной питушни, вроде того, какие куски массива ещё не отсортированы.
                          Ответить
                          • Ну у большинства это О(1) или O(log(N)), так что сойдёт. Наивный квиксорт мы тут упоминать не будем.
                            Ответить
    • Кто-нибудь?...
      Ответить
      • показать все, что скрыто
        <?php
        
        function CheckRepeat($cur, $i, &$word) {
        	return ($word[$cur] != "\0") ? (($word[$i] != "\0") ? (($word[$cur] == $word[$i] && $cur != $i) ? true : CheckRepeat($cur, $i + 1, $word)) : CheckRepeat($cur + 1, 0, $word)) : false;
        }
        Ответить
        • > $word

          Меня этот знак доллара всегда прикалывает, потому что я его читаю как С, которая английская С, то есть как русская Г.

          Так executable превращается в sexecutable, многие другие слова тоже забавно коверкаются.
          Ответить
        • показать все, что скрытоНу почему на этот код приятнее смотреть, чем на оригинал?
          Ведь можно обойтись без "була" в начале, без долбоёбских звёздочек, без указания типов...
          Ответить
    • показать все, что скрытоvanished
      Ответить
      • В дебаге - запросто. В релизе не должно, рекурсия всё-таки хвостовая.
        Ответить
    • Приведи реальный пример, когда тебе в работе нужно было проверять слово на повтор букв.
      Ответить
      • показать все, что скрытоУ меня такой хуйни не было. Так что ситуация в посте явно надуманная.
        Ответить
        • показать все, что скрытоvanished
          Ответить
        • Какое дали задание, такое и выполняем. Вот полное условие: Сформировать строку из слов исходной строки, содержащих повторяющиеся буквы. Плюс требования от преподавателя использовать рекурсию и 60 строк на подпрограммы
          Ответить
          • В шею гнать преподавателя, дающего неприменимые на практике задания.
            Ответить
          • > полное условие

            Слово "Bob" содержит повторяющиеся буквы?
            Ответить
            • А вот этого не уточнялось
              Ответить
              • неграмотно сформулированная постановка задачи

                можешь нассать преподу на усы (уверен, что они у него есть)
                Ответить
              • Является ли "字" буквой? Есть ли повторяющиеся буквы в слове "Straße"?
                Ответить
                • В вузе за пределами ascii жизни нет
                  Ответить
                  • За пределами ascii жизни вообще нет. Только анальная боль.
                    Ответить
              • Что делать с языками, в которых нет букв?
                Ответить
                • ты хочешь, чтобы он ушёл в вагоновожатые?))
                  Ответить
                  • Борманд вроде не любит личный транспорт, поэтому пользуется общественным. Значит, он заинтересован в том, чтобы вагоновожатых было много, чтобы долго не стоять на остановке в ожидании.
                    Ответить
                    • > Борманд вроде не любит личный транспорт
                      - не все знают, но в аббревиатуре BMW первая буква на самом деле означает Bormand
                      Ответить
                  • Да я просто подумал, что я не могу решить эту задачу.

                    Как, к примеру, разделить японский текст на слова? Боюсь, что даже «icu» с его многомегабайтными таблицами тут не справится.

                    З.Ы. Походу справится, у них есть таблички с word boundary для таких языков.
                    Ответить
                    • да это ж задача не про текст, на самом деле, а про дискретные множества

                      а как в общем работают рагулярки для японского текста?
                      Ответить
                      • В душе не ебу. Регулярками естественные языки лучше не парсить, имхо.
                        Ответить
                        • http://www.localizingjapan.com/blog/2012/01/20/regular-expressions-for-japanese-text/

                          кодепоинты и Unicode block properties, в общем
                          Ответить
                          • Ну суть в том, что ты слова регулярками там никак не выпарсишь. Разве что весь словарь японского языка загнать в регулярку. Но это будет покруче знаменитой регулярки про проверку email.

                            В «icu» специальный итератор для этого завезли. Который для любого языка умеет прыгать по границам слов, предложений и чего-то там ещё.
                            Ответить
                          • Проблему обозначил Борманд: «У японцев слово может быть записано как 1-2 иероглифа + ещё немного каны».

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

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

                            Это примерно как в дореволюционной орфографии русского были слова «миръ» и «міръ», которые звучали одинаково, а смысл был разным (одно из них — весь свет, другое — отсутствие войны). Русский пережил «нормализацию», потому что таких реальных примеров было немного, а вот в японском они на каждом шагу.
                            Ответить
                            • ну студент в лабе в любом случае проверяет слово на повторение букв

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

                              а вы как обычно усложнили задачу зачем-то)
                              Ответить
                              • > кодпоинты

                                В какой из четырёх нормальных форм?
                                Ответить
                                • какая разница?

                                  один символ можно записать четырьмя разными кодпоинтами что ли?

                                  я вот смотрю в статью и вижу, что у хираганы свой интервал, у катаканы свой, у защеканы свой
                                  Ответить
                                  • Выше обсуждали композицию-декомпозицию для буков типа немецкого «ä»:
                                    http://govnokod.ru/27025#comment584463
                                    Ответить
                                  • Ну вот есть у меня кодепоинт 'á' (форма NKC), а есть пара из кодепоинта 'a' и кодепоинта '´' (форма NKD). Визуально они выглядят одинаково, а твоя прога на них сломается.

                                    И это обычный еврогейский язык, никаких иероглифов.

                                    Именно поэтому придумали нормальные формы.
                                    Ответить
                                    • да уж

                                      я бы предполагал, что разный набор кодпоинтов подразумевает разные строки для технического сравнения, но сравнение выходит семантическое (проверил на свифте)
                                      Ответить
                                      • > семантическое

                                        Более того, всякие ⑦ и ⁷ тоже могут быть равны 7 если включить более мягкий режим сравнения (не во всех либах есть, но в icu точно был).
                                        Ответить
                                        • а road и rоаd?

                                          ё-моё, мне даже фф второе слово не подчёркивает лол
                                          Ответить
                                          • Да, с NFKC нормализацией о и o должны совпасть.
                                            Ответить
                                          • Хуй там, не совпали :) Кириллическая о в латинскую o почему-то не превращается.
                                            Ответить
                    • Китайцы тоже шпарят без пробелов. Это традиция письменностей, основанных на иероглифах.
                      Ответить
                      • Я не настоящий сварщик, но у китайцев вроде попроще.

                        У японцев слово может быть записано как 1-2 иероглифа + ещё немного каны. Или целиком каной. Или вообще ромадзи.
                        Ответить
                    • Кстати, по-японски можно писать хираганой. Тогда алгоритмы для европейских языков будут пригодны (с поправкой на то, что единицей письменности будет слог, а не буква).
                      Ответить
                      • Ну вот опять же, 「ツ」и 「つ」считать одинаковыми?

                        Или слова с «iteration mark»「ゝ」, который повторяет предыдущий слог.
                        Ответить
                        • Про «iteration mark» не знал. Похоже, что это такая же питушня, как реприза у музыкантов. Но если у музыкантов в этом есть смысл (там повторяется длинный отрывок), то тут повторяется всего лишь один слог? Зачем? Зачем?
                          Ответить
                          • Ещё маленькая 「っ」 есть, которая повторяет согласную (не путать с 「つ」!).
                            Ответить
                  • Иногда реально хочется уйти в вагоновожатые...

                    В старые добрые времена я знал что такое длина строки, всё было просто и понятно.

                    А теперь нет. В байтах (в какой-то кодировке)? В соснольных квадратиках? В глифах? В пикселях (может зависеть от предыдущего куска и вообще быть вертикальной)? В кодепоинтах (какой-то нормальной формы)?
                    Ответить
                    • показать все, что скрытоvanished
                      Ответить
                      • Ну вот например 字 — это один кодепоинт, 3 байта, один глиф и два соснольных квадратика (занимает джва слота в "моноширинном" шрифте).
                        А á - это один-два кодепоинта, два-три байта, один глиф и один соснольный квадратик.

                        > от порядка букв и наличия кернинга в шрифте

                        В какую сторону измеряется "длина" в монгольской вертикальной письменности?
                        // 字test
                        // --test
                        // мда, в браузере "моноширинный шрифт" вообще распидорасило
                        Ответить
                        • > два соснольных квадратика (занимает джва слота в "моноширинном" шрифте).

                          аа, пиздец, я не умею фар ист хуйни, слава богу.

                          От отсос я почуял еще в момент появления utf-8, когда стало непросто за O(1) указать середину текста.

                          > "длина" в монгольской вертикальной письменности?
                          в высоту, очевидно

                          body width это высота у вертикальных алфавитов
                          Ответить
    • Лол, СlangFormat'у крышу снесло от иврита, начал код пидорасить, вставляя пробелы в рандомные места.
      Ответить

    Добавить комментарий