본문 바로가기

Tech/Problem Solving

[프로그래머스] PCCP 기출문제 - 아날로그 시계 (Java)

 

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

풀이

 

시작하는 시간부터 끝나는 시간동안 초침이 몇 번 분침과 시침을 지나치는지에 대한 문제다.

 

(1)

시작시간과 끝시간 사이를 간격에서 횟수를 구하는 것 보다는 (0시0분0초~끝나는 시간동안 마주친 횟수)에 (0시0분0초~시작하는 시간동안 마주친 횟수)를 빼는 방법을 이용하면 문제를 훨씬 단순하게 해결할 수 있다.

 

주의할 점은 이렇게 차이를 계산하는 방법은 시작시간 자체가 알람이 울리는 시간이라면 이 횟수까지 제외해버린다. 때문에 마지막에 현재 시간 또한 알람이 울릴 수 있는지 체크해서 횟수에 반영해줘야 한다.

 

초침이 시계 한 바퀴를 도는 시간은 60초

분침이 시계 한 바퀴를 도는 시간은 60분 -> 3,600초 

시침이 시계 한 바퀴를 도는 시간은 12시간 -> 43,200초

 

분침이 한 바퀴 도는 동안 초침은 60(=3600초/60초)바퀴를 돈다

분침이 한 바퀴 돌 동안(3600초) 초침과 59번 마주친다. 60번이 아닌 이유는 분침도 이 시간동안 제자리에만 있는 게 아니기 때문!

즉, 분침과 만나서 울리는 알람은 3600초 동안 59번 울리며, 3600/59 초마다 1회 울린다.

 

시침이 한 바퀴 도는 동안 초침은 720(=43200초/60초)바퀴를 돈다

== 시침이 한 바퀴 돌 동안(43200초) 초침과 719번 마주친다. 720번이 아닌 이유는 마찬가지로 시침 또한 움직이고 있기 때문!

즉 분침과 만나서 울리는 알람은 43200초 동안 719번 울리며, 43200/719 초마다 1회 울린다.

 

(2)

문제를 "n초 동안 몇 번 울리는가?"로 바꿔서 생각해 볼 수 있겠다.

 

분침의 경우는 n % (3600/59) 번 마주치고

시침의 경우는 n % (43200/719) 번 마주친다

 

(이 식이 이해가 안된다면 10초마다 알람이 울린다고 했을 때 1분동안 몇 번 울리는 지 생각해보면 된다. 1분 / 10초 = 6번 이라고 계산하듯이 n초에 알람 1회가 울리는 초를 나누면 된다)

 

(3)

예외 사항이 있다. 분침과 시침이 겹쳐있는 경우다. 이 때는 분침과 시침이 각각 겹쳐도 알람은 1번만 울려야한다. 분침과 시침, 그리고 초침이 모두 겹치는 경우는 12시 정각 뿐이다. 우리는 (1)에서 0시0분0초에 시작하기로 했기 때문에 00시 정각과 12시 정각 두 시각에 대해 고려해야한다. 

n초가 43200초(12시0분0초)보다 작다면 00시만 고려해서 1회, 크다면 12시까지 포함해 2회가 중복된 셈이니 이 횟수만큼 빼줘야 한다.

 

코드

import java.util.*;

class Solution {
    public int solution(int h1, int m1, int s1, int h2, int m2, int s2) {
        int answer = -1;
        
        int startSec = parseToSec(h1, m1, s1);
        int endSec = parseToSec(h2, m2, s2);
        
        // (1)
        answer = countAlrams(endSec) - countAlrams(startSec);
        answer += alramNow(startSec) ? 1 : 0;
        
        return answer;
    }
    
    private int parseToSec(int hour, int minute, int second) {
        return hour * 60 * 60 + minute * 60 + second;
    }
    
    private int countAlrams(int seconds) {
    	// (2)
        int minuteAlrams = seconds * 59 / 3600;
        int hourAlrams = seconds * 719 / 43200;
        
        // (3)
        int duplicatedAlrams = 43200 <= seconds ? 2 : 1;
        
        return minuteAlrams + hourAlrams - duplicatedAlrams;
    }
    
    private boolean alramNow(int seconds) {
        return seconds * 59 / 3600 == 0 || seconds * 719 % 43200 == 0;
    }
}

 

 

도움 받은 경로

 

[PCCP 기출문제] 3번 / 아날로그 시계 자바

문제 풀이가 빡세다..아날로그 시계처음에 설마 각도로 풀겠어라고 생각해서 다른 방식 찾다가 결국 각도로 했는데 너무 복잡했다.그래서 풀이를 찾아봤는데 진짜 깔끔하게 푼 코드가 있어서

velog.io

 

반응형