본문 바로가기
Java/우테코 프리코스

[Onboarding] 문제1, 문제2

by 위대한초밥V 2023. 6. 28.

지난 가을에 공부한 참여한 우테코 프리코스 과제들을 리펙토링하면서 부족한 내용을 채워보려고 한다! 화이팅 :)

 

온보딩 과제에서 얻어가고 싶은 내용들은 헷갈리는 문법 정리 위주로 공부가 될 것 같다. 

더불어 이미 제출한 사람들의 결과물을 보면서 부족한 부분을 채울 예정이다.

 

https://github.com/woowacourse-precourse/java-onboarding

 

GitHub - woowacourse-precourse/java-onboarding: 온보딩 미션을 진행하는 저장소

온보딩 미션을 진행하는 저장소. Contribute to woowacourse-precourse/java-onboarding development by creating an account on GitHub.

github.com

 


문제 1️⃣ 

요구사항 분석

  • 포비와 크롱의 책 페이지 배열이 유효한 배열/리스트인지 검증한다.
    • 연속되지 않은 값은 유효환 리스트/배열이 아니다.
    • 짝수 -> 홀수는 유효한 리스트/배열이 아니다.
    • 시작 면(1페이지)이나 마지막 면(400페이지)이 나오면 유효한 리스트/배열이 아니다.
  • 가장 큰 값을 구한다.
    1. 각 페이지 번호의 자리수를 구한다.
    2. 각 페이지 번호의 자리수를 더하거나, 모두 곱한 값한다.
      • 각자의 왼쪽 페이지 번호와 각 자리의 숫자를 모두 더하거나, 모두 곱한 값 중 더 큰 값을 반환한다.
      • 각자의 오른쪽 페이지 번호의 각 자리 숫자를 모두 더하거나, 모두 곱한 값 중 더 큰 값을 반환한다.
  • 포비와 크롱의 점수를 비교한다.
    • 포비의 점수가 큰 경우: 1
    • 크롱의 점수가 큰 경우: 2
    • 포비와 크롱의 점수가 같은 경우(무승부): 0
    • 예외 상황: -1

코드

import java.util.List;
import java.util.stream.Stream;

class Problem1 {
    private static final int DRAW = 0;
    private static final int WINNER_IS_POBI = 1;
    private static final int WINNER_IS_CRONG = 2;
    private static final int EXCEPTION_CONDITION = -1;
    private static final int START_PAGE = 1;
    private static final int END_PAGE = 400;

    public static int solution(List<Integer> pobi, List<Integer> crong) {
        int answer = Integer.MAX_VALUE;

        if (!isValidPage(pobi) || !isValidPage(crong)) {
            return EXCEPTION_CONDITION;
        }
        answer = calculateGameResult(pobi, crong);

        return answer;
    }

    private static int calculateGameResult(List<Integer> pobi, List<Integer> crong) {
        if (calculateScore(pobi) > calculateScore(crong)) {
            return WINNER_IS_POBI;
        } else if (calculateScore(pobi) < calculateScore(crong)) {
            return WINNER_IS_CRONG;
        } else {
            return DRAW;
        }
    }

    private static int calculateScore(List<Integer> player) {
        int[] leftPage = integerToDigit(player.get(0));
        int[] rightPage = integerToDigit(player.get(1));

        int leftResult = calculatePageNumber(leftPage);
        int rightResult = calculatePageNumber(rightPage);

        return Math.max(leftResult, rightResult);
    }

    private static int calculatePageNumber(int[] pages) {
        int addResult = 0;
        int multipleResult = 1;
        for (int page : pages) {
            addResult += page;
            multipleResult *= page;
        }

        return Math.max(addResult, multipleResult);
    }

    private static int[] integerToDigit(Integer integer) {
        return Stream.of(String.valueOf(integer).split("")).mapToInt(Integer::parseInt).toArray();
    }

    private static boolean isValidPage(List<Integer> page) {
        if (page.get(1) - page.get(0) != 1) {
            return false;
        }
        if (page.get(0) % 2 == 0) {
            return false;
        }
        return !page.contains(START_PAGE) || !page.contains(END_PAGE);    // 처음 또는 마지막이라면
    }
}

 

숫자를 int형의 배열로 반환하는 함수

private static int[] integerToDigit(Integer integer) {
	return Stream.of(String.valueOf(integer).split("")).mapToInt(Integer::parseInt).toArray();
}
  1. String.valueOf(integer).split("")
    string형으로 변환하고 "" 기준으로 구분하여 문자열을 분할한다.
    ex) 123 -> ["1", "2", "3"]
  2. Stream.of(...)는 문자 배열에서 스트림을 생성한다. 
    스트림으로 병렬 또는 순차적으로 처리할 수 있다.
  3. mapToInt(Integer::parseInt)
    스트림의 각 요소를 문자열에서 정수로 변환한다. 
  4. toArray()
    스트림 요소를 수집하고 해당 요소를 포함하는 배열을 반환한다.

 


 

문제 2️⃣

요구사항 분석

  • 중복되고 연속된 문자열이 존재하고, 문자열이 0보다 클 때까지 반복한다.
    • 연속되는 중복된 문자열을 찾는다.
    • 연속되는 중복된 문자열을 삭제한다.

코드

public class Problem2 {
    public static String solution(String cryptogram) {
        while (cryptogram.length() > 0 && isDuplicated(cryptogram)) {
            cryptogram = deleteDuplicatedLetter(cryptogram);
        }
        return cryptogram;
    }

    private static boolean isDuplicated(String cryptogram) {
        char previous = cryptogram.charAt(0);

        for (int letter = 1; letter < cryptogram.length(); letter++) {
            if (previous == cryptogram.charAt(letter)) {
                return true;
            } else {
                previous = cryptogram.charAt(letter);
            }
        }
        return false;
    }

    private static String deleteDuplicatedLetter(String cryptogram) {
        StringBuilder result = new StringBuilder();
        int prevIndex = 0;

        for (int nowIndex = 0; nowIndex < cryptogram.length(); nowIndex++) {
            if (cryptogram.charAt(prevIndex) != cryptogram.charAt(nowIndex)) {
                if (prevIndex + 1 == nowIndex) {
                    result.append(cryptogram.charAt(prevIndex));
                }
                prevIndex = nowIndex;
                if (nowIndex + 1 == cryptogram.length()) {
                    result.append(cryptogram.charAt(prevIndex));
                }
            }
        }
        return result.toString();
    }
}

deleteDuplicatedLetter는 prevIndex와 nowIndex 값을 비교하고 나타내는 값이 다르면 추가하고, 같으면 제거해야하기 때문에 추가하지 않는다. 

반응형