const string splitor = "----";
void Main()
{
var r = Dp(new List<string>(){"a","b","c","d","e","f","g"});
Console.WriteLine(r);
//print combosition count
var count = 0;
for(var i = 0 ;i < r.Count; i++){
var c = Regex.Matches(r[i], splitor).Count;
count += c + 1;
}
Console.WriteLine(string.Format("total : {0}",count));
}
//Dp[0] = "a[0],a[1],...a[n]"
//Dp[i] = Dp[i-1] cross with Dp[0]
static List<string> Dp(List<string> arr){
if(arr == null || arr.Count == 0){
return new List<string>();
}
var dpArr = new dynamic[arr.Count];
var t = string.Empty;
for(var i = 0;i < arr.Count - 1; i++){
t += arr[i] + ",";
}
t += arr[arr.Count-1];
// set dpArr[0] = "a[0],a[1],a[2]..."
dpArr[0] = t;
dpArr[0] = dpArr[0].Replace(",",splitor);
// set dpArr[1] = "a[0...n] cross a[0...n]"
dpArr[1] = cross(t,t);
//set dpArr[i...n] = dpArr[0] cross dpArr[i-1]
for(var i = 2;i< dpArr.Length ; i++){
var tmp = cross(dpArr[i-1] ,t);
dpArr[i] = tmp;
}
//twick and save result into list
var ret = new List<string>();
ret.Add(dpArr[0]);
for(var i = 1 ;i < dpArr.Length; i++){
ret.Add(string.Join(splitor.ToString(),dpArr[i]));
}
return ret;
}
//for strA = ["a,b","a,c"] and strB = "a,b,c,d"
//return ["a,b,c","a,b,d","a,c,d"]
static List<string> cross(List<string> strA, string strB){
var ret = new List<string>();
var arr = strB.Split(',');
for(var i =0 ;i< strA.Count; i++){
var str = strA[i];
for(var j = 0 ;j < arr.Length; j++){
var t = str + "," + arr[j];
if(!str.Contains(arr[j]) && !IsInclude(ret,t)){
ret.Add(t);
}
}
}
return ret;
}
//for "a,b" and "b,c,d,a"
//return ["a,b","a,c","a,d","b,c","b,d"]
static List<string> cross(string a, string b){
var arr1 = a.Split(',');
var arr2 = b.Split(',');
var r = new List<string>();
for(var i = 0;i < arr1.Length; i++){
for(var j = 0;j < arr2.Length; j++){
if(arr1[i] != arr2[j]){
var t = arr1[i] + ","+arr2[j];
if(!IsInclude(r,t)){
r.Add(t);
}
}
}
}
return r;
}
// Define other methods and classes here
static bool IsInclude(List<string> lst,string str){
for(var i = 0 ;i < lst.Count; i++){
bool containsAll = true;
if(lst[i].Length != str.Length){
containsAll = false;
}
for(var j = 0; j< str.Length; j++){
if(!lst[i].Contains(str[j])){
containsAll = false;
}
}
if(containsAll){
return true;
}
}
return false;
}