Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> PHP

PHP ผลรวม N จำนวนแรกที่หาร x หรือ y ลงตัว

ตัวอย่างโค้ด

<?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
?>