코딩크리처 2024. 7. 25. 22:48

문제 이름 : 윤년


문제

연도가 주어졌을 때, 윤년이면 1, 아니면 0을 출력하는 프로그램을 작성하시오.

윤년은 연도가 4의 배수이면서, 100의 배수가 아닐 때, 또는 400의 배수일 때이다.

예를 들어,

2012년은 4의 배수이면서 100의 배수가 아니라서 윤년이다.

1900년은 100의 배수이고 400의 배수는 아니기 때문에 윤년이 아니다.

하지만, 2000년은 400의 배수이기 때문에 윤년이다.

입력

첫째 줄에 연도가 주어진다.

연도는 1보다 크거나 같고, 4000보다 작거나 같은 자연수이다.

출력

첫째 줄에 윤년이면 1, 아니면 0을 출력한다.

예제 입력 1

2000

예제 출력 1

1

예제 입력 2

1999

예제 출력 2

0

조건문 문제의 포인트는 문제를 잘 읽는것 이다.

아니 문제를 읽고 푸는데 이보다 더 잘 읽을 수 있을까?


사실 나도 알고리즘 문제를 풀면서, 문제의 관심사를 여러 갈래로 분리하는 분들을 감탄하며 본다.

하지만, 이러한 능력은 이미 가진 알고리즘 논리 구조의 존재와 함께, 문제를 찬찬히 읽는다는 공통점이 존재한다고 생각한다.


그렇다면, 문제 속에서 관심사를 추출하는 과정을 보자.

지금부터, 의식의 흐름대로 관심사를 필자가 분리 해 보겠다.


연도가 주어졌을 때, 윤년이면 1, 아니면 0을 출력하는 프로그램을 작성하시오.

윤년 이라는 조건에 의해 1 아니면 0 으로 이어진다. 따라서 이는 윤년을 따지는 조건문 이다.

윤년은 연도가 4의 배수이면서, 100의 배수가 아닐 때 또는 400의 배수일 때이다.

윤년을 판단하는 조건 이 주어졌다.

  • 4의 배수이면서, 100의 배수가 아닐 때 윤년이다.
  • 400의 배수일 때, 윤년이다.
  • 위 두가지 상황 외에는 전부 윤년이 아니다.


윤년 에 의해 1 또는 0을 출력한다는 조건,

그리고 이러한 수가 주어지면 윤년 이라고 판단한다는 조건.

이러한 문제를 풀기 위해서 2 가지 방법이 존재한다.


첫 번째, 조건문 안에 조건문을 넣는다.

두 번째, 조건문 완료 이후에 조건문을 다시 시작한다.


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));

        int year = Integer.parseInt(br.readLine());

        if(year % 400 == 0) { // 400으로 나뉠 경우 윤년.
            System.out.println("1");
        } else { // 그 외 
            if(year % 4 == 0 && year % 100 != 0) { // 4 배수이면서, 100의 배수가 아님
                System.out.println("1");
            } else { // 위의 조건들이 아니면 윤년이 아님.
                System.out.println("0");
            }
        }
    }
}

조건문 안에 또 다른 조건문을 넣는 방식으로 모든 로직을 그 자리에서 해결하는 방식이다.

하지만, 조건문 안에 또 다른 조건문을 넣어 로직을 해결하는 방식이다.

우리는 위에서 2가지 조건이 존재한다고 말했다.

만약에 이러한 조건이 n 가지 로 늘어나게 된다면, 엄청나게 중첩된 코드를 작성해야 한다.

주어지는 조건식 만큼 중괄호를 작성하고 n 배로 코드를 작성한다면, 정말로 시간낭비가 될 것이다.

물론 가독성 면에서도 엄청난 해악을 가져 올 것이다.


따라서, 조건의 흐름이 중첩되지 않고, 흘러가도록 이를 만들어 보겠다.

Answer 2 - 조건문 이후 조건문

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));

        int year = Integer.parseInt(br.readLine());

        // 윤년의 첫 번째 조건 - 4의 배수이면서, 100의 배수가 아닐 때 윤년이다.
        boolean isYun1 = (year % 4 == 0) && (year % 100 != 0);

        // 윤년의 두 번째 조건 - 400의 배수일 때 윤년이다.
        boolean isYun2 = year % 400 == 0;

        if(isYun1 || isYun2) // 윤년의 두 조건 중 하나라도 참이라면, 윤년이다.
            System.out.println("1");
        else  // 그 외에는 모두 윤년이 아니다.
            System.out.println("0");
    }
}

어떤가?

애초에 중첩문을 쓰려고 하지도 않았으며,

윤년의 최종 결과 및 조건을 두 개의 boolean 타입으로 미리 계산한다.

아주 깔끔하게 코드가 풀린 것을 볼 수 있다.


이 아티클을 읽는 독자들이 초보일 수도 있다.

따라서, 자신의 생각 흐름에 따라 조건문을 중첩 할 수도 있고,

이는 잘못된 행동은 아니다.

하지만, 더 난이도 있는 알고리즘 문제를 풀며,

혹은 복잡한 프레임워크를 이용하여 프로그램을 만들려 한다면,

내가 위에서 행했던 관심사의 분리 흐름을 이용하여 스스로의 생각을 정리하는 것이 매우매우 중요하다.

나도 배우는 중이지만, 가야 할 길은 항상 멀다는 것을 느낀다.