240513_TIL

J Lee·2024년 5월 13일
0

아무리 사소하더라도 배움이 없는 날은 없다.

SQL 코드카타 115번
난이도가 medium이었지만 비교적 간단하게 풀렸던 문제.

  1. 가장 리뷰를 많이 남긴 사람 이름을 찾는 쿼리 (동률일 경우 ABC순으로 먼저 있는 사람)
select u.name as results from
MovieRating mr
left join Users u on mr.user_id = u.user_id
group by 1
order by count(*) desc, u.name
limit 1
  1. 2020년 2월 기준으로 평균 평점이 가장 높은 영화 제목을 찾는 쿼리 (동률일 경우 ABC순으로 먼저 있는 영화)
select m.title as results
from MovieRating mr
left join Movies m on mr.movie_id = m.movie_id
where date_format(created_at,'%Y-%m') = '2020-02'
group by 1
order by avg(rating) desc, m.title
limit 1
  1. 이 둘을 수직결합하면 된다.
    단, 사람 이름과 영화 제목이 같을(e.g. Rebecca) 경우에는 Rebecca를 두 번 출력해야 하므로, 그냥 union이 아니라 중복을 허용하는 union all을 써야 함.
(SELECT u.name AS results
 FROM   movierating mr
        LEFT JOIN users u
               ON mr.user_id = u.user_id
 GROUP  BY 1
 ORDER  BY Count(*) DESC,
           u.name
 LIMIT  1)
UNION ALL
(SELECT m.title AS results
 FROM   movierating mr
        LEFT JOIN movies m
               ON mr.movie_id = m.movie_id
 WHERE  Date_format(created_at, '%Y-%m') = '2020-02'
 GROUP  BY 1
 ORDER  BY Avg(rating) DESC,
           m.title
 LIMIT  1) 

알고리즘 코드카타 39번

두 수를 입력받아 두 수의 최대공약수와 최소공배수를 반환하는 함수, solution을 완성해 보세요. 배열의 맨 앞에 최대공약수, 그다음 최소공배수를 넣어 반환하면 됩니다. 예를 들어 두 수 3, 12의 최대공약수는 3, 최소공배수는 12이므로 solution(3, 12)는 [3, 12]를 반환해야 합니다.

처음에 작성한 코드.
테스트 케이스는 통과했는데 제출 결과 오답 케이스가 많았다.

def solution(n, m):
    min = 0
    max = 0
    if n < m:
        if m%n == 0:
            min = n
            max = m
        else:
            min = 1
            max = n*m
    if n == m:
        min = n
        max = n
    if n > m:
        if n%m == 0:
            min = m
            max = n
        else:
            min = 1
            max = n*m
    return [min,max]

숫자가 한 자릿수로 작을 때는 저 정도 로직이면 될 줄 알았는데, 조금만 커져도 커버하지 못하는 케이스가 있었다. 예를 들어 n = 21, m = 36이라고 하면 첫 번째 분기를 타지만 min은 1이 아니라 3이고 max도 252다. (21×36이 아니라) 다른 로직이 필요할 것 같아서 최대공약수부터 구하고 그를 활용해서 최소공배수를 구해보기로.

def solution(n, m):
    div_n = []
    div_m = []
    for i in range(1,n+1):
        if n%i == 0:
            div_n.append(i)
    for j in range(1,m+1):
        if m%j == 0:
            div_m.append(j)
    nm_min = max(set(div_n) & set(div_m))               #최대공약수 정의
    nm_max = nm_min * (n//nm_min) * (m//nm_min)         #최소공배수 정의
    answer = [nm_min, nm_max]
    return answer
  1. 먼저 n과 m의 약수를 각각 div_n, div_m이라는 리스트에 담은 후,
  2. set(div_n) & set(div_m)으로 두 리스트의 공통된 값(공약수)을 찾고
  3. max(set(div_n) & set(div_m))까지 해서 최대공약수를 찾아준다.
  4. 최소공배수는 어떤 두 수를 최대공약수로 나눈 각각의 몫과 최대공약수를 모두 곱하면 구할 수 있으므로, 새로운 변수 nm_max를 정의한다.
  5. 새로운 리스트 answer에 두 값을 담아서 반환하면 정답.
profile
기본기를 소홀히 하지 말자

0개의 댓글