약간은 재밌는 방법으로 해결하였다. 프로그래밍적 관점보다는 시계에 관련된 특성을 조금 활용해서 직접 풀어보았다.
시침,분침,초건이 만나는 조건을 잘 생각하면 수학적으로 해결이 가능하다.
기본적으로 1분에 초침이 한바퀴를 돌며 시침,분침 두개를 한번씩 만난다고 가정해보자
그런데 잘생각해보면 59분 -> 00분으로 갈때는 초침과 분침이 만나지 않는데 59분인 경우 초침이 한바퀴를 돌아서 00분이 되는 경우에만 만나기 때문이다.
같은 원리로 분침,초침또한 11시->12시로 이동할때는 겹치지 않게된다.
즉 59분->00분으로 갈때마다 (한시간마다) 만나는 횟수를 1씩 빼주고 12시 00분인 경우에만 특이처리를 해주면 된다.
[조금더 쉬운 설명!!~]
0시0분0초 ~ 23시59분59초까지 시,분,초침이 만나는 횟수를 구한다생각해자. (마지막 예제)
단순하게 하루는 24*60 = 1440분 즉, 1분당 시,분침이 초침과 1번씩 만나므로
1440 * 2 = 2880번 만난다고 가정해보자.
방금 말한대로 59분 -> 00분으로 갈때 분침,초침은 만나지 않기에 -24의 카운트를 해준다.
또 11시59분 -> 12시 와 23시59분 -> 00시 로갈때 시침,초침은 만나지 않기에 -2의 카운트를 해준다.
0시0분0초 , 12시0분0초는 시-분-초 침이 만나서 카운트를 하나로만 치게 되기에 -2의 카운트를 해준다.
따라서 마지막 예제의 답은 2880 - 28 = 2852가되게 된다.
고려해야할 점은 시작 시간과 끝나는 시점이 유동적이라는 점이다.
따라서 0시0분0초부터 h1:m1:s1 까지 만나는 횟수와 0시0분0초부터 h2:m2:s2까지 만나는 횟수를 구해서 빼주는 방식을 응용했다.
이경우 시작하는 초는 세면 안되므로 시작하는 초가 카운트에 세지는 0시0분0초와 12시0분0초만 예외처리해주어야 한다.
시,분,초침이 만나게 되는 횟수에 관련 아이디어도 필요하지만 시작 시간과 끝나는 시간에 해당되는 분에서 몇번 만나는지 체크하는게 어려웠는데 이를 끝나는시간만 고려하여 두 횟수를 빼주는 아이디어가 좋았던 것 같다.
function solution(h1, m1, s1, h2, m2, s2) {
//0시0분0초 ~ h:m:s까지 겹치는 횟수
const getCntFromMidNight = (h,m,s) => {
const [hDegree,mDegree,sDegree] = [(h*30+m*0.5+s*0.5/60)%360,(m*6+s*0.1)%360,s*6]
let ret = -1 //0시0분0초는 분에 한번이므로 -1로 시작
// 마지막 분의 상태를 계산
if(sDegree>=mDegree) ret +=1
if(sDegree>=hDegree) ret +=1
ret += (h*60+m)*2 //분당 2번씩 만난다고 계산
ret -= h //59분 -> 0분일때는 분침과 만나지 않음
if(h>=12) ret -= 2 // 11시59분59초 -> 12시인경우 분,초침과 만나지않고 12시에 2번이아닌 1번만 만나는걸로 처리
return ret
}
//0시~주어진시간까지 횟수를 구한 이후 빼면 됨
let ret = getCntFromMidNight(h2,m2,s2) - getCntFromMidNight(h1,m1,s1)
if((h1===0||h1===12)&&m1===0&&s1===0) ret +=1 //0시와 12시인경우에만 예외적으로 1씩 더해줌
return ret
}
'FrontEnd > 프로그래머스' 카테고리의 다른 글
[JS] 다단계 칫솔 판매 (0) | 2023.12.07 |
---|---|
[JS] 110옮기기 (1) | 2023.12.06 |
[JS] 수레 움직이기 (1) | 2023.12.01 |
[JS] 석유 시추 (1) | 2023.12.01 |
[JS] 붕대 감기 (0) | 2023.11.27 |