JavaScriptで時刻の数字を再利用して最も近い次の時刻を求める方法
問題の概要
本記事では、「HH:MM」形式で時刻を表す文字列を受け取り、その文字列に含まれる数字を再利用して最も近い次の時刻を作成するJavaScript関数を紹介します。数字の再利用回数に制限はありません。
例として、関数への入力と出力は以下のようになります。
入力
const time = '19:34';
出力
const output = '19:39';
出力の解説
数字「1, 9, 3, 4」から選んで作れる次に近い時刻は「19:39」で、これは5分後の時刻です。「19:33」を採用しない理由は、この時刻が現在から23時間59分後になってしまうためです。
解法のコード例
以下が実際の実装コードです。
const time = '19:34';
const findClosestTime = (time = '') => {
const [a, b, c, d] = [time[0], time[1], time[3], time[4]].map(x => Number(x));
const sorted = [a, b, c, d].sort((x, y) => x - y);
const d2 = sorted.find(x => x > d);
if (d2 > d) {
return `${a}${b}:${c}${d2}`;
}
const c2 = sorted.find(x => x > c && x <= 5);
const min = Math.min(a, b, c, d);
if (c2 > c) {
return `${a}${b}:${c2}${min}`;
}
const b2 = sorted.find(x => x > b && a * 10 + x <= 24);
if (b2 > b) {
return `${a}${b2}:${min}${min}`;
}
const a2 = sorted.find(x => x > a && x <= 2);
if (a2 > a) {
return `${a2}${min}:${min}${min}`;
}
return `${min}${min}:${min}${min}`;
};
console.log(findClosestTime(time));出力結果
19:39
アルゴリズムの解説
この実装では、時刻を構成する4桁(時の十の位・一の位、分の十の位・一の位)について、分の一の位から優先的に、元の数字より大きい最小の数字へ置き換えられるかを順に確認していきます。
- 分の一の位を大きくできる場合 → 数分後の時刻を返します。
- 分の十の位(0〜5の範囲)を大きくできる場合 → 分の一の位を最小の数字に戻して返します。
- 時の一の位(合計が24時を超えない範囲)を大きくできる場合 → 分を最小の数字2桁にして返します。
- 時の十の位(0〜2の範囲)を大きくできる場合 → 時の一の位と分をすべて最小の数字にして返します。
- どの桁も置き換えられない場合 → 最小の数字4つで構成された時刻、つまり翌日の最も早い時刻を返します。
この優先順位に従って桁を置き換えていくことで、常に「現在から最も近い未来の時刻」を効率よく求められるのがこのアルゴリズムのポイントです。
-
new演算子を使ってJavaScriptコンストラクタを作成する方法
JavaScriptでは、通常の関数を「new」演算子と組み合わせて呼び出すことで、コンストラクタとして機能させることができます。これにより、同じ構造を持つ複数のオブジェクトを効率的に生成できます。以下に、new演算子を使用してJavaScriptのコンストラクタを作成するコード例を紹介します。 サンプルコード <!DOCTYPE html> <html lang=ja> <head> <meta charset=UTF-8 /> <meta name=viewport content=width=device-width, initial
-
JavaScriptで不正な時間文字列(HH:MM:SS)を正規化して修正する方法
JavaScriptでは、「HH:MM:SS」形式の時間文字列を扱う場面がよくあります。しかし、時間の加算処理などで計算ミスが発生すると、分や秒が60を超えてしまう「壊れた」時間文字列が生成されることがあります。この記事では、そうした不正な時間文字列を正しく正規化する方法を解説します。 課題:壊れた時間文字列とは 今回求められるのは、JavaScriptで「HH:MM:SS」形式の時間文字列を受け取り、必要な修正を加えた上で、正しい時間文字列として返す関数を作成することです。 問題になるのは、加算処理のバグによって、次のような不正な値が含まれてしまうケースです。 MM(分)の部分が60を超え