Кто этот Полигон?

14

Удобный и полезный способ представления топологических поверхностей с помощью фундаментального многоугольника . Каждая сторона многоугольника совпадает с другой стороной и может быть параллельной или антипараллельной. Например, вот фундаментальный многоугольник тора :

торус

Чтобы понять, почему это тор, мы можем представить, что наш многоугольник - это лист бумаги. Чтобы получить правильную поверхность, мы хотим согнуть нашу бумагу так, чтобы соответствующие ребра совпали со своими стрелками, идущими одинаковым образом. Для нашего примера тора мы можем начать, свернув бумагу в цилиндр так, чтобы два синих края (помеченные буквой b) были соединены. Теперь возьмем нашу трубку и согнем ее так, чтобы два красных края (обозначенных буквой а) соединились друг с другом. Мы должны иметь форму пончика, также называемого тор.

Это может стать немного сложнее. Если вы попытаетесь сделать то же самое со следующим многоугольником, где одно из ребер идет в противоположном направлении:

Бутылка Кляйна

Вы можете оказаться в беде. Это потому, что этот многоугольник представляет бутылку Кляйна, которая не может быть встроена в трех измерениях. Вот диаграмма из Википедии, показывающая, как вы можете сложить этот многоугольник в бутылку Кляйна:

Складывание бутылки Кляйна


Как вы уже догадались, задача здесь состоит в том, чтобы взять фундаментальный многоугольник и определить, какая это поверхность. Для четырехсторонних полигонов (единственные поверхности, с которыми вам придется обращаться) есть 4 разных поверхности.

Они есть

  • торус

  • Бутылка Кляйна

  • сфера

  • Проективная плоскость

Теперь это не поэтому я не ожидаю, что вы возьмете изображение в качестве ввода, вместо этого мы будем использовать удобную запись для представления основного многоугольника. Вы, возможно, заметили в двух приведенных выше примерах, что я назвал соответствующие ребра одной и той же буквой (или a или b), и что я дал скрученному ребру дополнительную метку, чтобы показать его скрученный. Если мы начнем с верхнего края и запишем метку для каждого края по часовой стрелке, мы можем получить обозначение, представляющее каждый фундаментальный многоугольник.

Например, предоставленный Торус станет abab, а Бутылка Кляйна станет ab - ab . Для нашей задачи мы сделаем это еще проще, вместо того, чтобы пометить скрученные края отрицательным, мы вместо этого сделаем эти буквы заглавными.

задача

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

правила

  • Стороны не всегда будут помечены буквами a и b, но они всегда будут помечены буквами.

  • Допустимый ввод будет состоять из 4 букв, двух одного типа и двух другого. Вы должны всегда выводить правильную поверхность для правильного ввода.

  • Вы должны отклонить (не выводить ни одно из 4 значений, представляющих поверхности) неверный ввод. Вы можете сделать что-нибудь, отклоняя ввод, если он отличается от 4 поверхностей

  • Это поэтому цель состоит в том, чтобы минимизировать количество байтов в исходном коде.

тесты

Простые тесты

abab Torus
abAb Klein Bottle
abaB Klein Bottle
abAB Projective Plane
aabb Klein Bottle
aAbb Projective Plane
aabB Projective Plane
aAbB Sphere
abba Klein Bottle
abBa Projective Plane
abbA Projective Plane
abBA Sphere

Хитрые тесты

ABAB  Torus
acAc  Klein Bottle
Emme  Projective Plane
zxXZ  Sphere
aaab  Bad input
abca  Bad input
abbaa Bad input
ab1a  Bad input
Пост Рок Гарф Хантер
источник
Почему ababтор и aabbбутылка Кляйна?
Нил
@Neil abab- это пример в первом абзаце, вы можете найти там объяснение. Вот изображение, показывающее, почему aabbэто то же самое, abAbчто и бутылка Кляйна.
Пост Рок Гарф Хантер
1
Какие плохие входные данные мы должны обработать и идентифицировать как плохие? Все возможные строки? Версия для печати ASCII? Есть ли ограничения по длине? Если мы напишем функцию, можно ли передать ей нестроковый объект? Действительно, весь этот бизнес по обработке ввода кажется мне проблемой хамелеона.
xnor
1
@WheatWizard В таком случае, не могли бы вы сделать это ясно в заголовке и теле? Он читается как математика до Правил, и даже там легко пропустить требование смены игры, чтобы подтвердить, а не просто классифицировать.
xnor
2
Отдельно, я думаю, что отсутствует объяснение того, что делает строку классифицированной в данной категории, так как вы, кажется, не ожидаете, что люди выполнят математику за классификацией. Я думаю, что мог бы разобраться в правилах из тестовых случаев, но это далеко от идеала.
xnor

Ответы:

6

Сетчатка , 123 байта

i`(.)(\1..)
$2$1
iG`^([a-z])(?!\1)([a-z])(\1\2|\2\1)$
(..)\1
T
.*(.).\1.*|(.)(.)\3\2
B
(.)..\1|.(.)\2.
P
i`(.)..\1
S
....
P

Попробуйте онлайн! Спасибо @JonathanAllen за указание на ошибку в моем коде, а также за то, как сохранить несколько байтов; Я также играл в гольф еще несколько байтов, поэтому я не могу отдать ему должное за конкретную цифру. Объяснение:

i`(.)(\1..)
$2$1

Если первые две буквы совпадают (без учета регистра), переместите первую букву на четвертую. Это уменьшает количество случаев, которые мне нужно проверить.

iG`^([a-z])(?!\1)([a-z])(\1\2|\2\1)$

Если не совсем четыре буквы, или первые две буквы совпадают, или последние две буквы не дублируют первые две, то удалите все.

(..)\1
T

Тора - это простой случай: пара букв, повторяющиеся совпадения.

.*(.).\1.*|(.)(.)\3\2
B

Если одна из пары соответствует случаю (в этом случае другая из пары должна не соответствовать случаю), то это бутылка Кляйна. Альтернативно, если пара соответствует случаю, но перевернута, то это также бутылка Кляйна.

(.)..\1|.(.)\2.
P

Если, с другой стороны, пара перевернута, но только одна пара соответствует регистру, то это проективная плоскость.

i`(.)..\1
S

И если пара перевернута, но не соответствует регистру, то это сфера. ( i`.(.)\1.также будет работать.)

....
P

Все остальное - проективная плоскость.

Нил
источник
1
@JonathanAllan Спасибо за совет; надеюсь, эта версия будет лучше проверена.
Нил
Если бы я мог сам разработать логику: р
Джонатан Аллан
1

Желе , 52 51 58 байт

+7 байт, я обнаружил, что отображение, которое я использовал, не работало для некоторых (вне примера) сценариев изменения случая.

“nḲ⁾⁶ƥ¦ṃṗḋ’b4s4‘µṙJ;U$µ€
,ŒsṢÞṪµŒlĠL€⁼2,2ȧ⁸i@€ṢeЀ¢TṪ’:3,8

Монадическая ссылка, принимающая строку и возвращающая следующие пять различных согласованных значений:

  • [-1,-1] - Неверный Ввод
  • [0,0] - проективная плоскость
  • [1,0] - бутылка Кляйна
  • [2,0] - сфера
  • [2,1] - торус

Попробуйте онлайн! или посмотрите набор тестов .

Как?

Любой фундаментальный многоугольник это:

  • без изменений при вращении - можно повернуть бумагу как руль
  • без изменений при отражении - можно перевернуть бумагу
  • без изменений при обращении к регистру - можно поменять местами as и As и / или bs и Bs без эффекта - поскольку мы хотим совпасть с направлениями, фактическая метка несущественна.

Таким образом, существует девять классов эквивалентности. Код создает списки из четырех целых чисел, каждый из которых представляет пример одного из девяти классов эквивалентности, создает четыре поворота каждого, отражает каждый из них и затем проверяет, существует ли переведенная форма ввода в каждом списке. Классы упорядочены P,P,P,K,K,K,S,S,T, поэтому взятие целочисленного индекса на основе 0, деленного на каждый из, [3,8]дает четыре допустимых выхода (индексирование основано на 1, а атом eвозвращается 0за несуществование, поэтому вычитание 1и деление целого числа на каждое из выходных [3,8]значений [-1,-1]для недопустимого случая ).

“nḲ⁾⁶ƥ¦ṃṗḋ’b4s4‘µṙJ;U$µ€ - Link 1, symmetries of the 9 equivalence classes: no arguments
“nḲ⁾⁶ƥ¦ṃṗḋ’              - base 250 number                 1704624888339951310984
           b4            - convert to base 4               [1,1,3,0,1,2,2,0,1,2,3,0,0,2,2,0,1,3,1,0,2,1,2,0,2,3,1,0,3,1,2,0,2,0,2,0]
             s4          - split into 4s                   [[1,1,3,0],[1,2,2,0],[1,2,3,0],[0,2,2,0],[1,3,1,0],[2,1,2,0],[2,3,1,0],[3,1,2,0],[2,0,2,0]]
               ‘         - increment (vectorises)          [[2,2,4,1],[2,3,3,1],[2,3,4,1],[1,3,3,1],[2,4,2,1],[3,2,3,1],[3,4,2,1],[4,2,3,1],[3,1,3,1]]
                µ     µ€ - for €ach:                       ...e.g. [2,2,4,1]:
                  J      -   range of length               [1,2,3,4]
                 ṙ       -   rotate left by (vectorises)   [[2,4,1,2],[4,1,2,2],[1,2,2,4],[2,2,4,1]]
                     $   -   last two links as a monad:
                    U    -     upend (reverse each)        [[2,1,4,2],[2,2,1,4],[4,2,2,1],[1,4,2,2]]
                   ;     -     concatenate                 [[2,4,1,2],[4,1,2,2],[1,2,2,4],[2,2,4,1],[2,1,4,2],[2,2,1,4],[4,2,2,1],[1,4,2,2]]

,ŒsṢÞṪµŒlĠL€⁼2,2ȧ⁸i@€ṢeЀ¢TṪ’:3,8 - Main link: string s      e.g. "xOxO"
 Œs                               - swap case                     "XoXo"
,                                 - pair with s                   ["xOxO","XoXo"]
    Þ                             - sort by:
   Ṣ                              -   sort                        ["xOxO","XoXo"]
     Ṫ                            - tail                          "XoXo"
      µ                           - monadic chain separation, call that v
       Œl                         - convert to lowercase          "xoxo"
         Ġ                        - group indices by value        [[2,4],[1,3]]
          L€                      - length of each                [2,2]
             2,2                  - 2 pair 2                      [2,2]
            ⁼                     - equal? (1 if so, 0 if not)    1
                 ⁸                - link's left argument, v       "XoXo"
                ȧ                 - and (v if equal, 0 if not)    "XoXo"
                     Ṣ            - sort v                        "XoXo"
                  i@€             - first index for €ach          [1,3,1,3]
                         ¢        - call the last link (1) as a nilad
                       Ѐ         - map over right:
                      e           -   exists in?                  [0,0,0,0,0,0,0,0,1]
                          T       - truthy indexes                [                9]
                           Ṫ      - tail (empty list yields 0)    9
                            ’     - decrement                     8
                              3,8 - 3 pair 8                      [3,8]
                             :    - integer division (vectorises) [2,1]

Примечание: 11 bytes ( ŒlĠL€⁼2,2ȧ⁸) только проверяют правильность входной строки как правильной формы - без этого кода проходит каждый пример, за исключением того, что ab1aон оценивается как abBaпроективная плоскость.

Джонатан Аллан
источник