[C#] 베스트앨범

소슬잎·2023년 11월 22일

프로그래머스 문제

https://school.programmers.co.kr/learn/courses/30/lessons/42579

풀이 후기

1. 분석

딱히 분석할 것도 없고 해쉬나 딕셔너리 한번 써보라고 있는 문제다. 일단 풀기는 했는데 시간제한도 딱히 없는 것 같고 최대한 Linq 돌려서 풀릴 것 같아서 그렇게 풀어봤다.

2. 실행 결과

3. 코드

using System;
using System.Linq;

public class Solution {
    public int[] solution(string[] genres, int[] plays) {
        return genres
            .Select((t, i) => new { Index = i, Genre = t, Play = plays[i] })
            .GroupBy(k => k.Genre)
            .Select(gm =>
                new {
                    gm.Key,
                    plays = gm.Sum(i => i.Play),
                    data = gm.OrderByDescending(m => m.Play)
                })
            .OrderByDescending(newM => newM.plays)
            .SelectMany(newM => newM.data.Take(2))
            .Select(m => m.Index)
            .ToArray();
    }
}

이것도 줄여지나? 하다보니까 코드를 다 쳐냈다.

4. 코드 해설

.Select((t, i) => new { Index = i, Genre = t, Play = plays[i] })

select는 해당 작업을 수행하고 결과를 모음. (t, i)와 같이 2개의 인자가 들어갈 경우, (앞에는 컬렉션의 요소, 인덱스 번호) 요렇게 된다. for문 안써도 되는게 편함. new { }은 익명 형식인데 아래에 적음.

.GroupBy(k => k.Genre)

그룹별로 집계한다. 여기서 k는 만들어둔 익명 형식. (Key = 음악 장르, 같은 장르의 곡들) 이런 객체가 완성.

.Select(gm =>
                new {
                    gm.Key,
                    plays = gm.Sum(i => i.Play),
                    data = gm.OrderByDescending(m => m.Play)
                })

모든 음악 장르에 대하여, 익명 형식(https://learn.microsoft.com/ko-kr/dotnet/csharp/fundamentals/types/anonymous-types)을 제작한다. 대충 처리 가능한 객체 느낌이다.

여기까지 (장르, 종합 플레이 수, 정렬된 같은 장르의 곡들)인 객체를 쿼리 딸깍으로 만들었다.

.OrderByDescending(newM => newM.plays)

이제 그 객체를 종합 플레이 수로 다시 정렬한다.

.SelectMany(newM => newM.data.Take(2))

'시퀀스의 각 요소를 IEnumerable<T\>에 투영하고 결과 시퀀스를 단일 시퀀스로 평면화합니다.' 라고 공식 문서에 쓰여 있는데 솔직히 이해는 안 됐고 내부 요소를 밖으로 끄집어 온다는 정도로만 생각 중.

.Select(m => m.Index)
.ToArray();

필요한 Index만 가져와서 배열로 변환하면 끝. 벌써 기술 면접이 걱정되는데 연습을 해야 할 것 같다.

profile
그냥 바보

0개의 댓글