JAVA - 프로그래머스 3레벨 - 베스트 앨범

JAVA - 프로그래머스 3레벨 - 베스트 앨범

프로그래머스 42579번 문제


image


@DisplayName("프로그래머스 42579 - 베스트앨범")
class Programmers42579Test {
    Programmers42579 solve = new Programmers42579();

    static Stream<Arguments> solution() {
        return Stream.of(
            Arguments.of(
                new String[]{"classic", "pop", "classic", "classic", "pop"},
                new int[]{500, 600, 150, 800, 2500},
                new int[]{4, 1, 3, 0}
            )
        );
    }

    @MethodSource
    @ParameterizedTest
    void solution(String[] genres, int[] plays, int[] expected) throws Exception {
        int[] actual = solve.solution(genres, plays);
        assertThat(actual).isEqualTo(expected);
    }
}


문제 분류는 해쉬로 돼있는데, 사실상 구현문제에 더 가까운 것 같다.

문제의 요구사항을 모두 구현하되, 해쉬맵을 사용하면 쉽게 풀린다.

코드 자체가 딱히 효율적이진 않지만, 애초에 문제에 효율성 테스트가 없기 때문에 별 문제가 되지 않는 것 같다.


  • genres[i]는 고유번호가 i인 노래의 장르입니다.
  • plays[i]는 고유번호가 i인 노래가 재생된 횟수입니다.
  • genres와 plays의 길이는 같으며, 이는 1 이상 10,000 이하입니다.
  • 장르 종류는 100개 미만입니다.
  • 장르에 속한 곡이 하나라면, 하나의 곡만 선택합니다.
  • 모든 장르는 재생된 횟수가 다릅니다.


public class Programmers42579 {
    public int[] solution(String[] genres, int[] plays) {
        return IntStream.rangeClosed(0, genres.length - 1)
                .mapToObj(toMusic(genres, plays))
                .collect(groupingBy(Music::getGenre))
                .entrySet().stream()
                .sorted(inOrderOfMostPlayedGenre())
                .flatMap(twoInOrderOfMostPlayed())
                .mapToInt(Music::getId)
                .toArray();
    }

    private IntFunction<Music> toMusic(String[] genres, int[] plays) {
        return i -> Music.of(i, genres[i], plays[i]);
    }

    private Comparator<Entry<String, List<Music>>> inOrderOfMostPlayedGenre() {
        return (entry1, entry2) -> sum(entry2.getValue()) - sum(entry1.getValue());
    }

    private int sum(List<Music> value) {
        return value.stream()
                .mapToInt(Music::getPlayed)
                .sum();
    }

    private Function<Entry<String, List<Music>>, Stream<? extends Music>> twoInOrderOfMostPlayed() {
        return entry -> entry.getValue()
                .stream()
                .sorted()
                .limit(2);
    }

    private static class Music implements Comparable<Music> {
        private final int id;
        private final String genre;
        private final int played;

        private Music(int id, String genre, int played) {
            this.id = id;
            this.genre = genre;
            this.played = played;
        }

        private static Music of(int id, String genre, int played) {
            return new Music(id, genre, played);
        }

        private int getId() {
            return id;
        }

        private String getGenre() {
            return genre;
        }

        private int getPlayed() {
            return played;
        }

        @Override
        public int compareTo(Music music) {
            if (this.played == music.played) {
                return this.id - music.id;
            }
            return music.played - this.played;
        }
    }
}



© 2022. All rights reserved.