프로그래머스 - 아날로그 시계

김준영·2025년 4월 13일

프로그래머스

목록 보기
16/19
post-thumbnail

문제 링크 ▶︎ 아날로그 시계

문제 파악

시침, 분침, 초침이 겹친다는 개념을 이해하는 것이 중요하다고 생각된다. 시간은 연속적이기 때문에 0도 ~ 360도 사이에서 같은 각도를 가지는 것이 아니라 각도가 역전되는 것이 겹친다의 개념으로 이해해야 한다.
처음에는 start time에서 end time까지 1초마다 시침 각도, 분침 각도, 초침 각도를 다 계산하며 각도가 역전되는지 검사를 통해서 파악하려고 했으나 시간은 연속적이기 때문에 되게 복잡했다.
그래서 다른사람의 코드를 참고해서 아래의 방법으로 풀었다.

접근 방법

  1. 우선 가장 중요하게 생각해야하는 부분은 시침과 초침, 그리고 분침과 초침이 겹치게 되는 순간은 항상 고정적으로 발생하는 시각이 있다는 것이다. 그래서 0시 0분 0초부터 시침-초침, 분침-초침이 겹치는 순간을 모두 파악한다.

  2. 시침-초침이 만나는 순간을 계산해본다면, 0시부터 1시까지 1시간을 계산해보면 시침은 30도 이동하는데 그동안 초침은 60번 돌게되는데 즉 시침이 한바퀴를 돌기 위해서는 12시간이 필요한데 초침은 그동안 720번 돌게된다. 그래서 시침과 초침은 12시간에 719(720번에 시작하는 순간 한번을 뺀다)번 만나게 된다.
    시간을 초 단위로 계산해본다면 시간(초) 719 / (60초 60분 * 12시간) 으로 계산할 수 있다.

  3. 분침과 초침이 만나는 것도 같은 개념으로 시간(분) 59 / (60초 60분)으로 계산할 수 있다.

  4. 그래서 0시 0분 0초 ~ 시작 시간까지 겹치는 횟수를 카운트하고 0시 0분 0초 ~ 끝 시간까지 겹치는 횟수를 카운트해서 빼주면 된다.
    이때 시침-분침-초침이 모두 겹치는 순간은 공통으로 계산되기 때문에 한번은 빼줘야하는데 그 순간은 0시 0분 0초 혹은 12시 0분 0초로 정해져있다.

  5. 마지막으로 시작 시간에 겹치는지만 파악하면 겹친다면 횟수를 한번 더해주고 아니라면 그대로 횟수를 리턴하면 된다.

코드 구현

class Solution {
    public int solution(int h1, int m1, int s1, int h2, int m2, int s2) {
        int answer = -1;
        int start = (h1 * 3600) + (m1 * 60) + s1;
        int end = (h2 * 3600) + (m2 * 60) + s2;
        answer = alram(end) - alram(start);
        if ((start * 59 % 3600) == 0 || (start * 719 % 43200) == 0) {
            answer += 1;
        }
        return answer;
    }
    public int alram(int t) {
        int m = t * 59 / (60 * 60); // 분침 초침은 1시간에 (60-1)번은 무조건 만남.
        int h = t * 719 / (60 * 60 * 12); // 시침과 초침은 12시간에 (720-1)번은 무조건 만남.
        int common = (t >= (60 * 60 * 12)) ? 2 : 1;
        return m + h - common;
    }
}

개선 사항

처음에는 각도로 계산을 했는데 생각보다 굉장히 복잡했다. 코드에 대한 어려움보다 문제를 이해하고 머릿속으로 시뮬레이션을 돌리는 과정이 어려워서 비슷한 유형의 문제를 많이 경험해봐야겠다.

profile
junyoun9dev@gmail.com

0개의 댓글