二重ループ:活用編

二重ループメニュー【行列の転置・かけ算表・素数の個数・log2・スーパー鳩時計・格子点・お金の支払い・三角形の探索】

【STEP: 1】コード

reader.on('close', () => {
   const [N, K] = lines[0].split(' ').map(Number);
   const A = [];  // 元の配列
   for (let i = 1; i <= N; i++) {
      A.push(lines[i].split(' ').map(Number));
   }
  // console.table(A);
   const B = [];  // 転置配列
   for (let i = 0; i < K; i++) {
      B.push(new Array(N));  // 要素数 N 個の配列 ✕ K 行 を B に追加
      for (let j = 0; j < N; j++) {
          B[i][j] = A[j][i];  // A の 列と行を反転させて B にエクスポート
       }
   }
  // console.table(B);
   B.forEach(b => {
      console.log(b.join(' '));
   });
});
hogeちゃんの画像

転置行列(列と行を反転させた2次元配列)を作成する課題でした。2次元配列の表示は console.table() を実行するとわかりやすいですね。

【STEP: 2】コード

reader.on('close', () => {
   const N = Number(lines[0]);
   const A = lines[1].split(' ').map(Number);  // 元の値
   const B = [];  // 掛算表を保存する配列…(1)
   // const B = new Array(N);  // 掛算表を保存する配列…(2)
   for (let i = 0; i < N; i++) {  // 行のループ
      const b = [];  // 掛算表の行を保存する配列…(1)
      // const b = new Array(N);  // 掛算表の行を保存する配列…(2)
      for (let j = 0; j < N; j++) {  // 列のループ
          b.push(A[i] * A[j]);  // b に積を代入…(1)
          // b[j] = A[i] * A[j];  // b に積を代入…(2)
      }
      B.push(b);  // 掛算表の各行 b を掛算表 B に追加…(1)
      // B[i] = b;  // 掛算表の各行 b を掛算表 B に追加…(2)
   }
   // console.table(B);
   B.forEach(b => {
      console.log(b.join(' '));
   });
});
hogeちゃんの画像

2重ループで 2次元配列のかけ算表を作成しました。

【STEP: 3】コード

reader.on('close', () => {
   const N = Number(lines[0]);
   let ans = 0;  // 素数の個数
   for (let i = 2; i <= N; i++) {
      let prime = true;  // 素数であるかどうかの真偽値
      for (let j = 2; j * j <= i; j++) {
         if (i % j === 0) {  // i % j で割り切れたら…
            prime = false;  // 素数に該当しないので prime は false
            break;
         }
      }
      if (prime) {
         ans++;
     }
   }
   console.log(ans);
});
hogeちゃんの画像

prime に素数であるかどうかの真偽値を保存。prime が false にならなければans++。

【STEP: 4】コード(1)…for文とwhile文の2重ループで演算

reader.on('close', () => {
   const N = Number(lines[0]);
   let ans = 0;
   for (let i = 2; i <= N; i++) {
      let j = i;
      while (j % 2 === 0) {
         j = j / 2;
         ans++;
      }
   }
   console.log(ans);
});
hogeちゃんの画像
for文 の i の範囲は 2〜Nij に代入し while文 で j が2で割り切れればループを続けて ans を 1 加算。階乗を求めてから2で割ると Number 型 の精度(2^53)では追いつかないみたいです。

【STEP: 4】コード(2)…BigInt()を使ってみた

reader.on('close', () => {
  const N = BigInt(lines[0]);
  let n = N;
  let ans = 0;
  for (let i = 2n; i < N; i += 1n) {
    n *= i;
  }
  while (n % 2n === 0n) {
    n = n / 2n;
    ans++;
  }
  console.log(ans);
});
hogeちゃんの画像
BigInt() で階乗の積を求めてから 割り算を繰り返してみました。Number()では無理なことも BigInt() なら 大丈夫みたいです。

【STEP: 5】コード

for (let x = 0; x < 24; x++) {  // 0時〜23時
   for (let y = 0; y < 60; y++) {  // 0分〜60分
      const now = x + y;
      if (now % 5 === 0 && now % 3 === 0) {  // 3の倍数かつ5の倍数なら…
         console.log('FIZZBUZZ');  // 'FIZZBUZZ'
      } else if (now % 3 === 0) {  // 3の倍数なら…
         console.log('FIZZ');  // 'FIZZ'
      } else if (now % 5 === 0) {  // 5の倍数なら…
         console.log('BUZZ');  // 'BUZZ'
      } else {  // それ以外なら…
         console.log('');  // 鳴かない
      }
   }
}
hogeちゃんの画像

○時○分を2重ループにして 全ての時刻にアクセスしています。

【STEP: 6】コード

let ans = 0;
for (let x = 1; x < 99; x++) {
   let y = 1;
   while (x + y < 100) {  // x + y が 100未満の間
      const xy = x * y;  // x * yxy に代入
      if (x ** 3 + y ** 3 < 100000 && xy > ans) {
   // (x ^ 3) + (y ^ 3)が10万未満で かつ xyansより大きければ…
         ans = xy;  // ans を上書き
      }
      y++;
   }
}
console.log(ans);
hogeちゃんの画像

for文 と while文 の組み合わせ。

【STEP: 7】コード

reader.on('close', () => {
  const [X, Y, Z] = lines[0].split(' ').map(Number);
  let ans = Z;  // 硬貨の枚数(全て 1 円で支払うパターンで初期化)
  for (let x = 0; x * X <= Z; x++) {
    for (let y = 0; y * Y + x * X <= Z; y++) { 
      for (i = 0; i + y * Y + x <= Z; i++) {
        if (X * x + Y * y + i === Z && x + y + i < ans) {
          ans = x + y + i;
        }
      }
    }
  }
  console.log(ans);
});
hogeちゃんの画像

三重ループ で 全ての組み合わせについて調べています。

【FINAL】コード

reader.on('close', () => {
  const n = Number(lines[0]);
  let pythagoras = false;  // 三平方の定理が成り立っているかどうかの真偽値
  for (let b = 1; b <= n - 2; b++) {  // bは直角三角形の高さ
    if(pythagoras){  // pythagoras が true なら…
      break;  // ループ終了
     }
    for (let c = 1; c < n - b; c++) {  // cは直角三角形の底辺
      const a = n - (c + b);  // aは直角三角形の斜辺
      if (a * a === b * b + c * c) {  // 三平方の定理が成り立っていれば
        pythagoras = true;  // true
      }
    }
  }
  console.log(pythagoras ? 'YES' : 'NO');
});
hogeちゃんの画像

a ^ 2 = b ^ 2 + c ^ 2  】→ 三平方の定理。

コメント