SELECT e.company_code,
c.founder,
Count(DISTINCT lead_manager_code),
Count(DISTINCT senior_manager_code),
Count(DISTINCT manager_code),
Count(DISTINCT employee_code)
FROM employee e
LEFT JOIN company c
ON e.company_code = c.company_code
GROUP BY 1,2
ORDER BY 1
위에서부터 복잡하게 join하면서 내려올 필요 없이,
모든 정보를 다 담고 있는 employee 테이블에서 개수만 count하고 company 테이블하고만 join해서 founder 이름만 받아오면 됨.
주어진 숫자 중 3개의 수를 더했을 때 소수가 되는 경우의 개수를 구하려고 합니다. 숫자들이 들어있는 배열 nums가 매개변수로 주어질 때, nums에 있는 숫자들 중 서로 다른 3개를 골라 더했을 때 소수가 되는 경우의 개수를 return 하도록 solution 함수를 완성해주세요.
제한사항
- nums에 들어있는 숫자의 개수는 3개 이상 50개 이하입니다.
- nums의 각 원소는 1 이상 1,000 이하의 자연수이며, 중복된 숫자가 들어있지 않습니다.
<1트> : 테스트 케이스 통과, 제출 시 오답(23.1)
def solution(nums):
x = [] #nums에서 세 개 수를 뽑아서 넣을 리스트
for i in range(len(nums)):
for j in range(i+1,len(nums)):
for k in range(j+1,len(nums)):
x.append(nums[i]+nums[j]+nums[k])
answer = 0 #소수의 개수를 담을 count 선언
for l in x:
if l%2 !=0 and l%3 !=0 and l%5 != 0: #소수의 조건을 충족하면
count += 1 #answer에 1씩 더해나가기
return answer
테스트 케이스는 통과했는데 제출 시 오답이 와장창 떴다.
소수의 조건을 별 생각없이 느슨하게 넣어서 그런 것 같다.
소수는 1과 자신 외에 약수가 없는 수이므로
2부터 자신의 제곱근까지의 수로만 나눠봤을 때 약수로 판명되는 경우가 없으면 된다. 예를 들어 17의 제곱근은 4.xx인데, 17을 2,3,4까지로만 나눠봤을 때 약수인 경우가 없으므로 17은 소수다.
다만 완전제곱수인 경우에는 제곱근까지 확인해 줘야 모든 경우의 수를 검증할 수 있다. 예를 들어 확인해야 할 수가 25라면 2,3,4,5까지의 수로 나눠봐야 5로 나누었을 때 나머지가 0인 경우가 있으므로 소수가 아님을 판정할 수 있는 것. 따라서, 코드상으로는 range(2,int(l**.5)+1)까지로 설정해야 한다.
<2트> : 정답
def solution(nums):
x = [] #nums에서 세 개 수를 뽑아서 넣을 리스트
for i in range(len(nums)):
for j in range(i+1,len(nums)):
for k in range(j+1,len(nums)):
x.append(nums[i]+nums[j]+nums[k])
count = 0 #x 중 소수의 개수를 셀 count 선언
for l in x: #x의 모든 요소들을 돌아가면서 검사
count_divisor = 0 #약수의 개수를 셀 임시 변수(count_divisor) 선언
for m in range(2,int(l**.5)+1): #l의 제곱근+1까지 돌면서 검사
if l%m == 0: #만약 l을 m으로 나눈 나머지가 0(약수)이라면
count_divisor += 1 #count_divisor에 1을 더하고
break #반복문 종료 (어차피 소수가 아니므로)
if count_divisor == 0: #만약 반복문이 다 끝났는데도 count_divisor가 0이면
count += 1 #소수라는 이야기이므로 count에 1씩 증가
return count #세 수의 합 x중 소수인 경우의 수를 최종 반환
만약 2부터 x의 원소 l의 제곱근+1까지의 수 중 약수인 경우가 하나라도 있다면 어차피 그 수는 소수가 아니므로 반복문을 더 돌릴 필요가 없다. 따라서 약수의 개수를 세기 위한 count_divisor 변수를 반복문 내에서 변수로 선언해 주고, (1과 자신 외에) 약수가 하나라도 확인되면 count_divisor에 1을 더해주고 반복문을 종료시킨다.
만약 모든 반복문이 다 끝났는데도 count_divisor가 0이라면, 그 수는 1과 자신 외에 약수가 없는 소수에 해당하므로 소수의 개수를 세기 위해 선언해 두었던 count에 1씩 증가시키면 된다.
예전에 코드카타에서 다뤘던 적이 있어서 삼중 반복문까지는 비교적 어렵지 않게 도달했는데, x의 원소 중 소수의 개수를 세는 로직을 반드는 부분이 조금 어려웠다.
어떤 수 l이 소수인지 알아보려면 (대칭의 원리에 의해) 2부터 l의 제곱근까지만 나눠보면 된다는 걸 알게 됐고, 이걸 파이썬에서 반복문으로 구현할 때는 int(제곱근)+1까지 조건으로 명시해야 제곱근까지 포함된다는 것도 새롭게 알게 된 부분. 이제 삼중 반복문은 더 헷갈려서는 안 되겠고, 소수 조건도 한 번 정도만 더 마주쳐 보면 손에 익힐 수 있을 것 같다.