codes/programmers

42839 소수 찾기

카제xd 2024. 12. 9. 18:16

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

 

# 나의 코드 -> 개별 후보에 대해 그 제곱근까지만 약수 여부 검증

- 몫과 나누는 수 둘중 하나는 N제곱근 이하라는 것에 착안.

from itertools import permutations

def solution(numbers):
    
    parts = list(numbers)
    
    candids = []
    for i in range(1, len(parts)+1):
        candids.extend(list(map(lambda x: int(''.join(x)), list(permutations(parts, i)))))
    
    candids = set(candids) - set([0, 1])
    
    n = 0
    for c in candids:
        for i in range(2, int(c**(1/2))+1):
            if c % i == 0:
                break
        else:
            n += 1
            
    return n

 

 

# 다른 사람의 코드 참조해서 수정 (에라토스테네스의 체)

- 소수 판별 범위를 미리 정해두고 배수들을 지워나가는 방식

- 이 경우에는 배열 max값의 N제곱근까지만 보면 됨.

from itertools import permutations

def solution(numbers):
    
    candids = set()
    for i in range(1, len(numbers)+1):
        candids |= set(map(lambda x:int(''.join(x)), permutations(list(numbers), i)))
    
    candids -= set(range(0, 2))
    
    for i in range(2, int(max(candids)**(1/2))+1):
        candids -= set(range(i*2, max(candids)+1, i))
            
    return len(candids)

 

 

 

[개선할 점]

- 대량의 소수를 한 번에 판별할 경우에는 에라토스테네스 체를 사용하면 좋다.

- list에서 set으로 이후에 변환하지 않고, candids를 set으로 만들고 permutations들도 set으로 만들어서 매번 합치면 된다. 집합의 복합 대입 연산자:

* 합집합 -> |=

* 차집합 -> -=

 

- map 결과를 set 또는 list로 wrap할거라면 permutations에서 미리 list로 감싸주지 않아도 된다.

- map에 함수 argument 줄때 map("".join, ~) 이런 식도 가능하다.

- range 범위 시작과 끝에 1을 더하는 것 말고, 실제 사용되는 i에서 i+1로 바꿔줌으로서 range(len(n))으로 쓸 수도 있다.