Skip to content

Commit a01490c

Browse files
authored
Merge pull request #81 from myoshi2891/dev/macbook_pro
Dev/macbook pro
2 parents 50d1a8e + 9cadc0e commit a01490c

10 files changed

Lines changed: 1223 additions & 0 deletions

File tree

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// 以下に、**Go 1.20.6** を用いて **2つの正の整数 `A`, `B` の最小公倍数(LCM)を求める実装**を提示します。
2+
3+
// ---
4+
5+
// ## ✅ 処理概要
6+
7+
// * **入力**:標準入力(`fmt.Scan`)で `A B` を読み取る(1 ≤ A, B ≤ 10⁹)
8+
// * **出力**:LCM(最小公倍数)
9+
// * **型**:`int64` を使用(必要に応じて `math/big` 使用可)
10+
// * **GCD**:ユークリッドの互除法
11+
// * **LCM**:`a / GCD(a, b) * b`(順番に注意)
12+
13+
// ---
14+
15+
// ## ✅ Go実装(関数型、型付き、計算量考慮)
16+
17+
package main
18+
19+
import (
20+
"fmt"
21+
"os"
22+
)
23+
24+
/**
25+
* gcd は 2つの整数 a, b の最大公約数を返します。
26+
* ユークリッドの互除法を使用。
27+
*
28+
* @param a int64 - 整数 a
29+
* @param b int64 - 整数 b
30+
* @return int64 - aとbの最大公約数
31+
*/
32+
func gcd(a int64, b int64) int64 {
33+
for b != 0 {
34+
a, b = b, a%b
35+
}
36+
return a
37+
}
38+
39+
/**
40+
* lcm は 2つの整数 a, b の最小公倍数を返します。
41+
* lcm(a, b) = a / gcd(a, b) * b の順に計算してオーバーフローを防ぎます。
42+
*
43+
* @param a int64 - 整数 a
44+
* @param b int64 - 整数 b
45+
* @return int64 - aとbの最小公倍数
46+
*/
47+
func lcm(a int64, b int64) int64 {
48+
return (a / gcd(a, b)) * b
49+
}
50+
51+
/**
52+
* main は標準入力から a, b を読み取り、
53+
* 最小公倍数を標準出力に出力します。
54+
*
55+
* 入力例: 25 30
56+
* 出力例: 150
57+
*/
58+
func main() {
59+
var a, b int64
60+
_, err := fmt.Scan(&a, &b)
61+
if err != nil {
62+
fmt.Fprintln(os.Stderr, "入力エラー:", err)
63+
return
64+
}
65+
66+
result := lcm(a, b)
67+
fmt.Println(result)
68+
}
69+
70+
// ## ✅ 入出力例
71+
72+
// ```
73+
// 入力: 25 30
74+
// 出力: 150
75+
76+
// 入力: 998244353 998244853
77+
// 出力: 996492287418565109
78+
// ```
79+
80+
// ---
81+
82+
// ## ✅ 計算量とリソース消費
83+
84+
// | 項目 | 内容 |
85+
// | ------ | ------------------------------------------ |
86+
// | 時間計算量 | O(log(min(a, b))): `gcd` のユークリッド互除法 |
87+
// | メモリ使用量 | O(1): 数個の `int64` 変数のみ |
88+
// | 最大出力対応 | `int64` → 約 `9.2 * 10^18` まで安全(64bit) |
89+
// | 注意 | `a = 10^9, b = 10^9` でも LCM = `10^18` → OK |
90+
91+
// ---
92+
93+
// ## ✅ オーバーフローについて
94+
95+
// `int64` 上限は約 `9.2e18`。本問題の LCM の最大値は:
96+
97+
// ```
98+
// LCM(10^9, 10^9) = 10^9
99+
// × (10^9 / GCD(10^9, 10^9)) = 10^9 × 1 = 10^9
100+
// ```
101+
102+
// または、異なる素数の場合は `10^9 * 10^9 = 1e18` → `int64` で安全!
103+
104+
// ---
105+
106+
// ## ✅ 解説図(例:LCM(25, 30))
107+
108+
// ```text
109+
// Step 1: GCD(25, 30)
110+
// 30 % 25 = 5
111+
// 25 % 5 = 0 → GCD = 5
112+
113+
// Step 2: LCM = (25 / 5) * 30 = 5 * 30 = 150
114+
// ```
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// 以下に、Node.js (`fs` モジュール使用) を用いて制限内で最小公倍数(LCM)を求める実装を提示します。
2+
3+
// ## ✅ 特徴
4+
5+
// * 入力: `fs.readFileSync("/dev/stdin", "utf8")`(AtCoderなどで利用可)
6+
// * 最小公倍数計算: `LCM(a, b) = a / GCD(a, b) * b`(オーバーフロー対策済)
7+
// * 使用アルゴリズム: **ユークリッドの互除法** によるGCD計算
8+
9+
// ---
10+
11+
// ### ✅ 実装コード(Node.js, JavaScript)
12+
13+
const fs = require("fs");
14+
15+
/**
16+
* 最小公倍数を求める関数
17+
* @param {bigint} a - 正整数 A
18+
* @param {bigint} b - 正整数 B
19+
* @returns {bigint} - aとbの最小公倍数(LCM)
20+
*/
21+
function lcm(a, b) {
22+
return (a / gcd(a, b)) * b;
23+
}
24+
25+
/**
26+
* 最大公約数(GCD)をユークリッドの互除法で求める関数
27+
* @param {bigint} a - 整数 a
28+
* @param {bigint} b - 整数 b
29+
* @returns {bigint} - aとbの最大公約数
30+
*/
31+
function gcd(a, b) {
32+
while (b !== 0n) {
33+
const temp = b;
34+
b = a % b;
35+
a = temp;
36+
}
37+
return a;
38+
}
39+
40+
// 入力読み込み
41+
const input = fs.readFileSync("/dev/stdin", "utf8").trim().split(" ");
42+
const A = BigInt(input[0]);
43+
const B = BigInt(input[1]);
44+
45+
// 最小公倍数を出力
46+
console.log(lcm(A, B).toString());
47+
48+
// ### ✅ 実行性能
49+
50+
// * **時間計算量**: O(log(min(A, B)))(ユークリッドの互除法)
51+
// * **空間計算量**: O(1)
52+
// * **BigInt**を用いることで **2^53 を超える範囲の整数にも対応**(例: `998244353 * 998244853`)
53+
54+
// ---
55+
56+
// ### ✅ サンプル入出力確認
57+
58+
// **入力:**
59+
60+
// ```
61+
// 25 30
62+
// ```
63+
64+
// **出力:**
65+
66+
// ```
67+
// 150
68+
// ```
69+
70+
// **入力:**
71+
72+
// ```
73+
// 998244353 998244853
74+
// ```
75+
76+
// **出力:**
77+
78+
// ```
79+
// 996492287418565109
80+
// ```
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
<!-- 以下に、**PHP 8.2.8** 向けに、**2つの整数 A, B の最小公倍数(LCM)を求める関数ベースの実装**を示します。
2+
3+
---
4+
5+
## ✅ 仕様概要
6+
7+
* **入力**:標準入力(例: `fgets(STDIN)`)で与えられる2つの整数 A, B(1 ≤ A, B ≤ 10⁹)
8+
* **出力**:最小公倍数(LCM)
9+
* **計算式**:
10+
11+
$$
12+
\text{LCM}(A, B) = \frac{A}{\gcd(A, B)} \times B
13+
$$
14+
15+
※ オーバーフロー防止のために順序に注意(`A / GCD` を先に行う)
16+
17+
---
18+
19+
## ✅ PHP 実装(型明示・関数化)
20+
21+
<?php
22+
23+
/**
24+
* 最大公約数(GCD)をユークリッドの互除法で求める
25+
*
26+
* @param int $a - 正の整数
27+
* @param int $b - 正の整数
28+
* @return int - aとbの最大公約数
29+
*
30+
* 時間計算量:O(log(min(a, b)))
31+
*/
32+
function gcd(int $a, int $b): int {
33+
while ($b !== 0) {
34+
$temp = $b;
35+
$b = $a % $b;
36+
$a = $temp;
37+
}
38+
return $a;
39+
}
40+
41+
/**
42+
* 最小公倍数(LCM)を求める関数
43+
*
44+
* @param int $a - 正の整数
45+
* @param int $b - 正の整数
46+
* @return int|string - aとbの最小公倍数(オーバーフロー時にはstring)
47+
*
48+
* 処理順に注意:a / GCD → b を掛ける(int型上限対策)
49+
*/
50+
function lcm(int $a, int $b): int|string {
51+
$g = gcd($a, $b);
52+
$div = intdiv($a, $g);
53+
$product = $div * $b;
54+
55+
// オーバーフロー対策(PHP_INT_MAXを超えた場合はstringに)
56+
if ($product > PHP_INT_MAX) {
57+
return bcmul((string)$div, (string)$b); // 多倍長整数で計算
58+
}
59+
60+
return $product;
61+
}
62+
63+
/**
64+
* メイン処理(標準入力を読み取り、LCMを出力)
65+
*
66+
* @return void
67+
*/
68+
function main(): void {
69+
$line = trim(fgets(STDIN));
70+
[$a, $b] = array_map('intval', explode(' ', $line));
71+
72+
$result = lcm($a, $b);
73+
echo $result . PHP_EOL;
74+
}
75+
76+
main();
77+
78+
// ## ✅ 実行例
79+
80+
// **入力:**
81+
82+
// ```
83+
// 25 30
84+
// ```
85+
86+
// **出力:**
87+
88+
// ```
89+
// 150
90+
// ```
91+
92+
// ---
93+
94+
// ## ✅ 性能解析
95+
96+
// | 項目 | 内容 |
97+
// | --------- | --------------------------------------- |
98+
// | 時間計算量 | O(log(min(A, B))) (GCD部分がボトルネック) |
99+
// | 空間計算量 | O(1)(GCD・LCM として数個の整数のみ使用) |
100+
// | メモリ使用 | 数十バイト(変数 + 一時計算) |
101+
// | オーバーフロー対応 | `PHP_INT_MAX` 超えを検知し `bcmul()`(多倍長演算)使用 |
102+
103+
// ---
104+
105+
// ## ✅ 多倍長処理の注意点
106+
107+
// * `PHP_INT_MAX ≒ 9223372036854775807`(64bit環境)
108+
// * 例:`998244353 * 998244853 = 996492287418565109` → **OK**
109+
// * ただし、`10^9 * 10^9 = 10^18` は string 処理推奨
110+
111+
// ---
112+
113+
// ## 🔚 備考
114+
115+
// * 必要に応じて `gmp` 関数での置換も可能です(例:`gmp_gcd`, `gmp_lcm`)
116+
// * `bcmath` は標準で使えるため環境依存しにくいです

0 commit comments

Comments
 (0)