https://programmers.co.kr/learn/courses/30/lessons/42839
코딩테스트 연습 - 소수 찾기
한자리 숫자가 적힌 종이 조각이 흩어져있습니다. 흩어진 종이 조각을 붙여 소수를 몇 개 만들 수 있는지 알아내려 합니다. 각 종이 조각에 적힌 숫자가 적힌 문자열 numbers가 주어졌을 때, 종이
programmers.co.kr
1차 시도
모든 조합을 만들고 소수만 남겨야겠다고 생각했다.
조합은 만들려는 중 순열 조합?이런건 난 다 까먹어서 아래 N으로 표현에서 노가다 한 방법대로 했다.
https://eunsera.tistory.com/24?category=1046251
[프로그래머스] [Python] Level3_N으로 표현
https://programmers.co.kr/learn/courses/30/lessons/42895 코딩테스트 연습 - N으로 표현 programmers.co.kr 동적계획법 Dynamic Programming 문제이다. 경우에 따라서 검사하는 range를 동적으로 설정해주기에..
eunsera.tistory.com
그랬더니 한 숫자는 한번씩만 들어가야하는데 중복해서 들어가고...암튼 난리남
그리고 소수 걸러내는 것도 제곱근 구해서 하는거 처음 알았음 (문송합니다...)
from itertools import permutations
def solution(numbers):
arr = list(numbers)
p_list = []
ans = 0
for i in range(1,len(arr)+1):
npr = permutations(arr, i)
for p in npr:
s = ''
for j in list(p) : s+=j
p_list.append(int(s))
p_list = list(set(p_list))
for p in p_list:
flag = True
tmp = 2
#0,1은 미리 제외
if p==0 or p==1: flag = False
#소수인지아닌지
while(tmp<p):
if p%tmp ==0: #소수아님
flag = False
break
else:
tmp+=1
if(flag): #소수
ans += 1
return ans
2차 시도
남들 다 하는대로 얌전하게 permutation을 쓰기로 했다.
소수인지 검사하는 부분에서 if문 처음 걸러낼 때, 음 소수아닌거 다 걸러면 되나?!
그럼 2의 배수 다빼자!!!하고 p%2 == 0도 넣었었는데
이렇게 되면 2도 소수인데 걸러져버려서 테스트케이스 4개 정도 정확성 fail이 떴었다
from itertools import permutations
def solution(numbers):
answer = []
nums = [n for n in numbers]
per = []
for i in range(1,len(numbers)+1):
per += list(permutations(nums, i)) #순열조합
per = set([int(("").join(p)) for p in per])
for p in per:#소수인지 검사
if p==0 or p==1 :
continue
flag = True #소수맞음
for i in range(2,int(p**0.5)+1):
if p%i == 0:
flag = False #소수아님
break
if flag : answer.append(p)
return len(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 배열에 추가
print(new_nums)
return len(set(answer))
💡최종로직
0. numbers를 문자열이 아니라 떨어진 숫자 list로 바꾼다
1. 숫자 list를 돌면서 permutation 실행
2. permutation한걸 다시 숫자로 변환하면서 set으로 바꿔 중복 제거
3. 숫자로 변환한 list를 돌면서
3-1. 0이거나 1이면 out
3-2. 해당 수의 제곱근까지 순회하며 나눴을 때 나머지가 0이게 하는 숫자(인수)가 있으면 out
3-3. out일때 flag = False하는데 여기서 살아남은 애들만 answer list에 appen
4. answer의 길이 return
permutation 공부가 필요
사실 permutation이 포함된 itertools 라이브러리를 봐야할 것같다
2021.09.29
from itertools import permutations
def solution(numbers):
arr = list(numbers)
p_list = []
ans = 0
for i in range(1,len(arr)+1):
npr = permutations(arr, i)
for p in npr:
s = ''
for j in list(p) : s+=j
p_list.append(int(s))
p_list = list(set(p_list))
for p in p_list:
flag = True
tmp = 2
#0,1은 미리 제외
if p==0 or p==1: flag = False
#소수인지아닌지
while(tmp<p):
if p%tmp ==0: #소수아님
flag = False
break
else:
tmp+=1
if(flag): #소수
ans += 1
return ans
오늘은 아무것도 안보고 혼자 풀었다!
중간에 시간이 좀 걸린 부분은 append할 때 바로 int로 하면 되는데 string으로 받았다가 '011', '11' 같은 게 중복으로 들어가서 set에서 제거가 덜 되었다.
int로 형변환해서 list에 넣으니 중복제거도 잘되고 나중에 형변환도 안해도 돼서 편했다.
소수 판별 로직은 Flag를 하나 선언해서 true로 시작한 다음, 소수가 아닌 로직에 거릴 때 마다 flag를 false로 바꿔주면서 break를 걸어서 빠져나온다.
1. 0과 1은 소수가 아니다
2. 자신보다 작은 수 중에 나머지 연산 %의 결과가 0이면, 나누어 떨어졌다는 뜻이니 소수가 아니다.
위 2가지를 걸려져서 while문을 빠져나온 수는 소수이므로 flag값이 true이면 소수이다.
'Algorithm > 프로그래머스' 카테고리의 다른 글
[프로그래머스] [Python] Level3_여행경로 (0) | 2021.08.05 |
---|---|
[프로그래머스] [Python] Level2_카펫 (0) | 2021.08.05 |
[프로그래머스] [Python] Level1_모의고사 (0) | 2021.08.05 |
[프로그래머스] [Python] Level3_N으로 표현 (0) | 2021.08.04 |
[프로그래머스] [Python] Level_2 H-Index (0) | 2021.08.04 |
댓글