본문 바로가기
‼ ERROR RECORD

소수만들기 코테 Error _ for문 끊기의 이해, itertools

by Queen2 2022. 6. 15.
728x90
반응형

https://programmers.co.kr/learn/challenges

Q. 주어진 숫자 중 3개의 수를 더했을 때 소수가 되는 경우의 개수를 구하려고 합니다. 숫자들이 들어있는 배열 nums가 매개변수로 주어질 때, nums에 있는 숫자들 중 서로 다른 3개를 골라 더했을 때 소수가 되는 경우의 개수를 return 하도록 solution 함수를 완성해주세요.

 

코딩테스트 연습

기초부터 차근차근, 직접 코드를 작성해 보세요.

programmers.co.kr

구현 필요한 기능

1) 숫자 3개를 조합하는 함수 2) 선별된 3개의 함수 합을 소수로 판별하는 함수


  • 기존의 에러코드
def solution(nums):
    answer = 0
    check = []
    l = []
    is_prime =True
    for a in range(len(nums)):
        for b in range(len(nums)):
            for c in range(len(nums)):
                if a == b or b == c or a==c : break
                else:
                    check.append(sorted([nums[a],nums[b],nums[c]]))
    
    for i in check:
        if i not in l:
            l.append(i)
            
    s = [sum(k) for k in l]    
    
    for e in s:
        for x in range(1,int(e)):
            if e%x == 0:
                is_prime =False
        
        if is_prime:
             answer +=1
            
    return answer

 결과괎 : answer 이 0이 반복됨

이슈 : 소수를 판별하는 마지막 for문에서  e%x에 대한 판별 이후, answer로 연결하는 과정 계산 오류가 계속 나타남

접근방식: for 문의 순서를 바꿔보고, is_prime boolean 함수로 바꿔보기도 했지만 계속 0이 나왔다....

--> 어느 부분에서 에러가 나타나는지 파악을 위해 각 단계별로 함수를 만들어서 점검을 시작했다.

 

역시나 에상대로 for문에서 에러가 계속 났고 m이라는 리스트를 통해 확인 결과, 2번째 for문이 돌아가면서 담게 되는 cnt값이 판별해야 하는 s 리스트의 값(선별된 3개 숫자의 합 값)별로 분리되지 못하고 엉키고 있었다.

 

  • 해결방안

for문이 순환될 때, cnt값이 0으로 포맷되도록 하고 별도의 m이라는 리스트에 소수인지 판별하기 위해 약분되는 숫자의 개수를 카운팅한 cnt를 기록하여, answer로 반환되도록 했다.

 for e in s:
        for y in range(1,e):
            if e%y == 0:
                cnt += 1
        m.append(cnt)
        cnt = 0

    answer = m.count(1)
    
    return answer

 

  • 셀프 피드백

구현해야 하는 기능을 나열식으로 하나하나 만드는데에 집중했더니, 코드가 길어졌다.

코테를 풀 때마다 느끼지만 단계별로 점검하면서 '돌다리도 두드리고 건너자'는  접근방식이 습관화 되어야 할거 같다.

 

  • 정답 코드
def solution(nums):
    from itertools import combinations as cb
    answer = 0
    for a in cb(nums, 3):
        cand = sum(a)
        for j in range(2, cand):
            if cand%j==0:
                break
        else:
            answer += 1
    return answer

정답 코드들 다수는 itertools의 조합형 iterator 을 이용했다.

아예 나눠는 수를 2부터 시작하도록 하여, 1외의 약수가 있을 때 break문을 사용하도록 해서 코드를 단순화시킨 것도 좋은 아이디어인 것 같다.

 

https://docs.python.org/ko/3/library/itertools.html

 

itertools — 효율적인 루핑을 위한 이터레이터를 만드는 함수 — Python 3.10.5 문서

itertools — 효율적인 루핑을 위한 이터레이터를 만드는 함수 이 모듈은 APL, Haskell 및 SML의 구성물들에서 영감을 얻은 여러 이터레이터 빌딩 블록을 구현합니다. 각각을 파이썬에 적합한 형태로

docs.python.org

 

itertools.combinations(어떤 요소를 비복원추출해라, 몇 개 단위의 조합으로) 만들어라

itertools.combinations_with_replacement(어떤 요소를 복원 추출해라, 몇개 단위의 조합으로) 만들어라 

itertools.permutations(어떤 요소를 모든 가능한 순서로, 몇개 단위의 조합으로)만들어라

 

이런 조합을 만드는 상황일 때 유용하게 쓰일 것 같다.

728x90
반응형

댓글