JAVA - 프로그래머스 3레벨 - 베스트 앨범
in Computer Science / Data-structure-algorithm
프로그래머스 42579번 문제
@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;
}
}
}