static int sstep;
static void FindAll(int N,int sum,int step,bool ord){
sstep=step;
sum/=step;
fill(new int[N],N,sum,sum-N+1,ord);
}
static void output(int[] A){
Console.Write("{0}",A[0]*sstep);
for(int i=1;i<A.Length;i++) Console.Write("/{0}",A[i]*sstep);
Console.WriteLine();
}
static void fill(int[] A,int N,int sum,int smax,bool ord) {
if(N==0 && sum==0) {
output(A);
return;
}
if(N==0 || sum<N) return;
int smin=ord ? 1 : (sum-1)/N+1;
N--;
for(A[N]=smin;A[N]<=smax;A[N]++) {
fill(A,N,sum-A[N],ord ? sum-N+1 : A[N],ord);
}
}
internal class Program
{
private static void Main(string[] args)
{
foreach (var combination in GenerateCombinations(3, 5, 1))
{
foreach (var i in combination)
{
Console.Write(i + ", ");
}
Console.WriteLine();
}
Console.WriteLine("----------------");
foreach (var combination in GenerateUniqueCombinations(3, 5, 1))
{
foreach (var i in combination)
{
Console.Write(i + ", ");
}
Console.WriteLine();
}
Console.ReadLine();
}
private static List<List<int>> GenerateUniqueCombinations(int stacksCount, int totalAmount, int step)
{
var generatedCombinations = GenerateCombinations(stacksCount, totalAmount, step);
var dicts = new List<Dictionary<int, int>>();
foreach (var combination in generatedCombinations)
{
var dict = new Dictionary<int, int>();
foreach (var i in combination)
{
if (dict.ContainsKey(i))
{
dict[i]++;
}
else
{
dict[i] = 1;
}
}
if (!dicts.Any(d => DictionaryEquals(d, dict)))
{
dicts.Add(dict);
}
}
return dicts.Select(d =>
{
var r = new List<int>();
foreach (var key in d.Keys)
{
if (d[key] == 1)
{
r.Add(key);
}
else
{
r.AddRange(Enumerable.Repeat(key, d[key]));
}
}
return r;
}).ToList();
}
private static bool DictionaryEquals(Dictionary<int, int> x, Dictionary<int, int> y)
{
foreach (var key in x.Keys)
{
if (!y.ContainsKey(key))
{
return false;
}
if (x[key] != y[key])
{
return false;
}
}
foreach (var key in y.Keys)
{
if (!x.ContainsKey(key))
{
return false;
}
if (x[key] != y[key])
{
return false;
}
}
return true;
}
private static List<List<int>> GenerateCombinations(int stacksCount, int totalAmount, int step)
{
var result = new List<List<int>>();
if (stacksCount > 1)
{
for (var i = 1; i < totalAmount / step; ++i)
{
var add = i * step;
foreach (var generated in GenerateCombinations(stacksCount - 1, totalAmount - add, step))
{
generated.Insert(0, add);
result.Add(generated);
}
}
}
else
{
result.Add(new List<int> { totalAmount });
}
return result;
}
}