본문 바로가기

CodingTest/Programmers

[ 프로그래머스 ] 2016년

/  제출 1  /

def solution(a, b):
    # 윤년: 2월이 29일까지인 해 +1일
    # 한 달 날짜 수:31일: 1,3,5,7,8,10,12 +3일 | 30일: 4,6,9,11 +2일
    thirty_one = [1,3,5,7,8,10,12]
    thirty = [4,6,9,11]
    # 1월 1일 금 +28(+3일) 2월 화+28(+1일) 3월 수
    # 3,1,3,2 = 9일/7일 = 2일 => 5월은 일부터 시작(0) + 24/7 = 3 (-1) 화 
    # 5월 24일 화
    day = ['SUN','MON','TUE','WED','THU','FRI','SAT']
    passing_date = 0
    num = 0
    for i in range(a-1):
        if i+1 in thirty_one:
            num = 3
        elif i+1 in thirty:
            num = 2
        elif i+1 == 2:
            num = 1
        passing_date += num
    passed_day = passing_date%7 
    month_start = (5+passed_day)%7
    day_key = month_start + (b % 7) - 1
    answer = day[day_key]
    
    return answer
채점 결과
정확성: 64.3
합계: 64.3 / 100.0
 
3,8,11,12,14 실패 ( 런타임 에러 )
 
아이고 윤년 문제 고등학교 때부터 싫어했는데 벗어나질 못하네요. 문제 이해하는데조차 시간 좀 걸렸습니다.
그래서인지 다 푼 다음에 검토 안 하고 제출했더니 와우 역시나 전체 테케 통과 못하네요. 항상 목표는 일단 테케 풀어내는 게 아니라 " 어떤 경우에도 " 다 맞게 풀이하는 것을 목표로 다시 잡고 수정해봅니다.

 

' 오류 테스트 케이스 검출 '

: 4월 13일 => 수요일 나와야하는데, list out of range 에러를 띄우고 죽었습니다. 왜일까요 고쳐보겠습니다.

 

일단 테스트케이스 몇 개 더 넣어서 실험해보니 4월 12일도 같은 문제가 납니다. 사용한 list는 thirty_one, thirty, day 3개뿐인데 앞의 2개는 문제사항이 없을 것 같은 로직입니다.

해서 day에서 값이 어떻게 들어갈 지 오류 테케를 이용해 손으로 직접 값을 검사해봤습니다.

day안에 들어갈 값이 8이 됩니다. 우리 day는 인덱스가 0-7까지밖에 없기 때문에 당연히 인덱스 범위 에러가 난 겁니다.

 

아래와 같은 마지막 과정을 거치지 않은 것이 문제입니다. 마지막에 해당 월에 대한 날짜를 계산 한 뒤 아래와 같이 7로 나눠 요일을 구할 수 있도록 범위 안에 들어올 인덱스처럼 나눴어야 했습니다.

    day_key = (month_start + (b % 7) - 1)%7
    answer = day[day_key]
 

/  제출 2  /

def solution(a, b):
    # 윤년: 2월이 29일까지인 해 +1일
    # 한 달 날짜 수:31일: 1,3,5,7,8,10,12 +3일 | 30일: 4,6,9,11 +2일
    thirty_one = [1,3,5,7,8,10,12]
    thirty = [4,6,9,11]
    # 1월 1일 금 +28(+3일) 2월 화+28(+1일) 3월 수
    # 3,1,3,2 = 9일/7일 = 2일 => 5월은 일부터 시작(0) + 24/7 = 3 (-1) 화 
    # 5월 24일 화
    day = ['SUN','MON','TUE','WED','THU','FRI','SAT']
    passing_date = 0
    for i in range(a-1):
        if i+1 in thirty_one:
            passing_date += 3
        elif i+1 in thirty:
            passing_date += 2
        elif i+1 == 2:
            passing_date += 1
    passed_day = passing_date%7 
    month_start = (5+passed_day)%7
    day_key = (month_start + (b % 7) - 1)%7
    answer = day[day_key]
    
    return answer
채점 결과
정확성: 100.0
합계: 100.0 / 100.0
 
수정한 코드로 제출하니 클리어됐습니다.
 

다른 분들 풀이 보면서 항상 어떻게 이렇게 변수명을 잘 지었지, 어떻게 이렇게 나와 달리 짰지, 어떻게 이런 라이브러리를 알아서 여기에 활용할 생각을 했지. 신기하고 재밌을 때가 많습니다.

이 문제는 유독 창의성이 돋보이는 코드들이 많아서 다른 분들 풀이 보며 정말 재밌었습니다.

 

그 중 참고해서 다시 보고 배울만한 풀이만 가져왔습니다.

/  다른 분들 풀이  /

def getDayName(a,b):
    months = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    days = ['FRI', 'SAT', 'SUN', 'MON', 'TUE', 'WED', 'THU']
    return days[(sum(months[:a-1])+b-1)%7]

print(getDayName(5,24))

months를 한 번에 작성하신 게 제 것보다 낫고, 이를 각각 가져오는 것보다 sum으로 이전 것들을 한 번에 처리하는게 정말 훨씬 직관적이고 깔끔한 방식이었습니다. 

그리고 저는 7로 나누는것을 계속 반복했는데 사실 총합을 구하고 마지막에 한 번에 나눠도 무방한데 단계별로 생각하다보니 이를 놓친 것 같습니다.

 


 

실수 할까봐 아직은 계산이 중복되더라도 문제에서 주어지는 데이터 값이 너무 커서 에러 뜨더라도 차근차근 단계별로 구현하고 있습니다.

하지만, 빨리 이런 해결방식을 숙지해서 속도를 높인다면 이런 식의 간단한+ 효율적인 방식으로 리팩토링해서 제출하도록 노력해야겠습니다.

더 실력이 늘면 한 번에 이와 같이 떠올려 구현할 수도 있겠죠? 많이 연습해야겠습니다.