PHP
 Computer >> コンピューター >  >> プログラミング >> PHP

【PHP】「x」または「y」で割り切れる1〜nの自然数の合計を求めるプログラム

「x」または「y」で割り切れる、1からnまでの自然数の合計を求めたい場合、単純にループで一つずつ判定する方法もありますが、等差数列の和の公式と包除原理を組み合わせれば、ループなしで効率的に計算できます。ここではその実装例を紹介します。

サンプルコード

<?php
function sum_of_nums($n_val, $x_val, $y_val)
{
    $val_1 = floor($n_val / $x_val) * ((2 * $x_val) + (floor($n_val / $x_val) - 1) * $x_val) / 2;
    $val_2 = floor($n_val / $y_val) * ((2 * $y_val) + (floor($n_val / $y_val) - 1) * $y_val) / 2;
    $val_3 = floor($n_val / ($x_val * $y_val)) * ((2 * ($x_val * $y_val)) + (floor($n_val / ($x_val * $y_val)) - 1) * ($x_val * $y_val)) / 2;
    return $val_1 + $val_2 - $val_3;
}
$n_val = 11;
$x_val = 2;
$y_val = 5;
print_r("2または5で割り切れる11以下の自然数の合計は ");
echo sum_of_nums($n_val, $x_val, $y_val);
?>

出力結果

2または5で割り切れる11以下の自然数の合計は 35

コードの解説

このプログラムでは、sum_of_numsという関数を定義し、その中で次の3つの値を計算しています。

  • $val_1: n以下の「xの倍数」の合計。この例では2の倍数(2, 4, 6, 8, 10)の合計である30になります。
  • $val_2: n以下の「yの倍数」の合計。この例では5の倍数(5, 10)の合計である15になります。
  • $val_3: n以下の「x × yの倍数」の合計。前述の2つの計算で二重に数えられた重複分に相当し、この例では10の倍数(10)の合計である10になります。

最終的な答えは「$val_1 + $val_2 − $val_3」として求められます。これは集合の重複を取り除く包除原理に基づいた考え方です。さらに、各倍数の合計は、項数k = floor(n ÷ その数)、初項・公差ともにaである等差数列の和の公式「k × (2a + (k−1) × a) ÷ 2」を利用することで、ループ処理を一切使わずに定数時間(O(1))で算出できます。そのため、nが非常に大きい場合でも高速に動作するのが大きな利点です。

実行の流れ

関数の外側では、上限となる数($n_val = 11)と、判定に使用する2つの数($x_val = 2、$y_val = 5)を定義し、これらを引数として関数を呼び出します。計算結果はprint_rおよびechoによってコンソールに出力されます。なお、1から11までの自然数のうち、2または5で割り切れる数は2, 4, 5, 6, 8, 10の6個であり、その合計は2 + 4 + 5 + 6 + 8 + 10 = 35となり、プログラムの出力と一致します。

  1. 【Python】最初のN個の自然数から合計がkで割り切れるペアの数を求めるプログラム

    問題の概要 数 n と値 k が与えられ、最初の N 個の自然数(1, 2, ..., n)を要素とする配列 A があるとします。このとき、i < j を満たす要素 A[i] と A[j] のペアのうち、その合計が k で割り切れるものの総数を求めるのが課題です。 例えば、入力が n = 10、k = 4 の場合、合計が 4 で割り切れるペアは次の 10 個存在するため、出力は 10 となります。 [(1,3), (1,7), (2,6), (2,10), (3,5), (3,9), (4,8), (5,7), (6,10), (7,9)] 解法のアプローチ この問題は、全ペアを素朴に

  2. Pythonで最初のn個の奇数の合計を求めるプログラム

    数値 n が与えられたとき、最初の n 個の正の奇数の合計を求めることを考えます。たとえば、入力が 7 の場合、出力は 49 になります。これは [1 + 3 + 5 + 7 + 9 + 11 + 13] = 49 となるためです。解決の手順この問題は、以下のステップに従って解くことができます。n が 0 と等しい場合は、0 を返します。変数を初期化します。sum := 1、count := 0、temp := 1count < n - 1 の間、次の処理を繰り返します。temp := temp + 2(次の奇数を生成)sum := sum + temp(合計に加算)count := c