백준-단계별로 풀어보기/2-조건문

백준 2525 - 오븐 시계

코딩크리처 2024. 7. 31. 00:35

문제 이름 : 오븐 시계


문제

인공지능 오븐은 요리가 끝나는 시간을 분 단위로 자동적으로 계산한다.

또한, 인공지능 오븐 앞면에는 사용자에게 요리가 끝나는 시각을 알려 주는 디지털 시계가 있다.

요리를 시작하는 시각과 요리하는 데 필요한 시간이 분 단위로 주어졌을 때,

요리가 끝나는 시각을 계산하는 프로그램을 작성하시오.

입력

첫째 줄에는 현재 시각이 나온다.

현재 시각은 시 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의 내용을 활용하면 이 문제 또한 쉽게 풀수 있다.

따라서, 이번에는 두 가지 풀이법을 사용하려고 한다.

  1. 시계의 특성을 이용하여 직접 계산하는 일회성 방법
  2. 시계의 특성을 이용하는 클래스를 만들어서 계산하는 재사용 방법

클래스, 즉 오브젝트는 자바의 꽃이자 끝이다.

나중에 직접 클래스를 제작해서 풀어야 할 문제들이 존재 할 것이다.

물론 정확히 말하자면, 클래스를 제작하는 것이 더 쉬운 문제들이 많다.

클래스를 제작하지 않고 low coding 으로 모든 것을 해결 할 수 있는 것이 사실이지만,

나중에 ListMap 클래스를 무조건 사용하게 될 것이다.

단순히 사용 방법만 알고 내부 클래스 구현을 모르게 된다면 모래성 위에 건물쌓기와 비슷하다는 의견을 가지는 편이다.

따라서, 기존의 일회성 알고리즘 방식, 그리고 클래스를 이용한 관심사 분리 방식 두 개를 보여 줄 것이다.

필요 없다면 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;
    }
}
  1. 클래스 초기화 시 현재 시각을 입력한다. (시, 분)
  2. 클래스 인스턴스에 단순히 요리할 분을 메서드로 계산한다.
  3. 결과를 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;
    }
}

아직은 문제가 단순 흐름 로직으로 구현 할 수 있기에, 클래스를 구현하면서까지 해결 할 필요는 없다.

하지만, 추후 구현해야 할 알고리즘의 난이도가 높아질수록,

알고리즘의 관심사를 분리해야 할 클래스의 필요성은 더 높아줄 것이다.