백준 2525 - 오븐 시계
문제 이름 : 오븐 시계
문제
인공지능 오븐은 요리가 끝나는 시간을 분 단위로 자동적으로 계산한다.
또한, 인공지능 오븐 앞면에는 사용자에게 요리가 끝나는 시각을 알려 주는 디지털 시계가 있다.
요리를 시작하는 시각과 요리하는 데 필요한 시간이 분 단위로 주어졌을 때,
요리가 끝나는 시각을 계산하는 프로그램을 작성하시오.
입력
첫째 줄에는 현재 시각이 나온다.
현재 시각은 시 A
(0 <= A
<= 23) 와, 분 B
(0 <= B
<= 59) 가 정수로 빈칸을 사이에 두고 순서대로 주어진다.
두 번째 줄에는 요리하는 데 필요한 시간 C
(0 <= C
<= 1,000) 가 분 단위로 주어진다.
출력
첫째 줄에 종료되는 시각의 시 와 분 을 공백을 사이에 두고 출력한다.
(단, 시는 0 에서 23 까지의 정수, 분은 0 부터 59 까지의 정수이다.)
(디지털 시계는 23시 49분에서 1분이 지나면 0시 0분이 된다.)
예제 입력 1
14 30
20
예제 출력 1
14 50
예제 입력 2
17 40
80
예제 출력 2
19 0
예제 입력 3
23 48
25
예제 출력 3
0 13
내가 제작했던 아티클 백준 2884의 내용을 활용하면 이 문제 또한 쉽게 풀수 있다.
따라서, 이번에는 두 가지 풀이법을 사용하려고 한다.
- 시계의 특성을 이용하여 직접 계산하는 일회성 방법
- 시계의 특성을 이용하는 클래스를 만들어서 계산하는 재사용 방법
클래스, 즉 오브젝트는 자바의 꽃이자 끝이다.
나중에 직접 클래스를 제작해서 풀어야 할 문제들이 존재 할 것이다.
물론 정확히 말하자면, 클래스를 제작하는 것이 더 쉬운 문제들이 많다.
클래스를 제작하지 않고 low coding 으로 모든 것을 해결 할 수 있는 것이 사실이지만,
나중에 List
와 Map
클래스를 무조건 사용하게 될 것이다.
단순히 사용 방법만 알고 내부 클래스 구현을 모르게 된다면 모래성 위에 건물쌓기와 비슷하다는 의견을 가지는 편이다.
따라서, 기존의 일회성 알고리즘 방식, 그리고 클래스를 이용한 관심사 분리 방식 두 개를 보여 줄 것이다.
필요 없다면 Answer 1
만 봐도 충분하다.
Answer 1 - 일회성 계산 알고리즘 방식
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int H = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int cookMinute = Integer.parseInt(br.readLine());
int cookHour = cookMinute / 60;
cookMinute %= 60;
// M + cookMinute 값이 변동하기 전,
// 이 두 변수의 합이 60을 넘어 한 시간을 추가해야 되는지 미리 체크 및 계산.
H = (M + cookMinute >= 60) ? H + 1 : H;
// 분 계산 - 삼항 연산
M = (M + cookMinute >= 60) ? (M + cookMinute) - 60 : M + cookMinute;
// 시간 계산 - 삼항 연산
H = (H + cookHour < 24) ? H + cookHour : (H + cookHour) - 24;
System.out.println(H + " " + M);
}
}
기본적으로, 삼항 연산 을 적극 이용하여 가독성을 한껏 끌어올린 모습을 볼 수 있다.
입력값으로 주어지는 것은 현재 시간, 현재 분, 요리하게 될 시간 이다.
이 중, 요리하게 될 시간은 분 으로 주어지기에, 현재 시각에서 추가하게 될 시간을 얻기 위해 /60
을 행한다.
삼항 연산(삼중문) 에 대한 것을 더 알고 싶다면,
바로 이전 아티클, 백준 2884 를 참고하면 된다.
Answer 2 - 클래스를 이용한 재사용 코드 생성 방식
클래스를 만들어 시간 계산에 대한 관심사를 따로 분리하기로 했으니,
먼저 어떤 기능 을 수행할 지, 어떤 속성 을 가지고 있어야 할 지 명확히 정해야 한다.
속성
우리가 만들 클래스는 시간을 계산하는 클래스이다.
먼저, 기준이 될 시간 을 초기화해야 한다.
따라서, 가지게 될 속성은 현재 시각 을 가져야 한다. (시, 분)
기능
문제에서 구현하라는 기능은 현재 시각에서 얼마나 지났는지 구현하는 것이다.
얼마나 많은 시간이 지나는지는, 분 으로 주어진다.
따라서, 입력값을 분 으로 받고, 이를 계산하여 클래스의 속성인 현재 시각 을 변경 하는 함수가 필요하다.
이것이면 된다.
우리는 위에서 스스로 필요한 관심사항과 필요사항에 대한 내용을 기록했다.
이를 토대로 클래스를 먼저 제작하면 된다.
class Oven{
private int currHour; // 현재 시
private int currMinute; // 현재 분
public Oven(int hour, int minute){
this.currHour = hour;
this.currMinute = minute;
}
// 몇 분이 걸리는지만 주어질 때 - ex 600 분
public void spendTime(int spendMinute){
int spendHour = spendMinute / 60;
spendMinute %= 60;
this.currHour =
(this.currMinute + spendMinute < 60) ?
this.currHour : (this.currHour + 1);
this.currMinute =
(this.currMinute + spendMinute < 60) ?
this.currMinute + spendMinute : this.currMinute + spendMinute - 60;
this.currHour =
(this.currHour + spendHour < 24) ?
this.currHour + spendHour : this.currHour + spendHour - 24;
}
// 시, 분을 소비했을 때, 해당 시각을 계산하는 메서드
// ex - 5 시간, 56분 등..
public void spendTime(int spendHour, int spendMinute){
this.currHour =
(this.currMinute + spendMinute < 60) ?
this.currHour : (this.currHour + 1);
this.currMinute =
(this.currMinute + spendMinute < 60) ?
this.currMinute + spendMinute : this.currMinute + spendMinute - 60;
this.currHour =
(this.currHour + spendHour < 24) ?
this.currHour + spendHour : this.currHour + spendHour - 24;
}
public int getCurrHour(){
return this.currHour;
}
public int getCurrMinute(){
return this.currMinute;
}
}
- 클래스 초기화 시 현재 시각을 입력한다. (시, 분)
- 클래스 인스턴스에 단순히 요리할 분을 메서드로 계산한다.
- 결과를
get..()
메서드로 받아 출력한다.
Answer 2 - 클래스로 관심사 분리 및 재사용성 확보
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int H = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
// 현재 시각을 오븐에 입력
Oven oven = new Oven(H, M);
int cookMinute = Integer.parseInt(br.readLine());
oven.spendTime(cookMinute);
System.out.println(oven.getCurrHour() + " " + oven.getCurrMinute());
}
}
class Oven{
private int currHour; // 현재 시
private int currMinute; // 현재 분
public Oven(int hour, int minute){
this.currHour = hour;
this.currMinute = minute;
}
// 몇 분이 걸리는지만 주어질 때 - ex 600 분
public void spendTime(int spendMinute){
int spendHour = spendMinute / 60;
spendMinute %= 60;
this.currHour =
(this.currMinute + spendMinute < 60) ?
this.currHour : (this.currHour + 1);
this.currMinute =
(this.currMinute + spendMinute < 60) ?
this.currMinute + spendMinute : this.currMinute + spendMinute - 60;
this.currHour =
(this.currHour + spendHour < 24) ?
this.currHour + spendHour : this.currHour + spendHour - 24;
}
// 시, 분을 소비했을 때, 해당 시각을 계산하는 메서드
// ex - 5 시간, 56분 등..
public void spendTime(int spendHour, int spendMinute){
this.currHour =
(this.currMinute + spendMinute < 60) ?
this.currHour : (this.currHour + 1);
this.currMinute =
(this.currMinute + spendMinute < 60) ?
this.currMinute + spendMinute : this.currMinute + spendMinute - 60;
this.currHour =
(this.currHour + spendHour < 24) ?
this.currHour + spendHour : this.currHour + spendHour - 24;
}
public int getCurrHour(){
return this.currHour;
}
public int getCurrMinute(){
return this.currMinute;
}
}
아직은 문제가 단순 흐름 로직으로 구현 할 수 있기에, 클래스를 구현하면서까지 해결 할 필요는 없다.
하지만, 추후 구현해야 할 알고리즘의 난이도가 높아질수록,
알고리즘의 관심사를 분리해야 할 클래스의 필요성은 더 높아줄 것이다.