最近太閒,所看了韓信點兵的故事,其中有提到算兵數的問題,就試著去研究一下後寫了一個函式
/*********************
* 使用範例
* Demo
*********************/
//測試資料1(Test Data1)
$data1 = array(
'2' => 1,//除2餘1,數學式:x ≡ 1 (mod 2)
'3' => 2,//除3餘2,數學式:x ≡ 2 (mod 3)
'5' => 4,//除5餘4,數學式:x ≡ 4 (mod 5)
'7' => 0 //除7餘0,數學式:x ≡ 0 (mod 7)
);
//測試資料2(Test Data2)
$data2 = array(
'3' => 2,//除3餘2,數學式:x ≡ 2 (mod 3)
'5' => 3,//除5餘3,數學式:x ≡ 3 (mod 5)
'7' => 2 //除7餘2,數學式:x ≡ 2 (mod 7)
);
echo CRT($data1);//output 203
echo CRT($data2);//output 23
/***********************************************
* 中國餘數定理
* 注意:需要用到求得多數最小公倍數的函式
* Chinese Remainder Theory
* Note: require function LCM_NUMS()
************************************************/
function CRT($data){
$sum = 0;
foreach($data as $key => $val){
if($val == 0){
$p[] = $key;
unset($data[$key]);
}
}
foreach($data as $key => $val){
$clone = $data;
unset($clone[$key]);
$lcm = LCM_NUMS(array_keys($clone));
$i = 1;
while($find%$key == 1) {
$find = $lcm*$i;
$i++;
}
$sum += $val*$lcm;
}
return $sum%array_product(array_keys($data))*LCM_NUMS($p);
}
/**********************************************************************************
* 最小公倍數與最大公因數函式
* 原始碼來源:
* Least Common Divisor / Greatest Common Mulitple
* Source: http://www.ideashower.com/our_solutions/leastgreatest-common-mulitple-lcmgcm-in-php-and-javascript/
**********************************************************************************/
//求得兩數最大公因數(Greatest Common Divisor)
function GCD($a, $b) {
return ( $b == 0 ) ? ($a):( GCM($b, $a % $b) );
}
//求得兩數最小公倍數(Least Common Mulitple)
function LCM($a, $b) {
return ( $a / GCD($a,$b) ) * $b;
}
//求得多數最小公倍數(Least Common Mulitple For Array)
function LCM_NUMS($ar) {
if (count($ar) > 1) {
$ar[] = LCM( array_shift($ar) , array_shift($ar) );
return LCM_NUMS( $ar );
} else if(count($ar) == 1){
return $ar[0];
} else {
return 1;
}
}
文章標籤
全站熱搜
