二重ループメニュー【行列の転置・かけ算表・素数の個数・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(' '));
});
});
転置行列(列と行を反転させた2次元配列)を作成する課題でした。2次元配列の表示は console.table()
を実行するとわかりやすいですね。
Task
【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(' '));
});
});
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);
});
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);
});
for文 の i の範囲は 2〜N。i を j に代入し 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);
});
…
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(''); // 鳴かない
}
}
}
○時○分を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 * y を xy に代入
if (x ** 3 + y ** 3 < 100000 && xy > ans) {
// (x ^ 3) + (y ^ 3)が10万未満で かつ xy が ansより大きければ…
ans = xy; // ans を上書き
}
y++;
}
}
console.log(ans);
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);
});
三重ループ で 全ての組み合わせについて調べています。
【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');
});
【a ^ 2 = b ^ 2 + c ^ 2 】→ 三平方の定理。
コメント