문제 설명
한자리 숫자가 적힌 종이 조각이 흩어져있습니다. 흩어진 종이 조각을 붙여 소수를 몇 개 만들 수 있는지 알아내려 합니다.
각 종이 조각에 적힌 숫자가 적힌 문자열 numbers가 주어졌을 때, 종이 조각으로 만들 수 있는 소수가 몇 개인지 return 하도록 solution 함수를 완성해주세요.
제한사항
- numbers는 길이 1 이상 7 이하인 문자열입니다.
- numbers는 0~9까지 숫자만으로 이루어져 있습니다.
- "013"은 0, 1, 3 숫자가 적힌 종이 조각이 흩어져있다는 의미입니다.
입출력 예
numbers return
"17" | 3 |
"011" | 2 |
입출력 예 설명
예제 #1
[1, 7]으로는 소수 [7, 17, 71]를 만들 수 있습니다.
예제 #2
[0, 1, 1]으로는 소수 [11, 101]를 만들 수 있습니다.
- 11과 011은 같은 숫자로 취급합니다.
코드
import itertools
import math
def solution(numbers):
answer = 0
parsed_list = [int(numbers[i]) for i in range(len(numbers))]
# 1 parsed list를 가지고 조합할 수 있는 수를 만들기
# itertools의 permutations를 사용하여 순열을 만든다.
# 각 요소를 담을 순열 리스트 초기화
permutations = []
for i in range(1, len(parsed_list) + 1): # 1자리 순열부터, list의 길이의 순열까지 모두 구하기 위함
permutations.extend(itertools.permutations(parsed_list, i)) # - 이거 숙지하기
# 순열을 숫자로 변환 - 이거 숙지하기
nums = set(int(''.join(map(str, perm))) for perm in permutations) # 중복이 있을 때는 set 자료형으로 변환한다.
# 2 그 수가 소수인지 아닌지를 확인하는 로직 만들기
for num in nums:
if check_prime(num):
answer += 1
return answer
def check_prime(num):
if num < 2:
return False
if num == 2 or num == 3:
return True
if num % 2 == 0 or num % 3 == 0:
return False
for i in range(5, int(math.sqrt(num)) + 1, 2):
if num % i == 0:
return False
return True
solution('011')
코드 풀이
- answer를 0으로 초기화
- 입력받은 string을 for 루프를 통해 list에 int로 담음 “011” → [0, 1, 1]
- itertools의 permutaions를 사용하여 해당 리스트의 모든 요소의 순열을 구함
- list.extend를 사용하여 요소들을 리스트에 추가함. append는 그 자체를 추가하는 것이므로 다름
- 모든 순열 튜플을 반복하면서 set() 으로 자료구조를 변경해주어 중복을 제거한다.
- 순열을 반복하며 해당 숫자가 소수인지 아닌지를 확인하는 로직을 가진다.
- 소수인지 확인하는 로직
- num < 2: 소수는 0과 1이 될 수 없다.
- num == 2 or num == 3: 2와 3은 소수이다.
- num % 2 == 0 or num % 3 == 0: 2의 배수와 3의 배수는 소수가 될 수 없다.
for i in range(5, int(math.sqrt(num)) + 1, 2): if num % i == 0: return False return True 숫자의 제곱근 이하의 수로 나누어 떨어진다면 그 수는 소수가 아니다. 모든 조건에 걸리지 않는다면 그 수는 소수이다.
핵심 포인트
- for 루프에서 range()를 사용할 때 start와 end를 정해준다면 end + 1을 반드시 해줘야 한다
- 이것 때문에 한 번 틀림
- 인풋으로 들어오는 string을 parse해서 각 요소를 리스트에 넣는다.
- parsed_list = [int(numbers[i]) for i in range(len(numbers))]
- parsed list를 가지고 조합할 수 있는 수를 만들기. 즉 순열을 만든다.
- 순열: 주어진 요소들의 모든 가능한 순서를 고려한 배열이다.
permutations = [] for i in range(1, len(parsed_list) + 1): # 1자리 순열부터, list의 길이의 순열까지 모두 구하기 위함 # [1, 3, 2] permutations.extend(itertools.permutations(parsed_list, i)) # - 이거 숙지하기 # 순열을 숫자로 변환 - 이거 숙지하기 nums = set(int(''.join(map(str, perm))) for perm in permutations) # 중복이 있을 때는 set 자료형으로 변환한다.
- 해당 순열의 숫자들이 소수인지를 판별한다.
def check_prime(num):
if num < 2:
return False
if num == 2 or num == 3:
return True
if num % 2 == 0 or num % 3 == 0:
return False
for i in range(5, int(math.sqrt(num)) + 1, 2):
if num % i == 0:
return False
return True
숫자 순열을 문자열로 변환 후 결합
import itertools
# 숫자 순열 생성
permutations = itertools.permutations([1, 2, 3], 2) # (1, 2) (1, 3) (2 1) (2 3) (3 1) (3 3)
result = [''.join(map(str, perm)) for perm in permutations]
print(result) # ['12', '13', '21', '23', '31', '32']
map(func, iterable): Iterable(리스트, 튜플 등) 내의 각 요소에 대해 func을 적용한 결과를 반환한다.
‘’.join(): Iterable내의 문자열들을 하나의 문자열로 결합한다. 앞의 빈 문자열(’’)은 각 요소 사이에 아무것도 넣지 않고 이어붙이겠다는 뜻
'백준 코딩테스트 > 완전탐색(Brute force)' 카테고리의 다른 글
프로그래머스: 모의고사 (8 / 25) (1) | 2024.10.10 |
---|