Problem:
I have a simple List<T>one and I'm trying to sort it. But the items in the list are not all transitive in terms of comparability, that is, for, for example, my List<T>looks like this:
A
B
C
D
E
where A> B and B> C, but C> A. It is also possible to have circular greatness similar to A> B, B> C, C> D, but D> A, i.e. not necessarily always a group of 3 . I want to find all groups of circular quantities in a givenList<T> . For example, if A> B> C> A and A> B> C> D> A are two circular groups in this case, my output should look like this:
List<List<T>> circulars = [[A, B, C, A], [A, B, C, D, A]]
or
List<List<T>> circulars = [[A, B, C], [A, B, C, D]]
. (linquish) , , . , - .
:
, / , , , , . , , , . , " " , , . , , , , .
:
class Player : IComparable<Player>
{
// logic
}
, :
3. [ABC], [A, C, B]...., [A, B, C, D], [ A, B, D, C].... .. ( )
. , , A > B > C > D ( , )
, , , [A, B, C] [B, C, A] ..
:
var players = [.....];
var circulars = Enumerable.Range(3, players.Count - 3 + 1)
.Select(x => players.Permutations(x))
.SelectMany(x => x)
.Select(x => x.ToList())
.Where(l => l.Zip(l.Skip(1), (p1, p2) => new { p1, p2 }).All(x => x.p1 > x.p2) && l.First() < l.Last())
.Distinct(new CircularComparer<Player>())
.ToList();
public static IEnumerable<IEnumerable<T>> Permutations<T>(this IEnumerable<T> list, int length)
{
if (length == 1)
return list.Select(t => new[] { t });
return Permutations(list, length - 1)
.SelectMany(t => list.Where(e => !t.Contains(e)), (t1, t2) => t1.Concat(new[] { t2 }));
}
class CircularComparer<T> : IEqualityComparer<ICollection<T>>
{
public bool Equals(ICollection<T> x, ICollection<T> y)
{
if (x.Count != y.Count)
return false;
return Enumerable.Range(1, x.Count)
.Any(i => x.SequenceEqual(y.Skip(i).Concat(y.Take(i))));
}
public int GetHashCode(ICollection<T> obj)
{
return 0;
}
}
, . 10 , , ( 1 ). , ? . ? .