A string is called a square string if it can be obtained by concatenating two copies of the same string. For example, \"abab\", \"aa\" are square strings, while \"aaa\", \"a
Here's a solution using LINQ:
IEnumerable input = new[] {"a","a","a"};
// The next line assumes the existence of a "PowerSet" method for IEnumerable.
// I'll provide my implementation of the method later.
IEnumerable> powerSet = input.PowerSet();
// Once you have the power set of all subsequences, select only those that are "square".
IEnumerable> squares = powerSet.Where(x => x.Take(x.Count()/2).SequenceEqual(x.Skip(x.Count()/2)));
Console.WriteLine(squares);
And here is my PowerSet extension method, along with a "Choose" extension method that is required by PowerSet:
public static class CombinatorialExtensionMethods
{
public static IEnumerable> Choose(this IEnumerable seq, int k)
{
// Use "Select With Index" to create IEnumerable
var indexedSeq = seq.Select((Value, Index) => new {Value, Index});
// Create k copies of the sequence to join
var sequences = Enumerable.Repeat(indexedSeq,k);
// Create IEnumerable containing one empty sequence
/// To create an empty sequence of the same anonymous type as indexedSeq, allow the compiler to infer the type from a query expression
var emptySequence =
from item in indexedSeq
where false
select item;
var emptyProduct = Enumerable.Repeat(emptySequence,1);
// Select "Choose" permutations, using Index to order the items
var indexChoose = sequences.Aggregate(
emptyProduct,
(accumulator, sequence) =>
from accseq in accumulator
from item in sequence
where accseq.All(accitem => accitem.Index < item.Index)
select accseq.Concat(new[] { item }));
// Select just the Value from each permutation
IEnumerable> result =
from item in indexChoose
select item.Select((x) => x.Value);
return result;
}
public static IEnumerable> PowerSet(this IEnumerable seq)
{
IEnumerable> result = new[] { Enumerable.Empty() };
for (int i=1; i<=seq.Count(); i++)
{
result = result.Concat(seq.Choose(i));
}
return result;
}
}