-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPermutation.java
More file actions
125 lines (112 loc) · 3.98 KB
/
Copy pathPermutation.java
File metadata and controls
125 lines (112 loc) · 3.98 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
package enigma;
import static enigma.EnigmaException.*;
import java.util.ArrayList;
/** Represents a permutation of a range of integers starting at 0 corresponding
* to the characters of an alphabet.
* @author NikkiTrueblood
*/
class Permutation {
/** ArrayList of Strings to represent
* all the cycles in the permutation. */
private ArrayList<String> _perm = new ArrayList<String>();
/** Set this Permutation to that specified by CYCLES, a string in the
* form "(cccc) (cc) ..." where the c's are characters in ALPHABET, which
* is interpreted as a permutation in cycle notation. Characters in the
* alphabet that are not included in any cycle map to themselves.
* Whitespace is ignored. */
Permutation(String cycles, Alphabet alphabet) {
_alphabet = alphabet;
char c;
for (int i = 0; i < cycles.length(); i++) {
c = cycles.charAt(i);
if (!(_alphabet.contains(c) || c == '(' || c == ')' || c == ' ')) {
throw new EnigmaException("Wrong character input.");
}
if (_alphabet.contains(c)) {
if (cycles.substring(i + 1).indexOf(c) != -1) {
throw new EnigmaException("Letter is "
+ "repeated too many times.");
}
}
}
String adder = "";
for (int i = 0; i < cycles.length(); i++) {
if (cycles.charAt(i) != '(') {
if (cycles.charAt(i) == ')') {
addCycle(adder);
adder = "";
} else if (cycles.charAt(i) == ' ') {
int something = 0;
} else {
adder = adder + cycles.charAt(i);
}
}
}
}
ArrayList<String> perm() {
return _perm;
}
/** Add the cycle c0->c1->...->cm->c0 to the permutation, where CYCLE is
* c0c1...cm. */
private void addCycle(String cycle) {
_perm.add(cycle + cycle.charAt(0));
}
/** Return the value of P modulo the size of this permutation. */
final int wrap(int p) {
int r = p % size();
if (r < 0) {
r += size();
}
return r;
}
/** Returns the size of the alphabet I permute. */
int size() {
return _alphabet.size();
}
/** Return the result of applying this permutation to P modulo the
* alphabet size. */
int permute(int p) {
char pp = _alphabet.toChar(wrap(p));
return _alphabet.toInt(permute(pp));
}
/** Return the result of applying the inverse of this permutation
* to C modulo the alphabet size. */
int invert(int c) {
char cc = _alphabet.toChar(wrap(c));
return _alphabet.toInt(invert(cc));
}
/** Return the result of applying this permutation to the index of P
* in ALPHABET, and converting the result to a character of ALPHABET. */
char permute(char p) {
for (int i = 0; i < _perm.size(); i++) {
for (int j = 0; j < _perm.get(i).length(); j++) {
if (_perm.get(i).charAt(j) == p) {
return _perm.get(i).charAt(j + 1);
}
}
}
return p;
}
/** Return the result of applying the inverse of this permutation to C. */
char invert(char c) {
for (int i = 0; i < _perm.size(); i++) {
for (int j = 0; j < _perm.get(i).length(); j++) {
if (_perm.get(i).charAt(j) == c && j != 0) {
return _perm.get(i).charAt(j - 1);
}
}
}
return c;
}
/** Return the alphabet used to initialize this Permutation. */
Alphabet alphabet() {
return _alphabet;
}
/** Return true iff this permutation is a derangement (i.e., a
* permutation for which no value maps to itself). */
boolean derangement() {
return true;
}
/** Alphabet of this permutation. */
private Alphabet _alphabet;
}