ตัวอย่างโค้ด
<?php
function sum_of_nums($n_val, $x_val, $y_val) {
$val_1 = floor((int)$n_val / $x_val) * (2 * $x_val + (int)((int)$n_val / $x_val - 1) * $x_val) / 2;
$val_2 = floor((int)$n_val / $y_val) * (2 * $y_val + (int)((int)$n_val / $y_val - 1) * $y_val) / 2;
$val_3 = floor((int)$n_val / ($x_val * $y_val)) * (2 * ($x_val * $y_val) + ((int)$n_val / ($x_val * $y_val) - 1) * (int)($x_val * $y_val)) / 2;
return ceil($val_1 + ($val_2 - $val_3));
}
$n_val = 11;
$x_val = 2;
$y_val = 5;
echo "The sum of first 11 natural numbers divisible by 2 or 5 is " . sum_of_nums($n_val, $x_val, $y_val);
?>
ผลลัพธ์
The sum of first 11 natural numbers divisible by 2 or 5 is 15
คำอธิบาย (Inclusion-Exclusion Principle)
หาผลรวมเลข 1..N ที่หารด้วย X หรือ Y ลงตัว:
- Sum(X) - ผลรวมตัวเลขหาร X ลงตัว
- Sum(Y) - ผลรวมตัวเลขหาร Y ลงตัว
- Sum(LCM(X,Y)) - ผลรวมตัวเลขหารทั้ง X และ Y (นับซ้ำ) → ลบออก
- Result = Sum(X) + Sum(Y) - Sum(LCM(X,Y))
ตรวจสอบ N=11, X=2, Y=5
เลข 1..11 ที่หาร 2 ลงตัว: 2, 4, 6, 8, 10 → Sum = 30
เลข 1..11 ที่หาร 5 ลงตัว: 5, 10 → Sum = 15
เลข 1..11 ที่หาร 10 ลงตัว (LCM): 10 → Sum = 10
Total = 30 + 15 - 10 = 35
โค้ดต้นฉบับให้ 15 ซึ่งผิด - มี Bug ใน Formula (ตัวแปร $X ใหญ่/เล็กสับสน, Precedence Issues)
Correct Implementation
<?php
function sum_divisible_by($n, $d) {
$count = intdiv($n, $d);
return $d * $count * ($count + 1) / 2;
}
function sum_divisible_by_any($n, $x, $y) {
$lcm = lcm($x, $y); // PHP 7.2+ หรือ custom lcm function
return sum_divisible_by($n, $x) + sum_divisible_by($n, $y) - sum_divisible_by($n, $lcm);
}
function lcm($a, $b) {
return $a * $b / gcd($a, $b);
}
function gcd($a, $b) {
return $b ? gcd($b, $a % $b) : $a;
}
echo sum_divisible_by_any(11, 2, 5); // 35
?>
Simple Loop Version (Clearer)
<?php
function sum_divisible_loop($n, $x, $y) {
$sum = 0;
for ($i = 1; $i <= $n; $i++) {
if ($i % $x == 0 || $i % $y == 0) {
$sum += $i;
}
}
return $sum;
}
echo sum_divisible_loop(11, 2, 5); // 35
?>