ループメニュー2【各桁の和・2で何回割れる?・10 進数から2進数に変換・約数の列挙 ほか】
【各桁の和】コード
reader.on('close', () => {
const N = Number(lines[0]);
let n = N;
let sum = 0; // 出力値を 0 で初期化
while (n > 0) { // n が 0 より大きい間
sum += n % 10; // 余りを加算
n = Math.floor(n / 10); // n を n ÷ 10(端数切り捨て)で上書き
}
console.log(sum);
});
下1桁目は n mod 10, 下2桁目は n ÷ 10(端数切り捨て) mod 10…
100の場合…
(100 mod 10) + {(100 ÷ 10) mod 10} + {(100 ÷ 10÷10) mod 10}
【カウント変数を使った計算】コード
reader.on('close', () => {
const N = Number(lines[0]);
const M = lines[1].split(' ').map(Number);
for (let i = 1; i <= N; i++) {
console.log(M[i - 1] * i);
}
});
配列の 1 番目 の index は [0] なので M[i - 1] * i
を出力しています。
【2 で何回割れる?】コード
reader.on('close', () => {
const N = Number(lines[0]);
let ans = 0;
let n = N;
while (n % 2 === 0) { // n が 2 で割り切れる間…
n /= 2; // n ÷ 2 で n の値を上書き
ans++; // ans を加算
}
console.log(ans);
});
n が 2 で割り切れたら n ÷
2 で n の値を上書きして ans を 1 加算しました。
【任意の数で何回割れる?】コード
reader.on('close', () => {
const [N, M] = lines[0].split(' ').map(Number);
let ans = 0;
let n = N;
while (n % M === 0) { // n が M で割り切れる間…
n /= M; // n ÷ M で n の値を上書き
ans++;
}
console.log(ans);
});
割る数が M になったので (n % M) ・( n /= M) になりました。
【10 進数から 2 進数に変換】コード 1/3
reader.on('close', () => {
const N = Number(lines[0]);
console.log(N.toString(2)); // 数値.toString(2)=>数値を2進数の文字列に変換
});
toString(変換したい基数)
で数値を(変換したい基数)の文字列に変換できました。ビルトイン関数を使うとスッキリ。
【10 進数から 2 進数に変換】コード 2/3
reader.on('close', () => {
const convert_base = (decimal, base) => { // decimal(10進数)を base進数に変換
let result = 0; // 計算結果
let digit = 1; // 計算する位
while (decimal > 0) { // decimal が 0 以上の間…
result += decimal % base * digit; // result に decimal mod base ✕ 位 を加算
decimal = Math.floor(decimal / base); // decimal => decimal ÷ base(端数切捨)
digit *= 10; // 計算する位を上げる
}
return result;
};
const N = Number(lines[0]);
console.log(convert_base(N, 2)); // N を 2進数に変換
});
while文 を使った関数で 基数変換しています。
ループメニューなので…(^-^*)
【10 進数から 2 進数に変換】コード 3/3
reader.on('close', () => {
const convert_base = (decimal, base, result, digit) => {
if (!decimal) { // decimal が 0 になったら…
return result; // result を返して処理終了
}
// 関数内で関数呼び出し (decimal が 0 になるまで繰り返される)
return convert_base(Math.floor(decimal / base), base, result + decimal % base * digit, digit * 10);
};
const N = Number(lines[0]);
console.log(convert_base(N, 2, 0, 1));
});
再起関数でも同じ実行結果になりました。
【10 進数から M 進数に変換】コード 1/3
reader.on('close', () => {
const [N, M] = lines[0].split(' ').map(Number);
console.log(N.toString(M)); // N を M 進数に変換
});
【STEP: 5】と同様 N.toString(M)) で N を M 進数に変換。
【10 進数から M 進数に変換】コード 2/3
reader.on('close', () => {
const convert_base = (decimal, base) => { // 基数変換のアロー関数
let result = 0; // 計算結果
let digit = 1; // 計算する位
while (decimal > 0) { // decimal が 0 以上 の間
result += decimal % base * digit; // result に decimal mod base ✕ 位 を加算
decimal = Math.floor(decimal / base); // decimal => decimal ÷ base(端数切捨)
digit *= 10; // 計算する位を上げる
}
return result; // ループを抜けたら result を返して処理終了
}
const [N, M] = lines[0].split(' ').map(Number);
console.log(convert_base(N, M)); // N を M 進数に変換
});
【STEP: 5】と同様 while文 を使ったアロー関数で 基数変換しています。
【10 進数から M 進数に変換】コード 3/3
reader.on('close', () => {
const convert_base = (decimal, base, result, digit) => {
if (!decimal) { // decimal が 0 になったら…
return result; // result を返して処理終了
}
// 関数内で関数呼び出し (decimal が 0 になるまで繰り返される)
return convert_base(Math.floor(decimal / base), base, result + decimal % base * digit, digit* 10);
};
const [N, M] = lines[0].split(' ').map(Number);
console.log(convert_base(N, M, 0, 1));
});
【STEP: 5】と同様 再起関数でも同じ実行結果になりました。
【N が M ずつ増えたときにいつ K を越える?】コード
reader.on('close', () => {
const [N, M, K] = lines[0].split(' ').map(Number);
let n = N;
let count = 0; // 足した回数
while (n <= K) { // n が K を超えるまで…
n += M; // n に M を加算
count++; // count を 1 増やす
}
console.log(count);
});
n が K 以下の間 M を加算。足した回数を出力。
【毎日増加するお金】コード
reader.on('close', () => {
const [A, B] = lines[0].split(' ').map(Number);
let days = 0; // 日数
let a = A; // 所持金
while (a <= B) { // 所持金 が B 未満の間
a += Math.floor(a / 10); // 所持金 を 10% 増やす
days++;
}
console.log(days);
});
a が B 以上になるまで days を 1 追加。
Task
【階乗の計算】コード
reader.on('close', () => {
const N = Number(lines[0]);
let result = 1; // 計算結果(階乗)
for (let i = 1; i <= N; i++) {
result *= i; // result を result×i で上書き
}
console.log(result);
});
10 の 階乗 = 1×2×3×4×5×6×7×8×9×10。
【階乗の末尾に 0 はいくつ付く?】コード 1/2
reader.on('close', () => {
const N = Number(lines[0]);
const factorial_0 = (n) => { // n の階乗の「末尾の0の数」を計算
let result = 0; // n が 5 で割れる回数
while (n > 0) { // n が 0 以上の間
result += Math.floor(n / 5); // result に n が 5 で割れる回数を加算
n = Math.floor(n / 5); // n を n ÷ 5 で上書き
}
return result;
};
console.log(factorial_0(N));
});
【階乗の末尾に 0 はいくつ付く?】コード 2/2
reader.on('close', () => {
const N = Number(lines[0]);
const factorial_0 = (n, result) => {
if(!n){ // n が 0 になれば…
return result; // result を返して処理終了
}
// 関数内で関数呼び出し (n が 0 になるまで繰り返される)
return factorial_0(Math.floor(n / 5),result + Math.floor(n / 5));
};
console.log(factorial_0(N, 0));
});
1/2 を再起処理を使って書き換えてました。
【加算された数列の最大値】コード
reader.on('close', () => {
const N = Number(lines[0]);
const A = lines[1].split(' ').map(Number);
for (let i = 1; i <= N; i++) {
A[i - 1] += i;
}
A.sort((s, b) => b - s); // A を 降順に並べ替え
console.log(A[0]);
});
配列を大きい順に並べ替えて先頭の値を出力しました。
【加算された数列の最小値】コード
reader.on('close', () => {
const N = Number(lines[0]);
const A = lines[1].split(' ').map(Number);
for (let i = 1; i <= N; i++) {
A[i - 1] += i;
}
A.sort((s, b) => s - b); // A を 昇順に並べ替え
console.log(A[0]);
});
配列を小さい順に並べ替えて先頭の値を出力しました。
【1 はどこにある?】コード
reader.on('close', () => {
const N = Number(lines[0]);
const A = lines[1].split(' ').map(Number);
for (let i = 1; i <= N; i++) {
if (A[i - 1] === 1) { // A[i - 1] が 1 なら…
console.log(i); // i を出力
}
}
});
A の要素を一つ一つ調査してA[i – 1] が 1 なら i を出力。
Task
【約数の個数】コード
reader.on('close', () => {
const N = Number(lines[0]);
let count = 0;
for (let i = 1; i <= N; i++) {
if (N % i === 0) { // N が i で割り切れれば…
count++; // count を加算
}
}
console.log(count);
});
N が i (1〜N) で割り切れれば count を加算しています。
【約数の列挙】コード
reader.on('close', () => {
const N = Number(lines[0]);
for (let i = 1; i <= N; i++) {
if (N % i === 0) { // N が i で割り切れれば…
console.log(i); // i を出力
}
}
});
N が i (1〜N) で割り切れれば i を出力しています。
コメント