Y-wing就比较简单一点,如果存在三个格辅数分别为:D1(AB),D2(AC),D3(BC),且D1与D2在同一规则上,D1与D3在同一规则上,D2与D3不在同一规则上,则与D2和D3在同一规则上的D4中的辅数C可删减掉
图中绿色组成Y-wing,Y-wing删减后可删减掉紫色单元中的5,以后就能用单链来解了
对数字5,(4,3)(4,7)(9,7)(9,2)组成单链(链长为单数3)
程序如下:
<?
/* AB --- BC
*
AC
C
*
*/
/* 找所有对 */
function getdouble($arrdu)
{
$ret = array();
foreach($arrdu as $i => $v)
{
if(strlen($v)==3)
{
$ret[$v{1}][]
= $i;
$ret[$v{2}][]
= $i;
}
}
//print_r($ret);
return $ret;
}
function y_wing(&$arrdu)
{
//outit2($arrdu);
GLOBAL $rule,$initstr,$r_row,$r_col,$r_box;
$max = true;
$ret = 0;
while($max)
{
$max = false;
$narr =
str_split(substr($initstr,1)); //1,2,3,4,...
$alldouble =
getdouble($arrdu);
foreach($narr as $num)
{
//echo "NUM
$num\n";
for($i=0;
$i<count($alldouble[$num]);$i++)
for($j=$i+1;$j<count($alldouble[$num]);$j++)
foreach($alldouble[$num]
as $i)
foreach($alldouble[$num]
as $j)
if( $j >
$i
&&
$r_row[$i] !=
$r_row[$j] //找两个不同的单元格,都包含C(num)
&&
$r_col[$i] !=
$r_col[$j] //且要求这两个格不在同一行/列/盒
&&
$r_box[$i] !=
$r_box[$j] //为AC,BC样式
&&
$arrdu[$i] != $arrdu[$j]
)
{
//再找是否存在一个关键点
AB
$first
= true;
$a
= str_replace("$num",'',substr($arrdu[$i],1));
$b
= str_replace("$num",'',substr($arrdu[$j],1));
//echo
"$i $j $a $b\n";
$q
= array_intersect( $alldouble[$a],$alldouble[$b] );
if(count($q)>0)
foreach($q
as $r)
if((
$r_row[$i] == $r_row[$r] || $r_col[$i] == $r_col[$r] || $r_box[$i]
== $r_box[$r])
&&
( $r_row[$j] == $r_row[$r] || $r_col[$j] == $r_col[$r] ||
$r_box[$j] == $r_box[$r])
)
{
//找到了
//echo
"Fund\n";
//outit2($arrdu);
foreach($arrdu
as $m => $n)
if(
$n{0} === '0'
&&
strpos($n,"$num") !== false
&&
$m != $i && $m != $j && $m != $r
&&
( $r_row[$i] == $r_row[$m] || $r_col[$i] == $r_col[$m] ||
$r_box[$i] == $r_box[$m])
&&
( $r_row[$j] == $r_row[$m] || $r_col[$j] == $r_col[$m] ||
$r_box[$j] == $r_box[$m])
)
{
$new
= str_replace("$num",'',$n);
$arrdu[$m]
= $new;
if($GLOBALS['debug'])
{
if($first)
{
echo
"Y-wing(A$a,B$b,C$num):AB:".bit2place($r)."
AC:".bit2place($j)