-
-
Notifications
You must be signed in to change notification settings - Fork 52
/
Statics-Permutations.cs
199 lines (177 loc) · 8.46 KB
/
Statics-Permutations.cs
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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
namespace Towel;
/// <summary>Root type of the static functional methods in Towel.</summary>
public static partial class Statics
{
#pragma warning disable CS1711 // XML comment has a typeparam tag, but there is no type parameter by that name
#pragma warning disable CS1572 // XML comment has a param tag, but there is no parameter by that name
#pragma warning disable SA1604 // Element documentation should have summary
/// <typeparam name="T">The generic element type of the indexed collection.</typeparam>
/// <typeparam name="TAction">The type of action to perform on each permutation.</typeparam>
/// <typeparam name="TStatus">The type of status checker for cancellation.</typeparam>
/// <typeparam name="TGet">The type of get index operation of the collection.</typeparam>
/// <typeparam name="TSet">The type of set index operation of the collection.</typeparam>
/// <param name="start">The starting index of the values to permute.</param>
/// <param name="end">The ending index of the values to permute.</param>
/// <param name="action">The action to perform on each permutation.</param>
/// <param name="status">The status checker for cancellation.</param>
/// <param name="get">The get index operation of the collection.</param>
/// <param name="set">The set index operation of the collection.</param>
/// <param name="array">The array to iterate the permutations of.</param>
/// <param name="list">The list to iterate the permutations of.</param>
/// <param name="span">The span of the permutation.</param>
[Obsolete(NotIntended, true)]
public static void XML_Permute() => throw new DocumentationMethodException();
#pragma warning restore SA1604 // Element documentation should have summary
/// <summary>Iterates through all the permutations of an indexed collection (using a recursive algorithm).</summary>
/// <inheritdoc cref="XML_Permute"/>
[Obsolete(NotIntended, true)]
public static void XML_PermuteRecursive() => throw new DocumentationMethodException();
/// <summary>Iterates through all the permutations of an indexed collection (using an iterative algorithm).</summary>
/// <inheritdoc cref="XML_Permute"/>
[Obsolete(NotIntended, true)]
public static void XML_PermuteIterative() => throw new DocumentationMethodException();
#pragma warning restore CS1572 // XML comment has a param tag, but there is no parameter by that name
#pragma warning restore CS1711 // XML comment has a typeparam tag, but there is no type parameter by that name
/// <inheritdoc cref="XML_PermuteRecursive"/>
public static void PermuteRecursive<T>(int start, int end, Action action, Func<int, T> get, Action<int, T> set) =>
PermuteRecursive<T, SAction, StepStatusContinue, SFunc<int, T>, SAction<int, T>>(start, end, action, default, get, set);
/// <inheritdoc cref="XML_PermuteRecursive"/>
public static void PermuteRecursive<T>(int start, int end, Action action, Func<StepStatus> status, Func<int, T> get, Action<int, T> set) =>
PermuteRecursive<T, SAction, SFunc<StepStatus>, SFunc<int, T>, SAction<int, T>>(start, end, action, status, get, set);
/// <inheritdoc cref="XML_PermuteRecursive"/>
public static void PermuteRecursive<T, TAction, TGet, TSet>(int start, int end, TAction action = default, TGet get = default, TSet set = default)
where TAction : struct, IAction
where TGet : struct, IFunc<int, T>
where TSet : struct, IAction<int, T> =>
PermuteRecursive<T, TAction, StepStatusContinue, TGet, TSet>(start, end, action, default, get, set);
/// <inheritdoc cref="XML_PermuteRecursive"/>
public static void PermuteRecursive<T, TAction, TStatus, TGet, TSet>(int start, int end, TAction action = default, TStatus status = default, TGet get = default, TSet set = default)
where TAction : struct, IAction
where TStatus : struct, IFunc<StepStatus>
where TGet : struct, IFunc<int, T>
where TSet : struct, IAction<int, T>
{
Permute(start, end);
StepStatus Permute(int a, int b)
{
if (a == b)
{
action.Invoke();
return status.Invoke();
}
for (int i = a; i <= b; i++)
{
Swap<T, TGet, TSet>(a, i, get, set);
if (Permute(a + 1, b) is Break)
{
return Break;
}
Swap<T, TGet, TSet>(a, i, get, set);
}
return Continue;
}
}
/// <inheritdoc cref="XML_PermuteRecursive"/>
public static void PermuteRecursive<T>(Span<T> span, Action action) =>
PermuteRecursive<T, SAction, StepStatusContinue>(span, action);
/// <inheritdoc cref="XML_PermuteRecursive"/>
public static void PermuteRecursive<T, TAction>(Span<T> span, TAction action = default)
where TAction : struct, IAction =>
PermuteRecursive<T, TAction, StepStatusContinue>(span, action);
/// <inheritdoc cref="XML_PermuteRecursive"/>
public static void PermuteRecursive<T, TStatus>(Span<T> span, Action action, TStatus status = default)
where TStatus : struct, IFunc<StepStatus> =>
PermuteRecursive<T, SAction, TStatus>(span, action, status);
/// <inheritdoc cref="XML_PermuteRecursive"/>
public static void PermuteRecursive<T, TAction, TStatus>(Span<T> span, TAction action = default, TStatus status = default)
where TAction : struct, IAction
where TStatus : struct, IFunc<StepStatus>
{
Permute(span, 0, span.Length - 1);
StepStatus Permute(Span<T> span, int a, int b)
{
if (a == b)
{
action.Invoke();
return status.Invoke();
}
for (int i = a; i <= b; i++)
{
Swap<T>(ref span[a], ref span[i]);
if (Permute(span, a + 1, b) is Break)
{
return Break;
}
Swap<T>(ref span[a], ref span[i]);
}
return Continue;
}
}
/// <inheritdoc cref="XML_PermuteIterative"/>
public static void PermuteIterative<T>(int start, int end, Action action, Func<int, T> get, Action<int, T> set) =>
PermuteIterative<T, SAction, StepStatusContinue, SFunc<int, T>, SAction<int, T>>(start, end, action, default, get, set);
/// <inheritdoc cref="XML_PermuteIterative"/>
public static void PermuteIterative<T>(int start, int end, Action action, Func<StepStatus> status, Func<int, T> get, Action<int, T> set) =>
PermuteIterative<T, SAction, SFunc<StepStatus>, SFunc<int, T>, SAction<int, T>>(start, end, action, status, get, set);
/// <inheritdoc cref="XML_PermuteIterative"/>
public static void PermuteIterative<T, TAction, TGet, TSet>(int start, int end, TAction action = default, TGet get = default, TSet set = default)
where TAction : struct, IAction
where TGet : struct, IFunc<int, T>
where TSet : struct, IAction<int, T> =>
PermuteIterative<T, TAction, StepStatusContinue, TGet, TSet>(start, end, action, default, get, set);
/// <inheritdoc cref="XML_PermuteIterative"/>
public static void PermuteIterative<T, TAction, TStatus, TGet, TSet>(int start, int end, TAction action = default, TStatus status = default, TGet get = default, TSet set = default)
where TAction : struct, IAction
where TStatus : struct, IFunc<StepStatus>
where TGet : struct, IFunc<int, T>
where TSet : struct, IAction<int, T>
{
action.Invoke();
int[] indeces = new int[end + 2 - start];
for (int i = 0; i < indeces.Length; i++)
{
indeces[i] = i;
}
for (int i = start + 1; i < end + 1 && status.Invoke() is Continue; action.Invoke())
{
indeces[i]--;
Swap<T, TGet, TSet>(i, i % 2 is 1 ? indeces[i] : 0, get, set);
for (i = 1; indeces[i] is 0; i++)
{
indeces[i] = i;
}
}
}
/// <inheritdoc cref="XML_PermuteIterative"/>
public static void PermuteIterative<T>(Span<T> span, Action action) =>
PermuteIterative<T, SAction, StepStatusContinue>(span, action);
/// <inheritdoc cref="XML_PermuteIterative"/>
public static void PermuteIterative<T, TAction>(Span<T> span, TAction action = default)
where TAction : struct, IAction =>
PermuteIterative<T, TAction, StepStatusContinue>(span, action);
/// <inheritdoc cref="XML_PermuteIterative"/>
public static void PermuteIterative<T, TStatus>(Span<T> span, Action action, TStatus status = default)
where TStatus : struct, IFunc<StepStatus> =>
PermuteIterative<T, SAction, TStatus>(span, action, status);
/// <inheritdoc cref="XML_PermuteIterative"/>
public static void PermuteIterative<T, TAction, TStatus>(Span<T> span, TAction action = default, TStatus status = default)
where TAction : struct, IAction
where TStatus : struct, IFunc<StepStatus>
{
action.Invoke();
int[] indeces = new int[span.Length - 1 + 2];
for (int i = 0; i < indeces.Length; i++)
{
indeces[i] = i;
}
for (int i = 1; i < span.Length && status.Invoke() is Continue; action.Invoke())
{
indeces[i]--;
Swap<T>(ref span[i], ref span[i % 2 is 1 ? indeces[i] : 0]);
for (i = 1; indeces[i] is 0; i++)
{
indeces[i] = i;
}
}
}
}