SW Expert Academy
SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!
swexpertacademy.com
<나의 풀이>
문제를 보자마자 파이썬을 처음 배웠을 때가 생각이 났다.
당시 교수님께서 내주신 과제도 달력과 관련된 문제였는데,
역시나 달력 문제는 코딩의 기본문제인가 보다.
우선 연월일 순서로 구성된 8자리의 날짜를 입력으로 받는다.
여기서 중요한 점은 유효성을 판단해야 한다는 것이다.
말 그대로 제대로 된 날짜가 들어왔는지 확인이 필요한 것이다.
이것은 조건문을 활용하여 우선적으로 판단할 수 있을 것이다.
생각해본 -1이 출력되는 경우는 다음과 같다.
- 입력값이 8자리가 아닐 경우
- 입력값이 8자리이지만, 4번째 자리가 0이나 1이 아닐 경우
- 입력값이 8자리이고 4번째 자리가 0이나 1이지만, 각 월에 해당하는 일 수가 아닐 경우
생각할 부분이 많아 보인다.
또한 입력값은 총 테스트 케이스의 개수 T와 그다음 줄부터는 각 테스트 케이스가 주어진다.
이것은 지난 '몫과 나머지 출력' 문제 풀이 방식 format을 활용해야겠다.
SW Expert Academy - 2029. 몫과 나머지 출력하기(D1)
SW Expert Academy SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요! swexpertacademy.com 연산을 하는 문제인데, 이번 문제는 테스트 케이스의 입력값이 여러 개다. 또한 각 수는 1
raccoonn9094.tistory.com
우선 주어진 테스트 케이스를 활용하여 입력값을 받고 그것을 정상적으로 받았는지 출력해보자.
T = int(input()) ##총 테스트 케이스 수 입력
for i in range(1,T+1): ##총 테스트 케이스 수만큼 반복문 실행
a = input() ##각 테스트 케이스를 a에 저장
print(a) ##각 테스트 케이스를 출력
22220228
20150002
01010101
20140230
11111111
입력값을 정상적으로 받았고 이제 이를 활용하면 된다.
먼저 들어온 테스트 케이스에 대해서 8자리인지 확인해보자.
이때 출력되는 결괏값들의 자료형은 <str>이다.
즉, 문자열로 출력되는 것이다.
이 문자열의 길이를 확인하는 함수가 있다.
바로 len()이다.
그렇다면 이번에는 각 출력물의 길이를 확인해보자.
8
8
8
8
8
예제 테스트 케이스는 다행히 모두 8자리이다.
하지만 지난 문제들과 다르게 이번에는 테스트 케이스에 맞춰서 작성하지 않고 유효성 검사를 할 수 있게 조건을 추가해보자.
그리고 다음으로는 8자리일 경우 4번째 자리의 수가 0이나 1인지 확인하는 부분도 넣어보자.
T = int(input())
for i in range(1,T+1):
a = input()
if len(a) == 8:
if a[4] == '0' or a[4] == '1':
print(1)
else: print(-1)
else: print(-1)
이것도 정상적으로 돌아간다. (13월~19월에 대한 유효성 판단은 넣지 않았다...)
지금까지는 테스트 케이스 모두가 유효한 상태이다.
마지막으로 '일'에 대한 유효성 판단을 해야 한다.
가장 먼저 들었던 생각은 더티 코딩이다.
각 월에 해당하는 숫자의 범위에 해당하지 않는다면 -1을 출력하게 하는 것이다.
하지만 12개의 월에 대해서 비교하는 것이기 때문에 좋은 방법은 아닌 듯하다.
각 월의 일수에 대한 자료를 구분하면
(1,3,5,7,8,10,12) -> 31일
(4,6,9,11) -> 30일
(2) -> 28일
이 자료를 활용하기 위해 7번째, 8번째 문자를 추출한 후 이를 정수형으로 바꾸는 방법은 어떨까?
여기까지 시도를 하다 보니 7번째, 8번째 문자를 따로 추출한 후 다시 합치는 과정이 매우 비효율적이라는 생각이 들었다.
그러던 중 입력받은 문자열을 잘라서 여러 개의 변수에 저장하는 방법이 생각이 났다.
T = int(input())
case1 = [1,3,5,7,8,10,12]
case2 = [4,6,9,11]
case3 = [2]
for i in range(1,T+1):
a = input()
year = int(a[0:3])
month = int(a[4:5])
day = int(a[6:7])
if len(a) == 8:
if (month < 1) or (month > 12):
print(-1)
else:
if month in case1:
if day < 1 or day >31:
print(-1)
elif month in case2:
if day < 1 or day >30:
print(-1)
elif month in case3:
if day < 1 or day >28:
print(-1)
else:
print(-1)
else: print(-1)
문자열을 슬라이싱 한 것은 문자열이기 때문에 숫자 비교를 활용하려면 int형으로 바꿔주는 것이 필요하다.
또한 각 월에 해당하는 일수를 비교하기 위해서 위에서 작성한 자료를 활용한 조건문을 작성해주었다.
계속 풀다 보니깐 문제가 복잡해져서 해설을 적으며 푸는 것이 어려웠다.
그래서 다 풀어내고 리뷰를 해봐야겠다.
T = int(input())
case_1 = [1,3,5,7,8,10,12]
case_2 = [4,6,9,11]
case_3 = [2]
for i in range(1,T+1):
a = input()
year = a[:4]
month = a[4:6]
day = a[6:]
if len(a) == 8:
if (int(month) >= 1) and (int(month) <= 12):
if int(month) in case_1 and int(day)>=1 and int(day)<=31:
print('#{} {}/{}/{}'.format(i,year,month,day))
elif int(month) in case_2 and int(day)>=1 and int(day)<=30:
print('#{} {}/{}/{}'.format(i,year,month,day))
elif int(month) in case_3 and int(day)>=1 and int(day)<=28:
print('#{} {}/{}/{}'.format(i,year,month,day))
else: print('#{} {}'.format(i,-1))
else: print('#{} {}'.format(i,-1))
else: print('#{} {}'.format(i,-1))
입력값 문자열 a를 먼저 year, month, day로 슬라이싱 한다.
각 슬라이싱한 변수들은 str이므로 case_# 리스트와 비교하거나 정수와 크기 비교를 할 때 int()를 사용하여 자료형을 바꿔줘야 한다.
또한 리스트 안에 있는지 확인하는 'in'을 사용하여 입력 테스트 케이스의 month가 어떤 case_#에 해당하는지에 따라서 조건을 다르게 주었다.
이 부분이 조금 더 개선되면 깔끔한 코딩이 되지 않을까 싶다.
결과적으로 출력 시 format을 활용하여 문제에서 요구하는 출력 조건을 맞춰주었다.
지금까지 풀어본 D1 문제 중에 가장 오래 걸리고 지저분하게 완성한 느낌이 강하다.
조금 더 다듬을 수 있을 것 같고, 좋은 방법이 있을 것만 같다.
그러나 format이나 반복문, 조건문을 여러 번 활용한 것을 통해 제대로 연습할 수 있었다.
실제 시험에서도 막히는 부분이 생길 수 있는데, 계속 붙잡고 있기보다는 새로운 방법은 없는지 고민해봐야 시간을 절약할 수 있다.
값진 문제였다!
'개발 > SWEA (D1) 문제 풀이' 카테고리의 다른 글
SW Expert Academy - 2063. 중간값 찾기(D1) (0) | 2022.11.11 |
---|---|
SW Expert Academy - 2058. 자릿수 더하기(D1) (0) | 2022.11.11 |
SWEA 문제 풀이SW Expert Academy - 2050. 알파벳을 숫자로 변환(D1) (0) | 2022.11.10 |
SW Expert Academy - 2047. 신문 헤드라인(D1) (0) | 2022.11.10 |
SW Expert Academy - 2046. 스탬프 찍기(D1) (0) | 2022.11.10 |
댓글