문제 확인
나의 풀이
- 가능한 문자열을 구성하기 위한 방법으로는 순열, 백트래킹을 활용한 DFS가 있다.
- DFS 과정에서 각 종이(숫자)가 한 번만 활용돼야 하기 때문에 is_used 라는 변수를 활용했다.
# 가능한 문자열 구성하기
def dfs(numbers, n_len, num):
global cnt, is_used, num_uniq
# 문자열 길이 최대일 경우
if n_len == len(numbers):
return
for i in range(len(numbers)):
if not is_used[i]:
num += numbers[i]
is_used[i] = 1
# 숫자 추가
num_uniq.add(int(num))
# 새로운 숫자 조합 찾기
dfs(numbers, n_len + 1, num)
num = num[:-1]
is_used[i] = 0
def is_prime(n):
# 소수 판별
if n <= 1: return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0: return False
return True
def solution(numbers):
# 종이 조각으로 만들 수 있는 숫자
global num_uniq
num_uniq = set()
# 종이(숫자) 사용 여부 확인
global is_used
is_used = [0] * len(numbers)
dfs(numbers, 0, "")
# 소수인 수 개수 확인
return len([i for i in num_uniq if is_prime(i)])
다른 사람 풀이
DFS를 활용한 풀이
- 종이 사용 여부를 확인할 변수 없이 풀 수 있다.
primeSet = set()
def isPrime(number):
if number in (0, 1):
return False
for i in range(2, number):
if number % i == 0:
return False
return True
def makeCombinations(str1, str2):
if str1 != "":
if isPrime(int(str1)):
primeSet.add(int(str1))
for i in range(len(str2)):
makeCombinations(str1 + str2[i], str2[:i] + str2[i + 1:])
def solution(numbers):
makeCombinations("", numbers)
answer = len(primeSet)
return answer
순열을 활용한 풀이
- 가능한 문자열을 순열을 통해 만들었다.
from itertools import permutations
def solution(numbers):
answer = []
nums = [n for n in numbers] # numbers를 하나씩 자른 것
per = []
for i in range(1, len(numbers)+1): # numbers의 각 숫자들을 순열로 모든 경우 만들기
per += list(permutations(nums, i)) # i개씩 순열조합
new_nums = [int(("").join(p)) for p in per] # 각 순열조합을 하나의 int형 숫자로 변환
for n in new_nums: # 모든 int형 숫자에 대해 소수인지 판별
if n < 2: # 2보다 작은 1,0의 경우 소수 아님
continue
check = True
for i in range(2,int(n**0.5) + 1): # n의 제곱근 보다 작은 숫자까지만 나눗셈
if n % i == 0: # 하나라도 나눠떨어진다면 소수 아님!
check = False
break
if check:
answer.append(n) # 소수일경우 answer 배열에 추가
return len(set(answer)) # set을 통해 중복 제거 후 반환