2023. 11. 24. 01:19ㆍIT/TIL
오늘의 TIL은 알고리즘 코드카타의 문제 2016년으로
https://school.programmers.co.kr/learn/courses/30/lessons/12901
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
2016년의 a월 b일이 주어지는 경우
해당 날짜가 어떤 요일인지를 알려주는 코드를 작성하는 것이다.
기본적으로 주어지는 정보는 2016년 1월 1일은 금요일이고 윤년(2월 29일까지 있는 년도)이며
a와 b에 들어가는 숫자는 실제로 있는 날짜 정보라는 것이다.
이 문제를 푸는 과정에서 간단하게 라이브러리를 사용하여
DateTime date = new DateTime(2016, a, b);
answer = date.DayOfWeek.ToString();
answer = answer.Substring(0, 3);
3줄로도 풀이할 수 있는 문제이지만,
이 라이브러리를 사용하지 못한다면 어떻게 풀어야될까 라는 의문에서 문제 풀이를 진행하였는데,
내가 생각했던 로직의 흐름은 아래와 같다.
1. enum을 사용하여 해당하는 요일을 불러오게 해보자.
2. 2016년 1월 1일을 기준으로 해당하는 날짜가 몇일 차이나는지 계산하자.
3. 날짜의 차이에서 7로 나눠서 요일이 반복되게 하여 enum을 사용하자.
4. 2016년 1월 1일은 금요일이므로 enum의 1에 해당하는 값을 FRI로 시작하자
의 흐름이였다.
결과 코드는 아래와 같은데
enum DayName
{
THU,
FRI,
SAT,
SUN,
MON,
TUE,
WED,
}
int a = 5;
int b = 24;
int c = a - 1;
string result = "";
int cnt = 0;
for (int i = c; i > 0; i--)
{
if (i > 7)
{
if (i % 2 == 0)
cnt++;
}
else
if (i % 2 == 1)
cnt++;
}
c = a > 2 ? c * 30 - 1 : c * 30;
cnt = (cnt + c + b) % 7;
result = Enum.GetName(typeof(DayName), cnt);
우선 enum을 이용하여 날짜의 이름을 정했는데,
2016년 1월 1일은 금요일이므로 7로 나눈 나머지가 1이 되면 FRI가 나오도록
0번 인덱스에는 THU를 입력하는 방식으로 진행하였다.
실제로는 주어지는 a와 b 값이 있으므로 비워두면 되지만,
visual studio에서 작업하기 위해 임의로 a와 b값을 입력하고 진행했다.
for 문을 통해 a월까지 날짜 수를 더하게 만들었는데,
a월 b일인 경우 (a -1)월까지의 날짜와 b일을 더하는 것이므로
c = a - 1로 c를 선언하여 진행하였다.
7월까지 홀수 달은 31일, 짝수 달은 30일 이지만
8월부터는 짝수 달이 31일, 홀수 달이 30일이 되기에
for 문 안에 if문을 넣었다.
for 문을 나온 뒤에는 2월달만 29일(윤년이므로)이므로 삼항연산자를 통해 2월보다 큰 경우 1을 빼도록 조정했다.
이후에 최종적으로 1월 1일부터 a월 b일까지의 일 수를 구한 뒤에 7로 나눈 나머지로 숫자를 구한 뒤에
result에 Enum을 사용하여 해당하는 이름을 가져오도록 코딩했다.
코드가 문제가 없이 잘 작동하는 것으로 판단하여 결과를 제출했지만,
5번과 6번 케이스에서 계속해서 틀린 답이 나오기에 이를 해결하기위해 여러가지로 고민했지만,
해결하지 못하여 튜터님께 질문하러 갔었다.
이를 튜터님과 해결하는 과정은 전체 날짜를 출력하여 문제가 있는 부분을 찾아보자 라는 생각으로
아래의 코드를 작성했다.
for (int k = 1; k< 13; k++)
{
for (int j = 1; j< 32; j++)
{
a = k;
b = j;
int c = a - 1;
for (int i = c; i > 0; i--)
{
if (i > 7)
{
if (i % 2 == 0)
cnt++;
}
else
if (i % 2 == 1)
cnt++;
}
c = c > 2 ? c * 30 - 1 : c * 30;
cnt = (cnt + c + b) % 7;
result = Enum.GetName(typeof(DayName), cnt);
Console.WriteLine(cnt);
Console.WriteLine($"{a} {b} {result}");
cnt = 0;
}
}
}
1월 1일부터 12월 31일까지 이중 for문을 사용하여 a월 b일 어떤 요일인지 출력하는 코드로
튜터님 앞에서 작성하다보니 조금 급하게 작성한 감이 있지만, 정상적으로는 작동하는 코드이다.
여기서 발견한 내 코드의 문제점은 c = a - 1을 한 뒤에 c를 가지고 2월인지 판단햇던 문제로
a가 3월인 경우 c = c > 2 ? c * 30 - 1 : c * 30; 의 삼항연산자를 이용하면
c = 2가 되므로 원래 원했던 3 > 2가 아니라 2 = 2가 되므로 No쪽으로 빠지게 되므로 오류가 나게된다.
이 문제를 해결하는 과정에서 반례를 찾는데 어려움을 겪었는데
튜터님께 질문하고 해결하는 과정에서 전체 케이스를 도입하는 방법을 사용하였다.
혼자서 열심히 고민했었을 때는 생각하지 못했던 방법이라
알고리즘 문제를 푸는 방법을 하나 더 배운 것으로 느껴서 성장한 기분을 느꼈다.
'IT > TIL' 카테고리의 다른 글
20231127_atan(게임수학) (0) | 2023.11.27 |
---|---|
20231124_카드뭉치(프로그래머스) (1) | 2023.11.24 |
20231122_기록_팀 프로젝트 회고 (2) | 2023.11.22 |
20231121_기록_유니티에서의 Static (1) | 2023.11.21 |
20231120_기록_C# Console에서의 글 정렬 (1) | 2023.11.20 |