-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathPermutation.class.st
More file actions
176 lines (153 loc) · 4.2 KB
/
Permutation.class.st
File metadata and controls
176 lines (153 loc) · 4.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
"
Finite-support bijective functions. Permutations under composition form groups (see SymmetricGroup and PermutationGroup).
"
Class {
#name : #Permutation,
#superclass : #AbstractPermutation,
#instVars : [
'map'
],
#category : #'Mathematics-Groups-Permutations'
}
{ #category : #'instance creation' }
Permutation class >> cycle: aCollection [
| answer first last |
answer := self new.
aCollection do: [:each|
first isNil
ifTrue: [first := each]
ifFalse: [answer at: last put: each].
last := each].
answer at: last put: first.
^ answer
]
{ #category : #'instance creation' }
Permutation class >> cycles: anArray [
^ anArray inject: self new into: [:answer :each| answer * (self cycle: each)]
]
{ #category : #'instance creation' }
Permutation class >> keys: anArray values: anotherArray [
| answer |
answer := self new.
anArray with: anotherArray do: [:x :y| answer at: x put: y].
^ answer
]
{ #category : #'instance creation' }
Permutation class >> new [
"Answer a new instance of the receiver representing the identity permutation."
^ super new map: Dictionary new
]
{ #category : #'instance creation' }
Permutation class >> on: aSet evaluating: aBlock [
| answer |
answer := self new.
aSet do: [:each| answer at: each put: (aBlock value: each)].
^ answer
]
{ #category : #'instance creation' }
Permutation class >> transposing: anObject with: anotherObject [
"Answer the tranposition of anObject with anotherObject."
^ self new
at: anObject put: anotherObject;
at: anotherObject put: anObject;
yourself
]
{ #category : #arithmetic }
Permutation >> * aPermutation [
"Answer the product (function composition) of the receiver with the argument.
This is the group product operation."
| answer |
answer := self species new.
self changesDo: [:each|
answer at: each put: (self at: (aPermutation at: each))].
aPermutation changesDo: [:each|
answer at: each put: (self at: (aPermutation at: each))].
^ answer
]
{ #category : #comparing }
Permutation >> = aPermutation [
(aPermutation isKindOf: self species)
ifFalse: [ ^ super = aPermutation ].
map
keysAndValuesDo: [ :key :value |
(aPermutation at: key) = value
ifFalse: [ ^ false ] ].
aPermutation map size <= map size
ifTrue: [ ^ true ].
aPermutation map
keysAndValuesDo: [ :key :value |
value = (self at: key)
ifFalse: [ ^ false ] ].
^ true
]
{ #category : #converting }
Permutation >> asArray [
^ (1 to: map size) collect: [ :each | self at: each ]
]
{ #category : #accessing }
Permutation >> at: anObject [
^ map at: anObject ifAbsent: [ anObject ]
]
{ #category : #accessing }
Permutation >> at: anObject put: anotherObject [
anObject = anotherObject ifTrue: [^ anotherObject].
^ map at: anObject put: anotherObject
]
{ #category : #enumerating }
Permutation >> changesDo: aBlock [
map keysDo: aBlock
]
{ #category : #accessing }
Permutation >> domain [
^ map keys as: Domain
]
{ #category : #comparing }
Permutation >> hash [
| answer |
answer := 0.
" self changesDo: [:each| answer := answer + each hash]."
map keysAndValuesDo: [:key :value| key = value ifFalse: [answer := answer bitXor: key hash hashMultiply + value hash]].
^ answer
]
{ #category : #arithmetic }
Permutation >> identity [
"Answer the identity permutation."
^ self species new
]
{ #category : #arithmetic }
Permutation >> inverse [
"Answer the compositive inverse of the receiver."
| answer |
answer := self species new.
self changesDo: [:each| answer at: (self at: each) put: each].
^ answer
]
{ #category : #testing }
Permutation >> isTransposition [
"Answer true if the receiver is a transposition."
^ self size = 2
]
{ #category : #'accessing-private' }
Permutation >> map [
^ map
]
{ #category : #'accessing-private' }
Permutation >> map: aCollection [
map := aCollection
]
{ #category : #private }
Permutation >> species [
^ Permutation
]
{ #category : #accessing }
Permutation >> transpositions [
"Answer the decomposition of the receiver in product of transpositions."
| answer last value |
answer := OrderedCollection new.
self changesDo: [:each|
last := each.
answer reverseDo: [:one| last := one at: last].
(value := self at: each) = last
ifFalse: [answer addFirst: (self species transposing: last with: value)]].
^ answer
]