А чем не нравится goto? Вполне легальный оператор. В случае чего, от него легко избавиться, преобразовав код в конечный автомат (получится цикл с одним switch внутри). Хотя чаще хватает одной дополнительной логической переменной.
И какого типа ограничения? И есть ли ограничение на порядок выдачи перестановок?
UPD. Вот вариант решения на C#. Не самый эффективный, правда.
class Program{
static IEnumerable<int[]> Permutations(int N,Func<int,int,bool>Cond1,Func<int,int,int,int,bool> Cond2) {
int[] res=new int[N];
int k=0;
res[0]=0;
while(k>=0){
if(++res[k]<=N){
if(Cond1(k+1,res[k]) && GoodValue(res,k,Cond2)){
if(k==N-1) yield return res;
else res[++k]=0;
}
}else k--;
}
}
static private bool GoodValue(int[] res,int k,Func<int,int,int,int,bool> Cond) {
for(int i=0;i<k;i++) {
if(res[i]==res[k] || !Cond(i+1,res[i],k+1,res[k])) return false;
}
return true;
}
static int N=6;
static bool Cond1(int a,int va) {
if(a==1) return va==1;
if(a==N) return va==N;
return true;
}
static bool Cond2(int a,int va,int b,int vb) {
return Math.Abs(a-b)>1 || Math.Abs(va-vb)<=3;
}
static void Main(string[] args) {
foreach(int[] perm in Permutations(N,Cond1,Cond2))
Console.WriteLine(String.Join(",",perm));
}
}
Функции Permutations передаются два условия. Первое Cond1(a,va) проверяет, может ли элемент va находиться в позиции a, второе Cond2(a,va,b,vb) - могут ли одновременно находиться va в позиции a и vb в позиции b.
В качестве примера - печать перестановок из задачи про лягушку из ProjectEuler:
https://projecteuler.net/problem=490
Для N=6 выдаёт ожидаемые 14 перестановок:
1,2,3,4,5,6
1,2,3,5,4,6
1,2,4,3,5,6
1,2,4,5,3,6
1,2,5,3,4,6
1,2,5,4,3,6
1,3,2,4,5,6
1,3,2,5,4,6
1,3,4,2,5,6
1,3,5,2,4,6
1,4,2,3,5,6
1,4,2,5,3,6
1,4,3,2,5,6
1,4,5,2,3,6
Если не нравится конструкция yield return - вставьте вместо неё свою обработку перестановки, а функцию опишите, как void. Если из GoodValue yбрать проверку res[I]==res[k], то вместо перестановок будут печататься все N-элементные наборы из чисел 1..N, удовлетворяющие условию.