Склад перестановок - груповий продукт


12

Враховуючи дві перестановки у формі неперервного циклу, виведіть їх продукт / композицію у форму неперервного циклу

Q · P = (1 5) (2 4) · (1 2 4 3) = (1 4 3 5).

Щоб знайти композицію, перетворіть роз'єднані цикли в перестановки в дворядкові позначення. Кожне число в неперервній частині циклу відображається на число, що слідує за ним в тій же частині. Він обертається навколо. Так 1 -> 5, 5 -> 1, 2 -> 4, 4 -> 2. Якщо число не знайдено 3 -> 3, воно відображається до себе. Перший неперервний цикл також міг бути записаний (1 5)(2 4)(3). Ці відображення перетворюються на два рядки, як-от так (зауважте, що порядок P і Q зворотні):

Ого, це зображення є масовим!

Твір продукту двох перестановок отримують шляхом перестановки стовпців другої (крайньої лівої) перестановки так, щоб її перший ряд був ідентичним другому ряду першої (правої) перестановки. Потім продукт може бути записаний як перший рядок першого перестановки над другим рядом модифікованої другої перестановки.

введіть тут опис зображення

Стаття у Вікіпедії


Правила:

  • Введення буде надано у вигляді списку списків або подібного формату
  • Ви не можете приймати щось подібне, (1 5)(2 4)як [5, 4, 3, 2, 1]вже у дворядковій формі (відображення індексу до значення)
  • Не всі числа мають бути в кожній групі, так що ви могли б мати (1 5)·(1 2)результат (2 5 1).
  • Ваш вихід повинен бути використаний як ваш вхід.
  • Вам не потрібно підтримувати введення з порожнім циклом (1 5)·(). Це було б замість цього як (1 5)·(1)щось рівнозначне.
  • Оскільки цикли завершуються, порядок не має значення, якщо результат правильний.
  • Можна починати з нуля або одиниці. Не має значення, адже результати однакові.
  • Цифри можуть бути більшими, ніж 9.
  • Ви можете не включати одне і те ж число більше одного разу у висновок. Так [[1],[1]]не дозволено.
  • Зауважте, що ця операція не є комутативною ! Я ставлю Q перед P, тому що це зробила Вікіпедія. Ви можете вибрати будь-яке замовлення, але вкажіть, яке, якщо воно інше.
  • Найкоротший код виграє
  • Вбудовані дозволені, але якщо ви їх використовуєте, покажіть рішення, не використовуючи його.

Приклади:

Не всі еквівалентні можливості виводу показані

Input
Output

[[1, 5], [2, 4]], [[1, 2, 4, 3]]
[[1, 4, 3, 5]] (or [[4, 3, 5, 1]] or ...)

[[1, 5]], [[1, 2]]
[[2, 5, 1]]

[[10, 2, 3]], [[2]]
[[3, 10, 2]]

[[1]], [[3]]
[[]] (or [[1]] or something equivalent)

[[10,2,3,15],[1,7],[5,6],[14,4,13,11,12]], [[5,6,7,9,14],[2,8,3,10],[1,11]]
[[12, 14, 6, 1], [8, 15, 10, 3, 2], [13, 11, 7, 9, 4]]

(arguments in reverse order from above gives a different answer)
[[5,6,7,9,14],[2,8,3,10],[1,11]], [[10,2,3,15],[1,7],[5,6],[14,4,13,11,12]]
[[9, 14, 4, 13, 1], [10, 8, 3, 15, 2], [7, 11, 12, 5]]

Для мене це перестановки , а не групи перестановок . Група перестановок - це колекція, закрита в рамках цієї операції композиції, з групи окремих перестановок.
Грег Мартін

@GregMartin Виправлена ​​термінологія
mbomb007

Відповіді:


2

Ваш вихід повинен бути використаний як ваш вхід.
mbomb007

@ mbomb007 Вихід можна використовувати як вхід. Кожен список циклів повинен бути 0-індексованим масивом коробкових масивів.
милі

Або це поведінка друку J за замовчуванням? Я просто хочу переконатися, що функцію можна прикувати.
mbomb007

@ mbomb007 Так, це лише візуальне уявлення про це. Він повинен бути 0-індексованим, але я вказав його як 1-індексований і перетворив їх на 0-індекс, перш ніж вони будуть збережені у змінних, які передаються функції. Потім після цього я перетворюю його назад з 0-індексованого до 1-індексованого перед виведенням його.
милі

3

Математика, 15 байт

##⊙Cycles@{}&

Так, Вірджинія, є вбудований .... Mathematica підтримує тип даних перестановки вже в неперервному позначенні циклу: ця чиста функція приймає як введення будь-яку кількість аргументів у форму Cycles[{{1, 5}, {2, 4}}]і виводить перестановку товару, знову ж таки, у Cycles[]формі. Він використовує протилежну конвенцію про впорядкування як ОП, наприклад,

##⊙Cycles@{}&[Cycles[{{1, 2, 4, 3}}], Cycles[{{1, 5}, {2, 4}}]]

повертає Cycles[{{1, 4, 3, 5}}]. Символ я вище повинен дійсно бути 3-байтовий приватного використання Unicode символ U + F3DE для роботи в Mathematica. Зауважте, що Mathematica має названий вбудований для цієї операції PermutationProduct, але це на три байти довше.


3

Haskell , 157 148 байт

Редагувати:

  • -9 байт: Це справді могло би бути більше гольфу. Навколо видалено зайві дужки p++q. Змінено аргумент порядку g. Позбувся d, починаючи iterateз p x, після чого takeWhileбільше не прив’язується до fst+ span. Зроблено iterateінфікс.

Роблячи це, поки я спізнююсь ... напевно, можна пограти ще трохи.

Це було простіше і, здавалося, дозволено, тому висновок включає одноелементні цикли.

q#p=g(p++q>>=id)$f q.f p
f p a=last$a:[y|c<-p,(x,y)<-zip(0:c)(c++c),x==a]
g(x:l)p|c<-x:fst(span(/=x)$p`iterate`p x)=c:g[x|x<-l,x`notElem`c]p
g[]p=[]

Спробуйте в Інтернеті!

Як це працює:

  • #є основною функцією. q#pбере два списки списків чисел і повертає аналогічний список. Здається, тести мають Q перед P, тому я використовував той самий порядок.
  • f pперетворює перестановку pз роз'єднаної форми циклу у функцію, після чого f qі f pможе скластись із звичайним оператором композиції ..
    • Розуміння списку повторюється за циклами c, шукаючи aта знаходячи свого наступника. Якщо розуміння нічого не знаходить, aпросто повертається.
    • zip(0:c)(c++c)це перелік пар елементів cта їх наступників. Оскільки питання дозволяє нам "почати з одного", ми можемо використовувати 0як фіктивне значення; дешевше додати цей zipперший аргумент, ніж використовувати tailдругий.
  • g l pприймає список lелементів та перестановку p, а також повертає список циклів, що торкаються елементів.
    • Ось cцикл, що містить перший елемент xсписку, інші елементи cзнаходять шляхом ітерації від p xдоx буде знайдений знову. При повторному пошуку інших циклів всі елементи cспочатку видаляються з розумінням списку.

Дякуємо, що зазначили, що порядок має значення під час обчислення результату. Я забув додати приклад або прокоментувати його. Це було виправлено.
mbomb007

1

Пітон, 220 байт

a,b=eval(input())
p,o=a+b,[]
for i in range(1,1+max(map(max,p))):
 if not any(i in t for t in o):
  u,m=(i,),i
  while 1:
   for t in p[::-1]:
    if m in t:m=t[(t.index(m)+1)%len(t)]
   if m==i:o+=[u];break
   u+=(m,)
o

2
Ласкаво просимо на сайт. Я бачу досить багато способів, як ви могли це скоротити. Розгляньте сторінку порад для python .
Ad Hoc Hunter Hunter

0

Пітон 3,8 , 187 байт

q,p=eval(input())
g=lambda p,i:[*(c[c.index(i)-1]for c in p if i in c),i][0]
h=lambda*c:(x:=g(p,g(q,c[0])))in c and(*c[(m:=c.index(min(c))):],*c[:m])or h(x,*c)
exit({*map(h,sum(p|q,()))})

Спробуйте в Інтернеті! або Перевірте всі тестові випадки!

Введення : qі pв такому порядку кожен - це набір кортежів, від STDIN.
Вихід : Перестановка виробу Q·Pяк набір кортежів, доSTDERR .

Пояснення

Функція gзнаходить, яке число збігається з числом iв перестановці p(ака g- зворотна перестановка p).

g=lambda p,i:        
[                   # creates a list
  *(                # containing the following
    c[c.index(i)-1] #   the number before i in cycle c
    for c in p      #   for all cycles in permutation
    if i in c       #   if i is in that cycle
  )                 #
  ,i                # adds i to the end of that list
                    #   (in case i is not in any cycle)
][0]                # returns the first element of the list

Функція hприймає число і повертає цикл, Q·Pщо містить це число. Повертається цикл буде кортежем, відформатованим таким чином, що найменший елемент знаходиться в індексі 0.

h=lambda*c:                   # input: an incomplete cycle c, as a list
(x:=g(p,g(q,c[0])))           # finds the number x before the first number in c
in c                          # if x is also in c (aka the cycle is complete)
and                           # then returns the following:
(                             #   c as a tuple with min element at index 0
  *c[(m:=c.index(min(c))):],  #   (c, from the min element to the end)
  *c[:m]                      #   (c, from start to the min element)
)
or                            # else (cycle is incomplete) returns the following
h(x,*c)                       #   recursive result when after prepending x to c

Застосовуючи hвсі числа, ми можемо отримати всі цикли Q·P. Щоб уникнути дублювання циклів у нашому результаті, ми просто помістимо всі цикли в набір. Це працює, оскільки подібні цикли, що повертаються, hбудуть відформатовані в один і той же кортеж (з найменшим елементом в індексі 0).
Нам потрібно лише врахувати числа, що відображаються в, Pабо Q, як і всі інші числа будуть відображатись для себе.

exit(              # returns through STDERR
  {                # create a set from the followings
    *map(h,        #   map function h to
      sum(p|q,())  #   all numbers in P or Q
    )
  }
)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.