카테고리 없음

99클럽 코테 스터디 23일차 TIL - [프로그래머스] 소수찾기 (Python)

레야_Reya 2024. 11. 20. 10:00
오늘의 문제

 

[프로그래머스] 소수찾기 - 레벨 2

(https://school.programmers.co.kr/learn/courses/30/lessons/42839)

문제 설명
한자리 숫자가 적힌 종이 조각이 흩어져있습니다. 흩어진 종이 조각을 붙여 소수를 몇 개 만들 수 있는지 알아내려 합니다.
각 종이 조각에 적힌 숫자가 적힌 문자열 numbers가 주어졌을 때, 종이 조각으로 만들 수 있는 소수가 몇 개인지 return 하도록 solution 함수를 완성해주세요.

제한사항

numbers는 길이 1 이상 7 이하인 문자열입니다.numbers는 0~9까지 숫자만으로 이루어져 있습니다."013"은 0, 1, 3 숫자가 적힌 종이 조각이 흩어져있다는 의미입니다.

입출력 예
입출력 예 설명
예제 #1[1, 7]으로는 소수 [7, 17, 71]를 만들 수 있습니다.
예제 #2[0, 1, 1]으로는 소수 [11, 101]를 만들 수 있습니다.
11과 011은 같은 숫자로 취급합니다.

코드
from itertools import permutations

def solution(numbers):

    # 숫자 리스트
    li = list(numbers)
    num_li = list(map(int, li))   # 문자열로 입력 받은 숫자를 정수 리스트로 변환
    
    all_num = set()   # 중복 방지
    
    # 모든 가능한 숫자 조합 생성
    for r in range(1, len(num_li)+1):
        perms = permutations(num_li, r)   # 1자릿수부터 최대 자릿수까지
        for p in perms:
            number = int("".join(map(str,p)))
            all_num.add(number)   # 중복제거

    # 소수 판별
    primes = []
    for i in all_num:
        is_prime = True   # 최초에는 소수라고 가정
        if i < 2:   # 2보다 작은 숫자는 소수가 아님
            continue
        for j in range(2,i):   # 검증하려는 숫자를 2부터 자기 자신을 제외한 i-1까지 나누기
            if i%j == 0:   # 나누어떨어지면 소수가 아님
                is_prime = False
                break
        if is_prime:   # 소수라면 리스트에 추가
            primes.append(i)

    return len(primes)

 

개선점 및 회고

 

  소수 판별 시 제곱근까지만 나누자.  

소수를 판별할 때,

2부터 N-1 까지 전체를 나누면서 확인할 필요 없이

2부터 √N 까지만 나눠서 확인해도 된다.

 

[예시]

N = 36 일 때, 약수 쌍은 .

여기서 작은 약수들은 모두 √36 = 6 이하임을 알 수 있다.

따라서 36의 소수 여부를 판별하기 위해 나누기를 할 때, √36 까지만 나눠줘도 된다는 것!

마찬가지로 N = 37 이라면 2,3,4,5,6 으로만 나눠봐도 충분하다.

 

이 방법을 사용하면 불필요하게 큰 수로 나눌 필요를 없애므로 효율적이다.