private IEnumerable <Expression> DistinctFor( IEnumerable <Expression> elements, int minPartitions, Func <Partition <Expression>, IEnumerable <Expression> > partitionExpressionBuilder, Func <Expression, IEnumerable <Expression>, IEnumerable <Expression>, IEnumerable <Expression> > reduceExpressionBuilder) => elements.Take(2).Count() == 1 ? elements : Partitionings.Of(elements) .All() .Where(partitioning => partitioning.Count() >= minPartitions) .SelectMany(partitioning => partitioning.Select(partitionExpressionBuilder).CrossProduct()) .SelectMany(subexpressions => this.ThreeWaySplit(subexpressions) .SelectMany(split => reduceExpressionBuilder(split.head, split.direct, split.inverse)));
static void PartitioningDemo() => InputNumberSequences .SelectMany(numbers => Partitionings.Of(numbers).All()) .Select(partitioning => partitioning.Select(partition => string.Join(" ", partition.ToArray()))) .Select(partitions => string.Join(" | ", partitions)) .WriteLinesTo(Console.Out);