Data/HackerRank

HackerRank - Challenges

corycory 2022. 3. 2. 23:26
728x90
반응형

https://www.hackerrank.com/challenges/challenges/problem?isFullScreen=true

 

Challenges | HackerRank

Print the total number of challenges created by hackers.

www.hackerrank.com

 

 

문제

 

Julia asked her students to create some coding challenges. Write a query to print the hacker_id, name, and the total number of challenges created by each student. Sort your results by the total number of challenges in descending order. If more than one student created the same number of challenges, then sort the result by hacker_id. If more than one student created the same number of challenges and the count is less than the maximum number of challenges created, then exclude those students from the result.

Input Format

The following tables contain challenge data:

  • Hackers: The hacker_id is the id of the hacker, and name is the name of the hacker.
  • Challenges: The challenge_id is the id of the challenge, and hacker_id is the id of the student who created the challenge.

Sample Input 0

Hackers Table:

Challenges Table:

Sample Output 0

21283 Angela 6
88255 Patrick 5
96196 Lisa 1

Sample Input 1

Hackers Table:

Challenges Table:

Sample Output 1

12299 Rose 6
34856 Angela 6
79345 Frank 4
80491 Patrick 3
81041 Lisa 1

 

Explanation

For Sample Case 0, we can get the following details:


Students  and  both created  challenges, but the maximum number of challenges created is  so these students are excluded from the result.

 

 

풀이

다소 지저분하게 풀긴 했다;;;

이 문제의 포인트는 이 조건이다. 위의 Explanation에서 Rose, Frank 둘다 4개씩 만들었는데, 가장 많이 만든 갯수는 Angela가 만든 6개 이므로 Rose, Frank의 값은 둘다 빼야 한다. 만약 안젤라 외에도 6개를 만든 사람이 또 있다면 포함한다. 

 

좀더 깔끔하게 풀 수 있는 방법이 있으면 좋을텐데, 일단 나는 조인 여러번 해서 푸는 방식으로 풀었다. 먼저 해커 아이디 별로 만들어진 챌린지 수를 구하고, unique한 챌린지 수가 1이거나 챌린지 값이 max(챌린지값)인 것만 가져온다. 그 다음에 이거를 해커 아이디별로 만들어진 챌린지수에 inner join 해서 가져오는 식이다. 그 다음에는 챌린지 값을 내림차순으로, 해커이름을 오름차순으로 정렬해주면 된다.

 

/*
Write a query to print the hacker_id, name, and the total number of challenges created by each student. Sort your results by the total number of challenges in descending order. 

If more than one student created the same number of challenges, then sort the result by hacker_id. If more than one student created the same number of challenges and the count is less than the maximum number of challenges created, then exclude those students from the result.
*/
select h.hacker_id, h.name, cha.challenge_count
from hackers h
left join
(select hacker_id, count(challenge_id) as challenge_count from challenges group by 1) cha
on h.hacker_id = cha.hacker_id
inner join
(
select ch2.challenge_count
from
    (
    select 
        ch.challenge_count, count(ch.challenge_count) as dup_count
    from
        (
        select hacker_id, count(challenge_id) as challenge_count 
        from challenges group by 1
        ) ch
    group by 1
    ) ch2
    where ch2.dup_count = 1 
    or ch2.challenge_count = (select max(t.challenge_count) from
    (select hacker_id, count(challenge_id) as challenge_count 
     from challenges group by 1) t)
) c
on cha.challenge_count = c.challenge_count
order by 3 desc, hacker_id

 

 

추가

디스커션 란에 있던 다른 사람의 코드인데, having을 쓰니까 더 깔끔하게 가져올 수 있는거 같다.

/* these are the columns we want to output */
select c.hacker_id, h.name ,count(c.hacker_id) as c_count

/* this is the join we want to output them from */
from Hackers as h
    inner join Challenges as c on c.hacker_id = h.hacker_id

/* after they have been grouped by hacker */
group by c.hacker_id

/* but we want to be selective about which hackers we output */
/* having is required (instead of where) for filtering on groups */
having 

    /* output anyone with a count that is equal to... */
    c_count = 
        /* the max count that anyone has */
        (SELECT MAX(temp1.cnt)
        from (SELECT COUNT(hacker_id) as cnt
             from Challenges
             group by hacker_id
             order by hacker_id) temp1)

    /* or anyone who's count is in... */
    or c_count in 
        /* the set of counts... */
        (select t.cnt
         from (select count(*) as cnt 
               from challenges
               group by hacker_id) t
         /* who's group of counts... */
         group by t.cnt
         /* has only one element */
         having count(t.cnt) = 1)

/* finally, the order the rows should be output */
order by c_count DESC, c.hacker_id

/* ;) */
;
반응형

'Data > HackerRank' 카테고리의 다른 글

HackerRank - The Report  (0) 2022.03.03
HackerRank - Occupations  (0) 2022.03.03
HackerRank - Weather Observation Station 20  (0) 2022.03.02
HackerRank - Binary Tree Nodes  (0) 2022.03.02
HackerRank - The PADS  (0) 2022.03.01