SQL 코드카타 118번
문제 해석만 잘 되면 그렇게까지 어렵지는 않은 문제.
SELECT Round(Sum(tiv_2016), 2) AS tiv_2016
FROM insurance
WHERE Concat(lat, ',', lon) NOT IN (SELECT Concat(lat, ',', lon) AS location
FROM insurance
GROUP BY 1
HAVING Count(*) >= 2)
AND tiv_2015 IN (SELECT tiv_2015
FROM insurance
GROUP BY 1
HAVING Count(*) > 1)
lat과 lon을 합친 concat(lat, ',', lon)가 2개 이상인 경우(지역이 중복되는 경우)는 모두 제외해 주고, 동시에 tiv_2015는 1개 초과인 경우(혼자 튀는 값이 있으면 제외)만 필터링하면 된다. 난이도가 medium인 것치고는 다른 medium 문제보다는 쉬웠던 듯.
한국중학교에 다니는 학생들은 각자 정수 번호를 갖고 있습니다. 이 학교 학생 3명의 정수 번호를 더했을 때 0이 되면 3명의 학생은 삼총사라고 합니다.
예를 들어, 5명의 학생이 있고, 각각의 정수 번호가 순서대로 -2, 3, 0, 2, -5일 때, 첫 번째, 세 번째, 네 번째 학생의 정수 번호를 더하면 0이므로 세 학생은 삼총사입니다. 또한, 두 번째, 네 번째, 다섯 번째 학생의 정수 번호를 더해도 0이므로 세 학생도 삼총사입니다.따라서 이 경우 한국중학교에서는 두 가지 방법으로 삼총사를 만들 수 있습니다.
한국중학교 학생들의 번호를 나타내는 정수 배열 number가 매개변수로 주어질 때, 학생들 중 삼총사를 만들 수 있는 방법의 수를 return 하도록 solution 함수를 완성하세요.
파이썬을 활용해서 처음으로 '조합'을 구해야 하는 문제.
주어진 number에서 중복을 허용하지 않고 3개의 수를 뽑아서 그것들을 더했을 때 0이 되는지 확인해보면 된다.
파이썬 코드로 조합을 구현하는 방법은 여러가지가 있는 것 같은데, 재귀함수는 배운 적도 없거니와 봐도 이해가 안 돼서 깔끔하게 포기. 그나마 알고 있는 반복문이라도 잘 써서 해결해보기로 했다.
def solution(number):
x = []
count = 0
for i in range(len(number)):
for j in range(i+1, len(number)):
for k in range(j+1, len(number)):
y = [number[i],number[j],number[k]]
x.append(y)
for 반복문은 한 번 쓸 때는 이해가 쉬운데 중첩해서 쓰기 시작하면 이해하기가 정말 어려운 것 같다. 이거 이해하고 만드는 데만 1시간이 넘게(...) 걸렸는데, 일단 이해한 바를 적어보면 아래와 같다.
먼저 조합된 수를 담을 빈 리스트 x를 선언한다.
count는 뒤에서 '구성요소의 합이 0인 리스트'의 개수를 세기 위해 미리 선언해 둔 것. 이 파트에서는 역할이 없다.
i는 0부터 시작해서 len(number)만큼의 수를 반복한다.
j는 위에서 선택된 i보다 하나 큰 수부터(즉, i와 중복되지 않고) len(number)만큼의 수를 반복한다.
k는 위에서 선택된 j보다 하나 큰 수부터(즉, i와j 모두와 중복되지 않고) len(number)만큼의 수를 반복한다.
그리고 그 각각의 수를 y라는 리스트에 넣고, 그걸 다시 x에 집어넣는다.
예를 들어 number = [1,2,3,4]이라고 하면
i=0, j=1, k=2부터 시작되므로
number[0],number[1],number[2], 즉 1,2,3이 리스트 y에 담긴다.
i와 j는 그대로 두고 k=3으로 바뀌어서 i=0, j=1, k=2가 실행된다. 따라서 number[0],number[1],number[3] 즉 1,2,4가 리스트 y에 담긴다.
(이제 k의 반복은 끝났으므로) i=0, j=2, k=3이 실행된다. 따라서 number[0],number[2],number[3] 즉 1,3,4가 리스트 y에 담긴다.
(이제 k와 j모두 반복이 끝났으므로) i=1,j=2,k=3이 실행된다. 따라서 number[1],number[2],number[3] 즉 2,3,4가 리스트 y에 담긴다.
3개의 반복문이 모두 끝나면 리스트 x에는 '중복되지 않는 3개 숫자의 조합'으로 이루어진 모든 리스트 y들이 담기게 된다.
def solution(number):
x = []
count = 0
for i in range(len(number)):
for j in range(i+1, len(number)):
for k in range(j+1, len(number)):
y = [number[i],number[j],number[k]]
x.append(y)
for z in range(len(x)):
w = sum(x[z])
if w == 0:
count += 1
return count
이제 range(len(x))를 써서 x의 요소들을 하나씩 반복하는데, x를 구성하는 각각의 리스트들의 합을 sum(x[z])로 표현해서 변수 w에 담아준다.
그리고 w가 0일 경우(즉, 문제에서 구하고자 하는 삼총사에 해당하는 경우)에는 제일 위에서 미리 선언해 두었던 count에 1씩 더해가면 된다. 모든 함수의 실행이 끝나면 count에는 삼총사 조합의 가짓수가 남게 되고, 이걸 return해 주면 끝.
갈수록 파이썬 알고리즘이 어려워지고 있어서 1시간 코드카타로 끝낼 수 있을지 모르겠다. 이렇게 되면 하루는 SQL, 하루는 알고리즘으로 분배를 다시 해야 할지도. 내일은 코드카타 생략하고 팀프로젝트로 바로 들어가는 날이니 판다스 2차 과제나 간단히 리뷰해 봐야겠다.