22.08.11 TIL

옵주비·2022년 8월 11일
0

정글 수료식

오늘은 대망의 정글 수료일이었다. 이 날이 올 줄이야..

어제 밤에 갑자기 반 친구들과 PC방을 갔다가 새벽 5시에나 들어오는 바람에, 점심 즈음에야 기상했다. 5월 이후로는 늦어도 10시 전후론 일어난거 같은데, 기분이 이상했다. 정글에서 이렇게 게임하는 것도 처음이라 그것도 이상했고..... :) 오늘은 점심을 먹고, 이후에는 강의실에서 짐을 세 차례에 걸쳐서 빼고, 강의실 청소를 하니까 수료식 시간이 거의 임박했다. 그러다보니 시간이 많지는 않았지만, 알고리즘 1문제는 빼놓지 않고 풀었다.

좀 전에 수료식을 다녀왔는데, 와 이제 끝이라는게 실감이 난다. 잠시 후에 뒷풀이 회식이 있어서, 얼른 TIL을 작성하고 가려고 한다. 고기고기 ❤.❤ 아무래도 마지막이니까 술을 좀 마실테니... 이렇게 모두가 모이는건 오늘이 마지막이라고 생각하니 싱숭생숭하다.

아, 참고로 정글 회고는 주말 이후에 여유롭게 작성할 계획이다. 아무래도 지난 5개월을 다 돌아보려면... 그리고 정글 회고글은 티스토리나 다른 블로그에도 업로드할 생각이라, 퇴고를 빡세게 할 생각이다.

어쨌든 오늘의 알고리즘 문제를 얼른 정리해보자!

알고리즘

프로그래머스 - 모의고사

오늘 풀어본 문제는 모의고사라는 문제다.
레벨 1치고는 상당히 긴 문제길이..
수학을 포기한 사람 3명이 있고, 그 3명이 답을 찍을 때 결과적으로 누가 1등을 할지를 찾아내야 하는 문제였다. 자세히 살펴보면 3명은 각자 자신만의 노하우가 있는듯하다. 다들 일정한 패턴에 따라서 답을 찍고 있다는 것을, '찍는 방식'에서 파악할 수 있었다.

그리하여 간단하게 세 사람의 패턴을 각각 리스트로 만들었다. 총 문제 갯수가 몇개이든, 결국 3명의 수포자는 각각 5개, 8개, 10개로 구성된 패턴 내에서 돌려가며 찍는다. 1번 문제부터 마지막 문제까지의 정답이 담긴 answers를 순회할 때 각자 답을 몇 번으로 찍었는지 확인하려면 '나머지'를 활용하면 된다고 생각했다.

가령 17번 문제라고 한다면, 1번 수포자는 자기 패턴 중 2번(17 % 5) 인덱스에 해당하는 답을 제출했을 것이다. 1번 수포자의 패턴은 [1,2,3,4,5] 이므로, 답을 3번으로 제출했을 것이다. (리스트 인덱싱은 0번부터 시작한다) 같은 방식으로 계산해보면 2번 수포자는 자기 패턴에서 17 % 8 = 1번 인덱스에 해당하는 답을, 3번 수포자는 자기 패턴에서 17 % 10 = 7번 인덱스에 해당하는 답을 제출했을 것이다.

위의 논리를 바탕으로 코드를 작성해보자.

# 풀이 1번

def solution(answers):
	# 각 수포자마다 패턴을 만들어줌
    supo1_L = [1,2,3,4,5]
    supo2_L = [2,1,2,3,2,4,2,5] 
    supo3_L = [3,3,1,1,2,2,4,4,5,5]
    
    supo1 = supo2 = supo3 = 0 # 각 수포자의 점수를 0점으로 초기화
    n = len(answers) # 총 문제 갯수는 n개
    for i in range(n):
        now = answers[i] # i번째 문제의 정답
        if now == supo1_L[i % 5]: # 1번 수포자가 정답을 맞췄으면 +1점
            supo1 += 1
        if now == supo2_L[i % 8]: # 2번 수포자가 정답을 맞췄으면 +1점
            supo2 += 1
        if now == supo3_L[i % 10]: # 3번 수포자가 정답을 맞췄으면 +1점
            supo3 += 1
    final = {1:supo1, 2:supo2, 3:supo3}
    winner = max(supo1, supo2, supo3) # 3명의 수포자 중 최고점수를 파악
    
    # 1번 수포자부터 차례로 최고점수를 받았나 확인 후에 리스트에 추가
    # 문제 조건(오름차순)을 자동으로 충족할 수 있게됨
    answer = [x for x in range(1,4) if final[x] == winner]
    return answer

일단 통과했다! 그런데 사실 이 풀이는 처음 생각한 방식은 아니다. 나는 좀 더 복잡하게 생각했는데, 1번 수포자 외에 2명은 패턴을 더 짧게 가져갈 수 있을 것 같았기 때문이다.

우선 2번 수포자의 경우 패턴을 [1,3,4,5]로 압축할 수 있다. 0번째, 2번째, 4번째... 등 짝수번째 문제는 모두 답을 2로 찍고, 홀수번째 문제는 1,3,4,5를 번갈아가며 찍는 방식이기 때문이다. 또한 3번 수포자의 경우에도 같은 답을 2번씩 반복하므로 패턴을 [3,1,2,4,5]로 줄일 수 있을 것이라고 생각했다.

일단은 가장 확실한 방법인 1번 풀이(모든 패턴을 적은 후에 각자 %5, %8, %10 해서 구하는 방식)으로 빠르게 풀어본 후에, 2번 풀이(원래 생각했던 풀이)로도 코드를 작성해보았다.

# 풀이 2번

def solution(answers):
    supo1_L = [1,2,3,4,5]
    supo2_L = [1,3,4,5] 
    supo3_L = [3,1,2,4,5]
    
    supo1 = supo2 = supo3 = 0
    n = len(answers)
    for i in range(n):
        now = answers[i]
        if now == supo1_L[i % 5]:
            supo1 += 1
        if i % 2:
            if now == supo2_L[(i % 8)//2]:
                supo2 += 1          
        else:
            if now == 2:
                supo2 += 1
        if now == supo3_L[(i % 10)//2]:
            supo3 += 1
    final = {1:supo1, 2:supo2, 3:supo3}
    winner = max(supo1, supo2, supo3)   
    answer = [x for x in range(1,4) if final[x] == winner]
    return answer

보다시피 일부 테스트에서는 오히려 느린 결과를 보인다. 아무래도 조건문이 복잡해져서 if문 수행횟수가 늘어나다보니 그런거 같다. 역시나 Simple is the Best! 내가 너무 복잡하게 생각했나보다.

오늘의 개발일지를 쓰고나니 벌써 시간이 다 되었다. 얼른 고기 먹으러 가자!

0개의 댓글