본문 바로가기

개발일지/TIL

TIL 23-04-08

1.프로그래머스 LV1 - 삼총사

 문제점

한국중학교에 다니는 학생들은 각자 정수 번호를 갖고 있습니다.
이 학교 학생 3명의 정수 번호를 더했을 때 0이 되면 3명의 학생은 삼총사라고 합니다.
예를 들어, 5명의 학생이 있고, 각각의 정수 번호가 순서대로 -2, 3, 0, 2, -5일 때,
첫 번째, 세 번째, 네 번째 학생의 정수 번호를 더하면 0이므로 세 학생은 삼총사입니다.
또한, 두 번째, 네 번째, 다섯 번째 학생의 정수 번호를 더해도 0이므로 세 학생도 삼총사입니다.
따라서 이 경우 한국중학교에서는 두 가지 방법으로 삼총사를 만들 수 있습니다.
# 3명의 숫자를 더해서 0이 되면 삼총사
    # 2중 for문?
    # 1개를 pop으로 빼고 나머지 2자리를 for문으로 돌린다

 시도해 본 것들

def solution(number):
    # 3명의 숫자를 더해서 0이 되면 삼총사
    # 2중 for문?
    # 1개를 pop으로 빼고 나머지 2자리를 for문으로 돌린다
    answer = 0
    pop_num = 0

    for _ in number:
        pop_num = number.pop()
        for num2 in number:
            for num3 in number:
                if pop_num + num2 + num3 == 0:
                    answer += 1
    answer = int(answer/2)
    return answer

일단 생각나는데로 작성해서 테스트 코드는 통과했으나, 정답처리는 불가능했다. 

for문에서 같은 숫자들이 같이 들어가는 것으로 예상된다. <- if문으로 같은 자리일 경우 pass?

또한 /2로 대충 때려박는 게 아니라 answer에 들어갈 때 부터 중복값을 제거해야 함.

 

def solution1(number):
    # 3명의 숫자를 더해서 0이 되면 삼총사
    # 2중 for문?
    # 1개를 pop으로 빼고 나머지 2자리를 for문으로 돌린다
    answer = 0
    pop_num = 0

    for _ in number:
        pop_num = number.pop()
        for num1 in range(len(number)):
            # print(number[num1])
            for num2 in range(len(number)):
                if num1 != num2 and pop_num + number[num1] + number[num2] == 0:
                    answer += 1
    answer = int(answer/2)
    return answer

같은 자리의 숫자를 들어가는 경우를 제외하자 이제 하나의 케이스를 제외하고는 정답으로 인정됐다.

이제 /2를 지우고 출력할 방법을 찾자.

def solution1(number):
    # 3명의 숫자를 더해서 0이 되면 삼총사
    # 2중 for문?
    # 1개를 pop으로 빼고 나머지 2자리를 for문으로 돌린다
    answer = 0
    copy_number = number[::]
    # 겹치지 않도록 빼고 시작
    copy_number.pop()
    while len(number) >= 3:
        pop_num1 = number.pop()
        pop_num2 = copy_number.pop()
        for num in copy_number:
            print(pop_num1, pop_num2, num)
            if pop_num1 + pop_num2 + num == 0:
                answer += 1
    return answer

/2를 제거했지만 print()를 찍어보니 pop_num2가 이렇게 작동하면 안된다. for문으로 돌려야 하나?

 해결 방법

def solution(number):
    # 3명의 숫자를 더해서 0이 되면 삼총사
    answer = 0
    while len(number) >= 3:
        pop_num1 = number.pop()
        # pop으로 빠진 상태의 number를 복사, copy_number 갱신
        copy_number = number[::]
        # pop_num2의 가능한 경우의 수를 모두 확인하기 위한 while문
        while len(copy_number) >= 2:
            pop_num2 = copy_number.pop()
            # 리스트에 남아있는 수를 대조하기 위한 for문
            for num in copy_number:
                if pop_num1 + pop_num2 + num == 0:
                    answer += 1
    return answer

처음 생각할 때만 해도 2중for문으로 가닥을 잡고 가능하면 하나를 줄여서 시간복잡도를 개선하고 싶었는데 오히려 한개가 늘어버렸다.

 알게 된 점

어제 알게된 [::]으로 리스트를 복사하고 내가 애용하는 pop()을 좀 더 활용할 수 있었다.

온전히 내가 작성한 주석을 포함해도 40줄이 안되는 코드인데 반복문이 늘어날 수록 코드 가독성이 급격하게 떨어졌다. 지금 이 순간은 코드를 이해했다고 생각하며 코드를 읽는데 불편함이 없지만, 일주일 뒤에도 바로 해석할 수 있을지 의문이다.

 

 

 

'개발일지 > TIL' 카테고리의 다른 글

TIL 23-04-10  (0) 2023.04.10
TIL 23-04-09  (0) 2023.04.09
TIL 23-04-07  (2) 2023.04.07
TIL 23-04-06  (0) 2023.04.06
TIL 23-04-05  (0) 2023.04.05