우테코 온보딩 - Problem 1 문제 풀이
문제 설명
포비와 크롱이 페이지 번호가 1부터 시작되는 400 페이지의 책을 주웠다. 책을 살펴보니 왼쪽 페이지는 홀수, 오른쪽 페이지는 짝수 번호이고 모든 페이지에는 번호가 적혀있었다. 책이 마음에 든 포비와 크롱은 페이지 번호 게임을 통해 게임에서 이긴 사람이 책을 갖기로 한다. 페이지 번호 게임의 규칙은 아래와 같다.
1. 책을 임의로 펼친다.
2. 왼쪽 페이지 번호의 각 자리 숫자를 모두 더하거나, 모두 곱해 가장 큰 수를 구한다.
3. 오른쪽 페이지 번호의 각 자리 숫자를 모두 더하거나, 모두 곱해 가장 큰 수를 구한다.
4. 2~3 과정에서 가장 큰 수를 본인의 점수로 한다.
5. 점수를 비교해 가장 높은 사람이 게임의 승자가 된다.
6. 시작 면이나 마지막 면이 나오도록 책을 펼치지 않는다.
포비와 크롱이 펼친 페이지가 들어있는 리스트/배열 pobi와 crong이 주어질 때, 포비가 이긴다면 1, 크롱이 이긴다면 2, 무승부는 0, 예외사항은 -1로 return 하도록 solution 메서드를 완성하라.
제한사항
- pobi와 crong의 길이는 2이다.
- pobi와 crong에는 [왼쪽 페이지 번호, 오른쪽 페이지 번호]가 순서대로 들어있다.
문제의 자세한 내용은 해당 링크를 통해 확인 : 문제 링크
풀이 코드
package onboarding;
import java.util.List;
import java.util.stream.Stream;
class Problem1 {
public static int solution(List<Integer> pobi, List<Integer> crong) {
int answer = 0;
int pobiMax = maxResult(pobi);
int crongMax = maxResult(crong);
if(pobiMax == -1 || crongMax == -1) {
return -1;
}
if(pobiMax > crongMax) {
answer = 1;
} else if (pobiMax < crongMax) {
answer = 2;
} else {
answer = 0;
}
return answer;
}
private static int maxResult(List<Integer> list) {
int max = 0;
if(exceptionCheck(list)) {
return -1;
}
for(Integer i : list) {
int sum = Stream.of(String.valueOf(i).split("")).mapToInt(Integer::parseInt).sum();
int mul = Stream.of(String.valueOf(i).split("")).mapToInt(Integer::parseInt).reduce(1, (a, b) -> a * b);
int calcMax = Math.max(sum, mul);
if(max < calcMax) {
max = calcMax;
}
}
return max;
}
private static boolean exceptionCheck(List<Integer> list) {
int minPage = 1, maxPage = 400;
if(list.size() != 2) {
return true;
}
for(int i = 1; i < list.size(); i++) {
Integer right = list.get(i);
Integer left = list.get(i - 1);
if(left % 2 != 1 || right % 2 != 0) {
return true;
}
if(left <= minPage) {
return true;
}
if(right >= maxPage) {
return true;
}
if(right - left != 1) {
return true;
}
}
return false;
}
}
문제 해결 전략
이라 쓰고 문제를 보고서 어떻게 풀면 될까?에 대한 생각을 정리한 항목
일단 예외 사항은 뒤로 미루고, 점수를 구하는 로직을 우선 구현하고자 생각
점수를 구하는 로직은 여러번 반복하여 사용하며, 하나의 동작이므로 메서드를 나누어 구현하고자 생각 (maxResult() 메서드)
왼쪽과 오른쪽 페이지의 숫자를 문자열로 변경 후 split("")을 사용하여 한자리로 변경 -> stream을 사용하여 Integer로 변환 후 덧셈과 곱셈의 값을 각각 구하여 큰 값을 max 변수에 대입 후 반환
이 때 max 변수의 초기값은 '0'으로 주어도 되는 이유는 제한 조건으로 인하여 페이지의 숫자는 무조건 2보다 크고 399 보다 작은 숫자이며, 덧셈도 포함하기 때문에 0보다 작은 수가 나올 수 없기 때문
점수를 구하는 로직 구현 후 예외 사항을 확인하는 메서드를 구현하여 점수를 구하는 메서드의 시작 부분에 호출하여 예외 상황이 확인 되도록 구현
예외 사항은 아래와 같이 생각하여 구현
- 왼쪽 페이지가 짝수 또는 오른쪽 페이지가 홀수인 경우
- 왼쪽 페이지가 1보다 작거나 같은 경우
- 오른쪽 페이지가 400보다 크거나 같은 경우
- 왼쪽 페이지와 오른쪽 페이지의 차이가 1이 아닌 경우
이러한 예외 사항을 나중에 코드를 확인할 때 알아보기 편하도록 메서드로 나누어 구현 후 호출하는 형태로 하는게 좋을지는 잘 모르겠어서 하나의 메서드에 if문을 사용하여 해결
코드를 업로드해 둔 깃 허브
'Develop > Algorithm' 카테고리의 다른 글
우테코 온보딩 - Problem 3 (2) | 2022.11.09 |
---|---|
우테코 온보딩 - Problem 2 (0) | 2022.11.09 |
프로그래머스 lv.2 - 12939 최댓값과 최솟값 (0) | 2022.11.04 |
프로그래머스 lv.1 - 131128 숫자 짝꿍 (2) | 2022.11.03 |
프로그래머스 lv.2 - 92335 k진수에서 소수 개수 구하기 (0) | 2022.11.03 |