라떼는말이야
[프로그래머스 lv2] 소수 찾기 (파이썬) 본문
문제 설명
한자리 숫자가 적힌 종이 조각이 흩어져있습니다. 흩어진 종이 조각을 붙여 소수를 몇 개 만들 수 있는지 알아내려 합니다.
각 종이 조각에 적힌 숫자가 적힌 문자열 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은 같은 숫자로 취급합니다.
나의 풀이
이 문제는 크게 두 부분을 구현 해야 한다.
- 숫자의 조합
- 소수 판별
숫자의 조합(순열)
숫자를 조합하는 경우는 파이썬 라이브러리 itertools의 permutations를 사용했다.
permutations는 수학적인 용어로는 순열인데
예를 들어 [1, 3, 5] 라는 리스트가 있을 때 순열로 조합하면 1, 3, 5, 13, 31, 15, 51, 35, 53, 135, 153, 315, 351, 513, 531 과 같이 순서를 가지는 조합을 의미한다.
이 부분의 코드는 다음과 같다.
from itertools import permutations
def makeCase(numbers):
result = []
for i in range(1, len(numbers)+1):
result.extend(list(map(int, map(''.join, permutations(numbers, i)))))
result = list(filter(lambda x: x > 1, list(set(result))))
return result
permutations를 사용하기 위해 상단에 import를 시켜주고
permutations의 사용법은 permutations(대상, 갯수)로 사용하면 된다.
대상에는 리스트, 문자열, 집합 등 iterable한 자료형이 올 수 있다.
permutations의 결과는 튜플 형식으로 반환된다.
예를 들어 ('1', '3') 과 같은 형식으로 반환된는 것인데 우리는 숫자 13으로 사용하기 위해서
map 함수로 각각의 경우에 ''.join를 사용하여 "13"을 만들어준다.
''.join은 리스트의 각 요소를 ' ' 안에 들어있는 문자를 구분자로 묶는 역할을 하는데 ' ' 안이 공백이므로 하나의 문자로 연결해준다.
그리고 또 그렇게 만들어진 문자열 요소들을 정수로 바꿔주기 위하여 map을 한번 더 사용하여 int형으로 만들어주었다.
이것을 list( ) 로 감싸서 리스트로 만들어준 후 result 리스트에 붙여넣었다.
이 문제에서는 소수를 판별하는 문제이므로 2 이하의 숫자는 소수가 아니기 때문에 리스트 내에서 1보다 큰 숫자만 filter를 사용하여 걸러낸다. 그리고 그 결과를 반환했다.
소수 판별
소수를 판별하는 방법은 아주 다양하다.
가장 보편적이고 코딩테스트 등에서 자주 쓰이는 방법이 '아리스토텔레스의 체' 이다.
2021.06.17 - [프로그래머스 lv1] 소수 만들기 (파이썬)
이 문제에서 "아리스토텔레스의 체"를 사용해 풀이했다.
자세한 내용은 위 게시글을 참고하거나 구글링을 해보면 자세히 나와있다.
이번 풀이에서는 가장 무식하고 단순한 방법을 사용했다.
일일히 나눠보는 방법이다.
범위 내의 모든 소수를 구하는 것이 아닌 해당 숫자가 소수인지 판별하는 것이기 때문에 이 방법을 선택했다.
def isPrime(n):
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0: return False
return True
하지만 범위를 보면 n까지가 아닌 √n 까지 나누었다.
어떤 수의 약수는 항상 짝을 이룬다.
예를 들어 100의 약수는 1, 2, 4, 5, 10, 20, 25, 50, 100 인데
(1, 100), (2, 50), (4, 25), (5, 20), (10, 10) 과 같이 짝을 이룰 수 있다.
즉 100의 제곱근보다 작은 수까지만 나눠보면 소수인지 아닌지 판별할 수 있다.
1, 2, 4, 5, 10까지만 나눠보면 짝을 이루는 100, 50, 25, 20, 10 까지 모두 구할 수 있기 때문이다.
2부터 √n까지 차례로 나누어 가면서 한 번이라도 나누어 떨어진다면 소수가 아니다.
모두 나눠봤지만 나누어 떨어지지 않았다면 소수이다.
전체 코드
from itertools import permutations
def solution(numbers):
answer = 0
case = makeCase(numbers)
for n in case:
if isPrime(n): answer += 1
return answer
def makeCase(numbers):
result = []
for i in range(1, len(numbers)+1):
result.extend(list(map(int, map(''.join, permutations(numbers, i)))))
result = list(filter(lambda x: x > 1, list(set(result))))
return result
def isPrime(n):
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0: return False
return True
위에서 구한 숫자들의 순열을 for문으로 순회하며 소수인지 판별하고 소수라면 answer에 1씩 더하여 풀이할 수 있다.
'알고리즘 > 코딩 테스트' 카테고리의 다른 글
[프로그래머스 lv2] 영어 끝말잇기 (파이썬) (0) | 2021.08.05 |
---|---|
[프로그래머스 lv2] 메뉴 리뉴얼 (2) | 2021.08.04 |
[프로그래머스 lv2] 후보키 (파이썬) (0) | 2021.08.04 |
[프로그래머스 위클리 챌린지] 부족한 금액 계산하기 (python) (0) | 2021.08.04 |
[구름LEVEL - 별 5개] 어느 개발자 이야기 (파이썬) (0) | 2021.08.01 |
[프로그래머스 lv2] [1차]뉴스 클러스터링 (파이썬) (0) | 2021.07.22 |
[프로그래머스 lv2] 카펫 (파이썬) (0) | 2021.07.21 |
[프로그래머스 lv2] 행렬 테두리 회전하기 (파이썬) (1) | 2021.07.21 |