時分秒重合問題
今天晚上和同事吃飯時聊起了以前初中接觸過的話題:24 小時內時針、分針和秒針重合幾次。
吃完飯之後回來捋了下思路:
- 假設時針的角速度為 ω(
ω = 1 / 120 (度/秒)
),那麼分針的角速度就為 12ω,秒針的角速度為 720ω - 假設時針和分針在 t 秒後重合,那麼分針在 t 時間內走過的角度減去時針在 t 時間內走過的角度,得到的結果肯定是 360 的整數倍
- 根據上面的規則,可以算出時針和分針重合的時間 -- 集合 A
- 同理也能算出分針和秒針重合的時間 -- 集合 B
- 那麼時針、分針及秒針三者重合的時間就是集合 A、B 的交集
具體實現程式碼如下:
/**
* 時間補 0
*
* @param time
*/
const padTime = (time: number) => {
return time < 10 ? `0${time}` : `${time}`;
};
/**
* 將秒轉換為 HH:mm:ss 格式
*
* @param seconds
*/
const convert = (seconds: number) => {
const hour: number = Number.parseInt(`${seconds / (60 * 60)}`),
minute: number = Number.parseInt(`${(seconds - hour * 60 * 60 ) / 60}`),
second: number = Math.round(seconds - hour * 60 * 60 - minute * 60);
return `${padTime(hour)}:${padTime(minute)}:${padTime(second)}`;
}
/**
* 計算重疊時間
*
* @param speedA
* @param speedB
*/
const overlap = (speedA: number, speedB: number) => {
const seconds: number = 24 * 60 * 60,
speed1Circles: number = seconds * speedA / 360; // A 速度一天走的圈數
let times: string[] = [];
for (let i = 0; i < speed1Circles - 1; i++) {
/**
* speedA 在 t 時間內走過的角度 - speedB 在 t 時間內走過的角度 = 360 的整數倍
*
* speedA * t - speedB * t = k * 360
* t = (k * 360) / (speedA - speedB)
*
*/
const time = (i * 360) / Math.abs(speedA - speedB); // 重合的時間
if (time < (3600 * 24)) {
times.push(convert(time));
}
}
return times;
}
複製程式碼
// 時分秒角速度(度/秒)
const hSpeed: number = 1 / 120,
mSpeed: number = 0.1,
sSpeed: number = 6;
const timesA: string[] = overlap(mSpeed, hSpeed), // 時針和分針重合時間
timesB: string[] = overlap(sSpeed, mSpeed), // 分針和秒針重合時間
result: string[] = timesA.filter(num => timesB.includes(num)); // 二者取交集
console.log(timesA.length); // 22
console.log(timesB.length); // 1416
console.log(result); // [ '00:00:00', '12:00:00' ]
複製程式碼
根據運算結果可知,時針、分針、秒針三者在 24 小時內重合了 2 次,重合時間分別是在 0 點以及 12 點。