
--subtype coorng is integer range 1..9;
--type coords is array(1..2) of coorng;
--type cellseq is array(1..9) of coords;


separate( asudx )

-- returns cell coords of a Ywing triple
procedure yWing(
	r1,c1, r2,c2, r3,c3, tr0,tc0, dig: out s9;
	--tr1,tc1, tr2,tc2, dig: out s9; 
	found: out boolean) is

	tr1,tc1, tr2,tc2: s9;

-- find 1st digit in common:
function cd( r1,c1, r2,c2: coorng ) return s9 is
begin
	for d in coorng loop
	if candidate(r1,c1)(d) and candidate(r2,c2)(d) then
		return d;
	end if;
	end loop;
	return 0;
end cd;
 
 
-- Count the candidate digits contained in
-- First cell in "rcd".
function d1( r,c: coorng ) return integer is
	kount: integer := 0;
begin
	for d in coorng loop
		if candidate(r,c)(d) then
			kount:=kount+1;
		end if;
	end loop;
	return kount;
end d1;

-- Count the candidate digits contained in the union
-- of First + Second cells in "rcd".
function d2( r1,c1, r2,c2: coorng ) return integer is
	kount: integer := 0;
begin

	for d in coorng loop

		if 
			candidate( r1,c1 )(d)
			or
			candidate( r2,c2 )(d) 
		then
			kount:=kount+1;
		end if;

	end loop;

	return kount;

end d2;






-- Count the candidate digits contained in the union
-- of First + Second + Third cells in "rcd".
function d3( r1,c1, r2,c2, r3,c3: coorng ) return integer is
	kount: integer := 0;
begin

	for d in coorng loop

		if 
			candidate( r1,c1 )(d)
			or
			candidate( r2,c2 )(d) 
			or
			candidate( r3,c3 )(d) 
		then
			kount:=kount+1;
		end if;

	end loop;

	return kount;

end d3;





function nblks( r1,c1, r2,c2, r3,c3: coorng ) return integer is
	kount: integer := 3;
	br1,bc1, br2,bc2, br3,bc3, nb1,nb2,nb3: integer;
begin
	br1:=(r1-1)/3;
	br2:=(r2-1)/3;
	br3:=(r3-1)/3; --0..2

	bc1:=(c1-1)/3;
	bc2:=(c2-1)/3;
	bc3:=(c3-1)/3; --0..2

	nb1:=br1*3+bc1;
	nb2:=br2*3+bc2;
	nb3:=br3*3+bc3; --0..8

	if nb1=nb2 then kount:=kount-1; end if;
	if nb1=nb3 then kount:=kount-1; end if;
	if nb2=nb3 then kount:=kount-1; end if;
	return kount;
end nblks;

function nrows( r1,c1, r2,c2, r3,c3: coorng ) return integer is
	kount: integer := 3;
begin
	if r1=r2 then kount:=kount-1; end if;
	if r1=r3 then kount:=kount-1; end if;
	if r2=r3 then kount:=kount-1; end if;
	return kount;
end nrows;

function ncols( r1,c1, r2,c2, r3,c3: coorng ) return integer is
	kount: integer := 3;
begin
	if c1=c2 then kount:=kount-1; end if;
	if c1=c3 then kount:=kount-1; end if;
	if c2=c3 then kount:=kount-1; end if;
	return kount;
end ncols;


--ftn "match"...
--input: coords of 2 cells
--output: 
--		0=>no visibility
--		1=>visibility (same house)
function match( r1,c1, r2,c2: coorng ) return integer is
	br1,bc1,b1, br2,bc2,b2: integer;
begin

	br1:= (r1-1)/3;		--0..2	zero-based box row
	bc1:= (c1-1)/3; 		--0..2	zero-based box col
	b1 := br1*3 + bc1;	--0..8	lexicographic box number

	br2:= (r2-1)/3;		--0..2
	bc2:= (c2-1)/3;		--0..2
	b2 := br2*3 + bc2;	--0..8

--  rowmatch  colmatch  boxmatch
	if r1=r2 then
		return 1;
	elsif c1=c2 then
		return 1;
	elsif b1=b2 then
		return 1;
	else
		return 0;
	end if;

end match;




	victory,
	same12, same13, same23: boolean := false;
	nb,nr,nc,k, n1,n2,n3: integer;

	rcbm12, rcbm23, rcbm13, piv: integer;

begin --yWing (stops @ 1st found 15may)

	found:=false;
	r1:=0; c1:=0;
	r2:=0; c2:=0;
	r3:=0; c3:=0;

	for row1 in coorng range 1..9 loop
	for col1 in coorng range 1..9 loop
	if not found and d1(row1,col1)=2 then

	for row2 in coorng range 1..9 loop
	for col2 in coorng range 1..9 loop
	same12:= (row2=row1) and (col2=col1);
	if not found and not same12 and d1(row2,col2)=2 then

	for row3 in coorng range 1..9 loop
	for col3 in coorng range 1..9 loop
	same13:= (row3=row1) and (col3=col1);
	same23:= (row3=row2) and (col3=col2);
	if not found and not same13 and not same23 and d1(row3,col3)=2 then

		k:=d3(row1,col1, row2,col2, row3,col3); -- #digits in Union{1,2,3}
		n1:=d2(row1,col1, row2,col2); --#digits in Union{1,2}
		n2:=d2(row1,col1, row3,col3); --#digits in Union{1,3}
		n3:=d2(row2,col2, row3,col3); --#digits in Union{2,3}

		if k=3 and n1=3 and n2=3 and n3=3 then --(non-aligned naked 222 triple)

			nb:=nblks(row1,col1, row2,col2, row3,col3);--#blocks
			nr:=nrows(row1,col1, row2,col2, row3,col3);--#rows
			nc:=ncols(row1,col1, row2,col2, row3,col3);--#cols

			-- a match => same house
			rcbm12 := match( row1,col1, row2,col2 );
			rcbm23 := match( row2,col2, row3,col3 );
			rcbm13 := match( row1,col1, row3,col3 );


			tr1:=0;
			tc1:=0;
			tr2:=0;
			tc2:=0;
			dig:=0;
			if rcbm13=0 then 
				piv:=2;
				dig:=cd(row1,col1, row3,col3);
				tr1:=row1; tc1:=col3;
				tr2:=row3; tc2:=col1;

			elsif rcbm23=0 then 
				piv:=1;
				dig:=cd(row2,col2, row3,col3);
				tr1:=row2; tc1:=col3;
				tr2:=row3; tc2:=col2;

			elsif rcbm12=0 then 
				piv:=3;
				dig:=cd(row1,col1, row2,col2);
				tr1:=row1; tc1:=col2;
				tr2:=row2; tc2:=col1;

			else 
				piv:=0; 
			end if;



			if
				(nb=3 and nr=2 and nc=2) or
				(nb=2 and nr=3 and nc=2) or
				(nb=2 and nr=2 and nc=3)
			then

				if rcbm12+rcbm23+rcbm13 = 2  and piv>0  then 
				-- exactly 1 cell (pivot) matches other 2,
				-- but other 2 don't match each other.

					--Wait until we find a removable target digit 
					--before declaring victory...
					victory:=candidate(tr1,tc1)(dig) or candidate(tr2,tc2)(dig);

					if victory then
						found:=true;
						r1:=row1; c1:=col1;
						r2:=row2; c2:=col2;
						r3:=row3; c3:=col3;

						if candidate(tr1,tc1)(dig) then
							tr0:=tr1; tc0:=tc1;
						else
							tr0:=tr2; tc0:=tc2;
						end if;

					else --keep looking
						null;
					end if;

				end if;

			end if;

		end if;


	end if; --outer
	end loop; --c3
	end loop; --r3

	end if;
	end loop; --c2
	end loop; --r2

	end if;
	end loop; --c1
	end loop; --r1

end yWing;

