//找到所有的ALS集
function
als_find_a(&$arrdu,$tar)
{
$tmp = '';
foreach($tar as $t)$tmp.=$arrdu[$t];
$tc = str_split(str_replace('0','',$tmp));
$td = array_count_values($tc);
asort($td);
$te = implode(',',$td);
$tals = array();
if((count($td) == (count($tar)+1))
//
&& (substr($te,0,4) == '1,1,'))
{
$mk=0;
$tals = array(0,0,0,0);
$tmp = array();
foreach($td as $tk =>
$tl)
{
$tmp[]=$tk;
if($mk++
>= 1)break;
}
$place=4;
$i=0;
foreach($tar as $k)
{
$la
= (strpos($arrdu[$k],''.$tmp[0]) >0)? true :
false;
$lb
= (strpos($arrdu[$k],''.$tmp[1]) >0)? true :
false;
if($la xor
$lb)
{
if($la)$tals[$i]
= $tmp[0];
else
$tals[$i] = $tmp[1];
$tals[$i+2]=$k;
$i++;
}
else {
$tals[$place++] = $k;}
}
}
if($tals[0] == 0 || $tals[1] == 0)return
'';
else return implode(',',$tals);;
}
function als_find(&$arrdu)
{
//返回数组格式候选数y,候选数z,候选y所在位置,候选z所在位置,其它单元格位置
//reutrn array[]=(y,z,Py,Pz,Pa1,Pa2,...)
GLOBAL $rule,$initstr;
$narr =
str_split(substr($initstr,1)); //1,2,3,4,...
$als = array();
foreach($rule as $ru)
{
$m=0;
foreach($ru as
$j)if($arrdu[$j]{0} === '0')$m++;
if($m<=2)continue; //最小的ALS由两个单元格(3个辅数)组成,单规则中未填格必大于2
//第1个数
if($m>2)
foreach($ru as
$i)if($arrdu[$i]{0} === '0')
foreach($ru as $j)if(($i != $j)
&& ($arrdu[$j]{0} === '0'))
//顺序不同的看成两个
{
//双格
$tmp =
als_find_a($arrdu,array($i,$j));
if(strlen($tmp)>2)$als[]=$tmp;
//三格
if($m>3)foreach($ru
as $k)if(($i != $k)&&($j != $k) && ($arrdu[$k]{0}
=== '0'))
{
$tmp
= als_find_a($arrdu,array($i,$j,$k));
if(strlen($tmp)>2)$als[]=$tmp;
if($m>4)foreach($ru
as $m)if(($i != $m)&&($j != $m)&&($k != $m)
&& ($arrdu[$m]{0} === '0'))
{
$tmp
= als_find_a($arrdu,array($i,$j,$k,$m));
if(strlen($tmp)>2)$als[]=$tmp;
//以后可扩展到5格,再多就没意思了
}
}
}
}
return $als;
}
//专门用来输出一个ALS的 A1(B1,C2,D3)D5(超过2的)或
A1-A3
function als_outit($chain,$allpairs)
{
$j=0;
$t = array();
foreach($chain as $i)
{
$ap =
explode(',',$allpairs[$i]);
if(count($ap)>4)$t[$j].=bit2place($ap[2])."(".implode('
',array_map("bit2place",array_slice($ap,4))).")".bit2place($ap[3]);
else
$t[$j].=bit2place($ap[2])."-".bit2place($ap[3]);
$j++;
}
return implode(':',$t);
}
function
als_deepchains(&$arrdu,$num,$chain,&$allpairs)
{
//$num 是链首数
//$chain 是链集
//$allpairs 是所有链
GLOBAL $rule,$initstr,$r_row,$r_col,$r_box;
$max = false;
end($chain);
$tp =
current($chain); //B
$tp = explode(',',$allpairs[$tp]);
for($j=0;$j<count($allpairs);$j++) //first
pair CD
{
$tj = $tq =
explode(',',$allpairs[$j]);
$tmp =
$tj[0];$tj[0]=$tj[1];$tj[1]=$tmp;
$tmp =
$tj[2];$tj[2]=$tj[3];$tj[3]=$tmp;
$k =
array_search(implode(',',$tj),$allpairs);
$savea = array();
foreach($chain as $st)
{
$sb =
explode(',',$allpairs[$st]);
$savea[]=$sb[2];
$savea[]=$sb[3];
}
if(
!in_array($tq[2],$savea)
&&
!in_array($tq[3],$savea)
&& ($tp[1] ==
$tq[0])
//&&
ishardlink($arrdu,$tp[1],$tp[3],$tq[2])) //不要求尾和首是强链
m
&&
insamerule($tp[3],$tq[2])
)
{
if($chain[0] == 25 &&
$j==27)echo "B $num \n";
array_push($chain,$j);
$first =
true;
//本层是否有解
$tf =
$chain[0];
$tf =
explode(',',$allpairs[$tf]);
if($tq[1] ==
$num)
foreach($arrdu
as $m => $n)
if($n{0} ===
'0'
&&
($m != $tf[2]) && ($m != $tq[3])
&&
strpos($n,"$num") !== false
&&
insamerule($m,$tf[2])
&&
insamerule($m,$tq[3])
)
{
//echo
"$tm,$tf,$tp,$tq\n";
if($first)
{
if($GLOBALS['deep'])$GLOBALS['diff'][24]++;
if(!$GLOBALS['debug'])$first
= false;
}
//有解
$max
= true;
$new
= str_replace("$num",'',$n);
$arrdu[$m]
= $new;
if($GLOBALS['debug'])
{
if($first)
{
$first
= false;
echo
"ALS($num):[ ".als_outit($chain,$allpairs)."]\n";
}
echo
"
".bit2place($m)." $n => $new \n";
}
}
//if($max)return
$max;
//下一层
//if(
als_deepchains($arrdu,$num,$chain,$allpairs))$max = true;
array_pop($chain);
}
}
return $max;
}
function als(&$arrdu)
{
GLOBAL $rule,$initstr,$r_row,$r_col,$r_box;
//outit2($arrdu);
$als = array_unique(als_find($arrdu));
sort($als);
//print_r($als);
if(count($als)>1)foreach($als as $k =>
$strals)
{
if($max =
als_deepchains($arrdu,$strals{0},array($k),$als))
{
if(onlyone($arrdu)==-1)return
-1;
else return
1;
}
}
return 0;
}
|