順列の構成–グループ製品


12

互いに素なサイクル形式で2つの順列が与えられた場合、それらの製品/組成を互いに素なサイクル形式で出力します。

Q・P =(1 5)(2 4)・(1 2 4 3)=(1 4 3 5)。

構成を見つけるには、分離したサイクルを2行表記の順列に変換します。サイクルのばらばらの部分の各番号は、同じ部分でそれに続く番号にマッピングされます。包み込みます。ですから1 -> 55 -> 12 -> 44 -> 2。番号が見つからない場合は3 -> 3、それ自体にマップされます。最初のばらばらのサイクルも書くことができます(1 5)(2 4)(3)。これらのマッピングは、次のように2行に変換されます(PQの順序が逆になっていることに注意してください)。

うわー、この画像は巨大です!

2つの順列の積は、最初の行が最初の(最も右の)順列の2番目の行と同じになるように、2番目(左端)の順列の列を再配置することによって得られます。次に、積を、変更された2番目の順列の2番目の行に対する最初の順列の最初の行として書き込むことができます。

ここに画像の説明を入力してください

ウィキペディアの記事


ルール:

  • 入力はリストのリストまたは同様の形式で与えられます
  • のように、すでに2行の形式(インデックスから値へのマッピング)をとることはできません。(1 5)(2 4)[5, 4, 3, 2, 1]
  • すべての数値が各グループで発生する必要はないので(1 5)·(1 2)、発生する可能性があり、結果としてになり(2 5 1)ます。
  • 出力は入力として使用できるはずです。
  • 空のサイクルでの入力をサポートする必要はありません(1 5)·()。代わりに、(1 5)·(1)または同等のものとして与えられます。
  • サイクルは循環するため、結果が正しければ、順序は関係ありません。
  • ゼロまたは1から開始できます。結果は同じなので、問題ではありません。
  • 数値はより大きい場合があり9ます。
  • 同じ番号を出力に複数回含めることはできません。だから、[[1],[1]]許可されていません。
  • この操作は可換でないことに注意してください!私はPの前にQを置きました。任意の順序を選択できますが、順序が異なる場合は指定してください。
  • 最短コードの勝利
  • 組み込みは許可されますが、組み込みを使用する場合は、それを使用せずにソリューションを表示します。

例:

同等の出力の可能性がすべて示されているわけではありません

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 2017

回答:


2

出力は入力として使用できるはずです。
mbomb007 2017

@ mbomb007出力は入力として使用できます。サイクルの各リストは、ボックス化された配列の0インデックスの配列でなければなりません。
マイル

それとも、このJのデフォルトの印刷動作ですか?関数をチェーンできることを確認したいだけです。
mbomb007 2017

@ mbomb007はい、それは単なる視覚的な表現です。0インデックスを付ける必要がありますが、1インデックスとしてリストされ、関数に渡される変数に格納される前に0インデックスに変換されます。その後、0インデックスから1インデックスに変換してから出力します。
マイル

3

Mathematica、15バイト

##⊙Cycles@{}&

はい、バージニア、組み込みがあります。...Mathematicaは、互いに素な循環表記の置換データ型をサポートしています。この純粋な関数は、フォームに任意の数の引数を入力としてCycles[{{1, 5}, {2, 4}}]受け取り、積の置換を再びフォームに出力しますCycles[]。OPとは逆の順序付け規則を使用しているため、たとえば、

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

を返しますCycles[{{1, 4, 3, 5}}]私は上記の使用する記号は本当にMathematicaでの作業にUnicodeの記号U + F3DE 3バイト私的使用する必要があります。Mathematicaにはこの操作のための組み込みの名前が付いていますがPermutationProduct、それは3バイト長いことに注意してください。


3

ハスケル157の 148バイト

編集:

  • -9バイト:それは確かにもっとゴルフすることができます。の周りの冗長な括弧を削除しましたp++q。の引数の順序を入れ替えましたg。ガットはを取り除くd開始することでiteratep 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数値のリストの2つのリストを取り、同様のリストを返します。テストではPの前にQがあるようなので、同じ順序を使用しました。
  • f p順列変換p互いに素なサイクルフォームからは、その後、関数へf qf p通常の合成作用素で構成することができます.
    • リスト内包表記はサイクルを繰り返し、後続をc検索しaて見つけます。理解力が何も見つからない場合aは、単に返されます。
    • zip(0:c)(c++c)cとその後続要素のペアのリストです。質問では「1から始める」ことができる0ので、ダミー値として使用できます。2番目のzip引数で使用するよりも、最初の引数の前に追加する方が安価tailです。
  • g l pl要素のリストと順列関数を受け取り、要素にp接触するサイクルのリストを返します。
    • これは、リストのc最初の要素xを含むサイクルです。他の要素は、再びが見つかるまでcから反復することで見つかります。残りのサイクルを見つけるために再帰的に実行すると、のすべての要素がリスト内包表記で最初に削除されます。p xxc

結果を計算するときに順序が重要であることを指摘していただきありがとうございます。例やコメントを追加するのを忘れました。それは修正されました。
mbomb007 2017

1

Python、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ヒントページを確認することを検討してください
アドホックガーフハンター

0

Python 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

説明

この関数gi、順列の数にマップされる数を検出します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。結果のサイクルが重複しないように、すべてのサイクルを1つのセットに入れるだけです。によって返される同様のサイクル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
    )
  }
)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.