0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

終了判定 2 と while  おまけ:対数

Posted at

今回もpaizaの条件分岐の問題を解いたけど、久しぶりにwhileを使ったコードを書いた!
あと、おまけで対数についてまとめてみたから見てみてね!



問題概要

2つの整数 N, K が与えられ、N を 2 倍していって K 以上になるまでの操作回数 M を求める。


入力例:

2 18

出力例:

4




✅ OK例(while版)

const rl = require('readline').createInterface({ input: process.stdin });

rl.once('line', (input) => {
    const [N, K] = input.split(' ').map(Number);
    let current = N;  // 現在のNの値
    let count = 0;    // 操作回数(M)

    // NがK以上になるまで、2倍を繰り返す
    while (current < K) {
        current *= 2;
        count++;
    }

    console.log(count);  // 最終的な操作回数Mを出力

    rl.close();
});

current < K の間は 2倍 し続け、カウントは K に到達した時点でストップ!



❌ NG例

let count = 0;
while (N <= K) {
    N *= 2;
    count++;
}

N <= K だと、N === K のときも、もう1回ループしてしまう。
つまり「ちょうど K のとき」にも2倍されて1回余計にカウントされる。



✅他パターン:for

const rl = require('readline').createInterface({ input: process.stdin });

rl.once('line', (input) => {
    const arr = input.split(' ').map(Number); 

    let N = arr[0];
    const K = arr[1];

    // 回数カウントは1から開始(1回目の操作から)
    for (let i = 1; ; i++) {
        N *= 2; // Nを2倍

        if (N >= K) { // K以上になったら回数出力
            console.log(i);
            break; // ループ終了
        }
    }

    rl.close(); 
});
  • for (let i = 1; ; i++) で無限ループしつつ、操作回数をカウント。
  • N を 2倍 したあと K 以上かチェック。
  • K 以上になった時点で console.log(i) し、break で終了。



📝気づきメモ

  • 無限ループ + break でもいけるけど、while文での明示的な条件設定の方が直感的で安全かも。
  • whileループでの条件設計力:何を条件にしてどこで止めるか
  • 初期値と境界条件の扱いの大切さ(NとKが等しい時など)

📒 まとめ

最初は「ただ倍にするだけでしょ」と思ってたけど、意外に論理的な考え方が試されて面白かった!




僕の失敗談(´;ω;`)と解決法🐈






💡おまけ:対数(log)

const rl = require('readline').createInterface({ input: process.stdin });

rl.once('line', (input) => {
    const [N, K] = input.split(' ').map(Number); 

    const M = Math.ceil(Math.log2(K / N)); 
    console.log(M); 

    rl.close(); 
});

💡Math.ceil(Math.log2(K / N)) を分かりやすく

✅ ステップ1:「2倍していく」とはどういうこと?

たとえば、はじめの数が N = 2 だったとする。
そして K = 18 を超えるまで、どんどん 2倍 する。

1回目 → 2 × 2 = 4  
2回目 → 4 × 2 = 8  
3回目 → 8 × 2 = 16  
4回目 → 16 × 2 = 32(ここで18を超えた!)

👉 このとき、4回で18を超えた。



✅ ステップ2:「じゃあ、何回2倍したらいいかを早く計算できないかな?」

毎回2倍して調べるのはちょっと大変…。

そこで登場するのが「log(対数:logarithm)」という考え!

対数とは、ある数を何乗すると指定の数になるかを表す指数のこと。



✅ ステップ3:log2ってなに?

log2(x)」は、こう考える👇


「2を何回かけたら x になる?」

たとえば:

  • log2(8) → 答えは 3(なぜなら 2×2×2 = 8)
  • log2(32) → 答えは 5(2 を 5 回かけると 32)



✅ ステップ4:「K / N」はなぜ出てくる?

※ K / N = K ÷ N

さっきの例で K = 18, N = 2 だったよね。


「N を 2倍して、いつ K を超えるか?」

ってことは、KN で割って「何倍すればいいか」を先に調べればいいんだ!

K / N = 18 / 2 = 9

じゃあ、「2を何回かけたら9を超えるのか?」と考える。

log2(9) ≒ 3.17(3回じゃ足りない、4回は必要)



✅ ステップ5:Math.ceil() は「切り上げ」

Math.ceil(3.17) → 4 にする
(小数点があったら、1つ上の整数にする)

なぜなら、3回じゃ足りないから!



✅ 🔁 全体をまとめて読むと…

Math.ceil(Math.log2(K / N))

はこういう意味👇


N を 2倍 して K を超えるには、何回やればいい?
その回数をちゃんと整数に切り上げて出してね!」



✅ まとめ

  • log2(x) → 2 を何回かけたら x になる?
  • K / N → N をどれだけ大きくすれば K になる?
  • ceil(x) → 小数点があっても上の数に切り上げるよ
0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?