링크 : 프로그래머스 > Level 1 > 신고 결과 받기
40분
public class GetReportResultTest {
/**
* 게시판의 사용자 목록(ID)과 신고 정보 목록 그리고 사용정지에 해당하는 신고횟수를 입력 받아서 각 사용자 별 신고 결과 알림을 받는 횟수를 반환합니다.
* @param users 사용자 목록
* @param report "A B"인 경우 A가 B를 신고한 정보를 뜻합니다. 신고 정보가 중복되는 경우 사용정지를 위한 통계에 포함시키지 않습니다. 자신이 자기를 신고하는 경우는 없습니다.
* @param dropOutNum 해당 숫자 이상 신고를 받은 사용자는 사용정지 대상이 됩니다.
* @return 사용정지된 사용자를 신고한 횟수
*/
public int[] solution(String[] users, String[] report, int dropOutNum) {
// 각 사용자를 신고한 사람 목록을 중복을 제외하고 수집합니다.
HashMap<String, Set<String>> userAndReportersMap = new HashMap<>();
IntStream.range(0, users.length)
.forEach(i -> userAndReportersMap.put(users[i], new HashSet<>()));
IntStream.range(0, report.length).forEach(i -> {
String[] reporterAndTargetUser = report[i].split(" ");
String reporter = reporterAndTargetUser[0];
String targetUser = reporterAndTargetUser[1];
Set<String> reporters = userAndReportersMap.get(targetUser);
reporters.add(reporter);
});
// 각 사용자의 사용중지될 사용자 신고 횟수를 카운트 합니다.
HashMap<String, Integer> reporterAndAlarmCountMap = new HashMap<>();
IntStream.range(0, users.length)
.forEach(i -> reporterAndAlarmCountMap.put(users[i], 0));
userAndReportersMap.forEach( (user, reporters) -> {
if (reporters.size() >= dropOutNum) {
reporters.forEach(reporter -> {
int alarmNum = reporterAndAlarmCountMap.get(reporter);
alarmNum++;
reporterAndAlarmCountMap.put(reporter, alarmNum);
});
}
});
// 약속된 정수 배열로 반환합니다.
int[] alarmNums = new int[users.length];
IntStream.range(0, users.length)
.forEach(i -> alarmNums[i] = reporterAndAlarmCountMap.get(users[i]));
return alarmNums;
}
}
40분이라는 시간동안 테스트 케이스를 통과하도록 작성한 날 것 그대로의 코드입니다.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class GetReportResultTest {
/**
* 게시판의 사용자 목록(ID)과 신고 정보 목록 그리고 사용정지에 해당하는 신고횟수를 입력 받아서 각 사용자 별 신고 결과 알림을
* 받는 횟수를 반환합니다.
* @param users 사용자 목록
* @param report "A B"인 경우 A가 B를 신고한 정보를 뜻합니다. 신고 정보가 중복되는 경우 사용정지를 위한 통계에 포함시키지 않습니다. 자신이 자기를 신고하는 경우는 없습니다.
* @param dropOutNum 해당 숫자 이상 신고를 받은 사용자는 사용정지 대상이 됩니다.
* @return 사용정지된 사용자를 신고한 횟수
*/
public int[] solution(String[] users, String[] report, int dropOutNum) {
// "A B" (A가 B를 신고) 형식의 리포트를 분석해서 누가, 누구를 신고했는지 정보를 모읍니다.
// 사용자 별로 자신을 신고한 다른 사용자 목록을 알고 있어야 합니다.
HashMap<String, List<String>> myReportUserMap = new HashMap<>();
IntStream.range(0, users.length)
.forEach(i -> myReportUserMap.put(users[i], new ArrayList<>()));
IntStream.range(0, report.length)
.forEach(i -> {
String[] aReportB = report[i].split(" ");
List<String> myReportUser = myReportUserMap.get(aReportB[1]);
if (!myReportUser.contains(aReportB[0])) {
myReportUser.add(aReportB[0]);
}
});
// 결국 사용 중지 당한 사용자를 신고한 사람을 카운팅 해야합니다.
HashMap<String, Integer> alarmNumMap = new HashMap<>();
IntStream.range(0, users.length)
.forEach(i -> alarmNumMap.put(users[i], 0));
myReportUserMap.forEach( (user, myReportUsers) -> {
if (myReportUsers.size() >= dropOutNum) {
myReportUsers.forEach(reportUser -> {
int alarmNum = alarmNumMap.get(reportUser);
alarmNum++;
alarmNumMap.put(reportUser, alarmNum);
});
}
});
// 최종적으로 사용자 별로 사용정지된 사용자를 신고한 횟수를 반환합니다.
int[] alarmNums = new int[users.length];
IntStream.range(0, users.length)
.forEach(i -> alarmNums[i] = alarmNumMap.get(users[i]));
return alarmNums;
}
}
@Test
void getOrDefault() {
// Given
Map<String, Integer> userAndAgeMap = new HashMap<>();
userAndAgeMap.put("Joo", 40);
userAndAgeMap.put("Yang", 39);
// Expected
Assertions.assertEquals(10, userAndAgeMap.getOrDefault("SSa", 10));
Assertions.assertEquals(40, userAndAgeMap.getOrDefault("Joo", 10));
Assertions.assertEquals(39, userAndAgeMap.getOrDefault("Yang", 10));
}
@Test
void distinctRemovesDuplicatedItems() {
// When
List<Integer> integers = Stream.of(1, 2, 3, 4, 5, 5, 4, 3, 2, 1)
.distinct()
.toList();
// Expected
Assertions.assertArrayEquals(new Integer[] { 1, 2, 3, 4, 5 }, integers.toArray());
}
혼자 문제를 풀고 리팩토링해 보는데 아쉬운 마음이 듭니다. 다른 사람들과 같이 리뷰도 하고, 내 머리 밖에 있는 더 좋은 방법들에 대해 교류하면 좋겠다는 생각이 듭니다.