Определение на доске "четверок" ферзей

Gennadiy Usov
Дата: 27.11.2018 21:02:37
Есть интересная задача:
построение «квадрата» ферзей на доске NxN при известных двух ферзях.

В сообщениях 21156343 и 21183322 показано, что таких четверок для ФМР1 может быть много: каждый с каждым. Приведенные значения квадратов показаны только для центральных четверок.

Задача:
Пусть имеются значения Ax и Ay для одного ферзя и Bx и By для другого ферзя.
Необходимо найти значения Cx и Cy для третьего ферзя и Dx и Dy для четвертого ферзя.

Могут быть три варианта:
- исходные ферзи находятся в противоположных углах квадрата;
- исходные ферзи находятся на одной стороне квадрата и квадрат с одной стороны;
- исходные ферзи находятся на одной стороне квадрата и квадрат с другой стороны.

Если определяемые ферзи «выбегают» за доску, то их надо «возвращать»: по принципу >N и <1.
Gennadiy Usov
Дата: 28.11.2018 13:57:11
Допустим имеется на доске 13х13 следующее ФМР1:
11, 6,1,9,4,12,7,3,10,5,13,8,3
Необходимо построить «квадрат» ферзей для 2-го и 7-го ферзей, которые находятся в противоположных углах этого «квадрата».
Напишем код:
function main {					
	var N=13;				
	// определяем массив ФМР1				
	var F = new Array(N+1);				
					
	var shag=5;				
	MODrech(N, F, shag);				
					
	var ax=2;				
	var bx=7;				
	var ay=F(ax);				
	var by=F(bx);				
	KVADRAT(N, ax, ay, bx, by, cx, cy, dx, dy);				
					
	// печать  cx, cy, dx, dy				
}					
function KVADRAT(N, ax, ay, bx, by, cx, cy, dx, dy) { 					
	var rk=bx-ax+1;				
	var delx=rk/2;				
	var dely=by-ay;				
	var k=(dely-1)/2;				
	var yn=ay-delx+k;				
					
	dy=yn+1;				
	cy=yn+rk;				
	dx=ax+delx+1+k;				
	cx=ax+delx-1-k;				
}					
function MODrech(N, R, shag) {			
	var N1= (N+1)/2;		
	var ij=N+1;		
	var j=N1;		
			
	R[N1] = N1;		
	for (var i = N1+1 ; i <= N ; i++) {		
		j = j + shag;	
		if (j > N) j = j – N;	
		R[i] = j;	
		R[ij-i] =ij-j;	
	}		
}	
Получаем значения для 4-го и 5-го ферзей.
Gennadiy Usov
Дата: 28.11.2018 20:53:52
В предыдущем сообщении рассмотрен вариант, когда величина rk=bx-ax нечетная.
Если величина rk - четная, то необходимо уточнить function KVADRAT.

Теперь рассмотрим вариант, когда величина rk четная: для 2-го и 12-го ферзей.
function KVADRAT(N, ax, ay, bx, by, cx, cy, dx, dy) { 				
	var kd=bx-ax			
	if (odd(kd)) {			
		var k1=0;		// kd - нечетное
	} else {			
		var k1=1;		
	}			
	var rk=k+1;			
	var delx=(rk-k1)/2;			
	var dely=by-ay;			
	var k=(dely-1-k1)/2;			
	var yn=ay-delx+k;			
				
	dy=yn+1;			
	cy=yn+rk;			
	dx=ax+delx+1+k;			
	cx=ax+delx-1-k;			
}		
      function odd(a) {		
        return a % 2 == 1;		
      }		
Получаем значения для 6-го и 8-го ферзей.
Gennadiy Usov
Дата: 29.11.2018 07:45:07
Рассмотрим вариант, когда получаемые ферзи «выскакивают» за край доски.
В частности, для 3-го и 13-го ферзей.
Напишем код изменения процедуры KVADRAT:
function KVADRAT(N, ax, ay, bx, by, cx, cy, dx, dy) { 					
	var kd=bx-ax				
	if (odd(kd)) {				
		var k1=0;		// kd - нечетное	
	} else {				
		var k1=1;			
	}				
	var rk=k+1;				
	var delx=(rk-k1)/2;				
	var dely=by-ay;				
	var k=(dely-1-k1)/2;				
	var yn=ay-delx+k;				
					
	dy=yn+1;				
	if (dy > N) dy=dy-N;				
	if (dy < 1) dy=dy+N;				
	cy=yn+rk;				
	if (cy > N) cy=cy-N;				
	if (cy < 1) cy=cy+N;				
	dx=ax+delx+1+k;				
	if (dx > N) dx=dx-N;				
	if (dx < 1) dx=dx+N;				
	cx=ax+delx-1-k;				
	if (cx > N) cx=cx-N;				
	if (cx < 1) cx=cx+N;				
}		
Получаем значения для 7-го и 9-го ферзей.
Gennadiy Usov
Дата: 29.11.2018 17:02:29
Далее, процедура KVADRAT построена для случая, когда bx > ax. Поэтому необходимо в main добавить условие отображения по вертикали.

Кроме того, не для всех «двоек» ферзей существует «квадрат» ферзей, когда эти ферзи располагаются в противоположных углах квадрата. Поэтому необходима проверка на то, что полученные значения ферзей совпадают со значениями массива F.

Поэтому код для function main будет выглядеть по другому:
function main {		
	var N=13;	
	// определяем массив ФМР1	
	var F = new Array(N+1);	
		
	var shag=5;	
	MODrech(N, F, shag);	
		
	var ax=2;	
	var bx=7;	
	var ay=F[ax];	
	var by=F[bx];	
		
	if (bx > ax ) {	
		KVADRAT(N, ax, ay, bx, by, cx, cy, dx, dy);
	} else {	
		KVADRAT(N, bx, ay, ax, by, dx, cy, cx, dy);
	}	
	if ( F[cx]== cy) {	
		// "квадрат" ферзей получился
	}	
		
	// печать  cx, cy, dx, dy	
}		
Теперь необходимо найти ещё два «квадрата» ферзей при условии, два исходных ферзя находятся на одной из сторон «квадрата».
Gennadiy Usov
Дата: 30.11.2018 07:45:14
Теперь необходимо найти ещё два «квадрата» ферзей при условии, два исходных ферзя находятся на одной из сторон «квадрата».

Имеем тот же ФМР1: 11, 6,1,9,4,12,7,3,10,5,13,8,3
Необходимо построить два «квадрата» ферзей для 2-го и 7-го ферзей, которые буду находиться на одной стороне этого «квадрата».

Напишем код определения этих двух «квадратов» ферзей:
function main {	
	var N=13;
	// определяем массив ФМР1
	var F = new Array(N+1);
	
	var shag=5;
	MODrech(N, F, shag);
	
	var ax=2;
	var bx=7;
	var ay=F[ax];
	var by=F[bx];
	
	KVADRAT1(N, ax, ay, bx, by, cx, cy, dx, dy);
	// печать  cx, cy, dx, dy
	
	KVADRAT1(N, bx, by, ax, ay, cx, cy, dx, dy);
	// печать  cx, cy, dx, dy
}	
function KVADRAT1(N, ax, ay, bx, by, cx, cy, dx, dy) { 				
	var delx=bx-ax;			
	var dely=by-ay;			
				
	cx=bx+delx;			
	cy=by-delx;			
	dx=ax+dely;			
	dy=ay-delx;			
				
	if (dy > N) dy=dy-N;			
	if (dy < 1) dy=dy+N;			
	if (cy > N) cy=cy-N;			
	if (cy < 1) cy=cy+N;			
	if (dx > N) dx=dx-N;			
	if (dx < 1) dx=dx+N;			
	if (cx > N) cx=cx-N;			
	if (cx < 1) cx=cx+N;			
}				
Получаем в первом случае ферзи 8 и 3, а во втором случае - ферзи 1 и 6.

В отличии от первого «квадрата» ферзей у второго и третьего «квадратов» определяемые ферзи всегда существуют в массиве F.
Gennadiy Usov
Дата: 30.11.2018 13:14:30
Теперь можно построить код для определения всех возможных «четверок» ферзей в виде номеров ферзей на доске 13х13.

Данные номера будут храниться в массиве MCHET(k1,4) где k1 – количество «четверок».
Многие «четверки» будут совпадать друг с другом. Это пока не важно. Главное – «четверки» ферзей есть для каждой пары ферзей из ФМР1 для любой доски NxN, где есть этот ФМР1.
Итак код:
function main {									
	var N=13;								
	var ax, ay, bx, by, cx, cy, dx, dy;								
									
	// определяем массив ФМР1								
	var F = new Array(N+1);								
									
	// определяем  массивы четверок ферзей								
	var F = new Array(1000+1);								
	var MCHET = new Array(nchet+1);								
	for(var i = 0; i < nchet + 1; i++) { MCHET [i] = new Array(4+1);}								
									
	var shag=5;								
	MODrech(N, F, shag);								
	var k1=0;								
	for(var i = 1; i < =13; i++) { 								
		for(var j = 1; j < =13; j++) { 							
			if (i != j) {						
				ax=i;					
				ay=F[i];					
				bx=j;					
				by=F[j];					
									
				KVADRAT1(N, ax, ay, bx, by, cx, cy, dx, dy);					
				// печать  cx, cy, dx, dy					
				k1=k1+1;					
				MCHET[k1][1]= i;					
				MCHET[k1][2]= j;					
				MCHET[k1][3]= cx;					
				MCHET[k1][4]= dx;					
									
				KVADRAT(N, ax, ay, bx, by, cx, cy, dx, dy);					
									
				if ( F[cx]== cy) {					
					k1=k1+1;				
					MCHET[k1][1]= i;				
					MCHET[k1][2]= cx;				
					MCHET[k1][3]= j;				
					MCHET[k1][4]= dx;				
				}					
			}						
		}							
	// печать  k1 - количество "четверок" ферзей.								
	}								
}	
Оказывается, что при определении номеров ферзей, для формирования "четверок" ферзей, необязательно определять cy и dy.
Gennadiy Usov
Дата: 01.12.2018 08:51:42
А теперь рассмотрим задачу определения «четверки» ферзей, которая при повороте совместится с установленным ферзем.
Получается следующий код:
function main {					
	var N=13;				
					
	// определяем массив ФМР1				
	var R = new Array(N+1);				
	// определяем массив ФМР3				
	var R1 = new Array(N+1);				
					
	// определяем ФМР1				
	var shag=5;				
	MODrech(N, R, shag);				
					
	// установленный ферзь				
	var Fx= 11;				
	var Fy=2;	
	// заполняем форму для нового решения		
	for(var i = 1; i < =N; i++) { R1[i]=R[i];}				
	// поворот "четверки" ферзей и получение нового решения				
	POVORchet(N, R, R1, Fx, Fy); 				
}					
function POVORchet(N, R, R1, Fx, Fy) { 				
	var ax, ay, bx, by, cx, cy, dx, dy;			
	var i1=1;			
	while (R[i1] != Fy) {			
		i1=i1+1;		
	}			
	var ax=i1;			
	var ay=Fy;			
	var bx=Fx;			
	var by=R[Fx];			
				
	KVADRAT(N, ax, ay, bx, by, cx, cy, dx, dy);			
				
	R1[ax] = R[bx};			
	R1[bx] = R[ax};			
	R1[cx] = R[dx};			
	R1[dx] = R[cx};			
}	

Получаем новое решение R1.
Gennadiy Usov
Дата: 01.12.2018 19:15:27
необходимо поменять процедуру на новый вариант:
function POVORchet(N, R, R1, Fx, Fy) { 					
	var ax, ay, bx, by, cx, cy, dx, dy;				
	var i1=1;				
	while (R[i1] != Fy) {				
		i1=i1+1;			
	}				
	var ax=i1;				
	var ay=Fy;				
	var bx=Fx;				
	var by=R[Fx];				
					
	KVADRAT(N, ax, ay, bx, by, cx, cy, dx, dy);				
					
	R1[ax] = R[bx];				
	R1[bx] = R[ax];				
	R1[cx] = R[dx];				
	R1[dx] = R[cx];				
}