diff --git a/src/main/java/onboarding/Problem1.java b/src/main/java/onboarding/Problem1.java index b99e6b5e67..aef327008c 100644 --- a/src/main/java/onboarding/Problem1.java +++ b/src/main/java/onboarding/Problem1.java @@ -1,10 +1,88 @@ package onboarding; +import java.util.ArrayList; import java.util.List; class Problem1 { public static int solution(List pobi, List crong) { - int answer = Integer.MAX_VALUE; + int answer = 0; + + // 예외 처리 함수 호출 + if (!isValidInput(pobi) || !isValidInput(crong)) { + return -1; + } + + int pobiMaxScore = calculateMaxPageScore(pobi); + int crongMaxScore = calculateMaxPageScore(crong); + if (pobiMaxScore > crongMaxScore) return 1; + else if (pobiMaxScore < crongMaxScore) return 2; + return answer; } -} \ No newline at end of file + + // 예외 처리 함수 + public static boolean isValidInput(List pages) { + if (pages.size() != 2) { + return false; + } + int leftPage = pages.get(0); + int rightPage = pages.get(1); + + // 페이지 번호가 범위를 벗어나는 경우 + if (leftPage <= 1 || rightPage >= 400) { + return false; + } + + // 페이지 순서가 잘못되었거나 차이가 1이 아닌 경우 + if (rightPage <= leftPage || rightPage - leftPage != 1) { + return false; + } + + // 왼쪽 페이지는 홀수, 오른쪽 페이지는 짝수이어야 함 + if (leftPage % 2 != 1 || rightPage % 2 != 0) { + return false; + } + + return true; + } + + public static List splitDigits(int number) { + List result = new ArrayList<>(); + + while (number > 0) { + result.add(0, number % 10); + number = number / 10; + } + return result; + } + + public static Integer sumDigits(List digits) { + int sum = 0; + for (int digit : digits) { + sum += digit; + } + return sum; + } + + public static Integer multiplyDigits(List digits) { + int product = 1; + for (int digit : digits) { + product *= digit; + } + return product; + } + + public static Integer calculateMaxSumOrProduct(Integer page) { + List pageDigits = splitDigits(page); + int sumOfDigits = sumDigits(pageDigits); + int productOfDigits = multiplyDigits(pageDigits); + return Math.max(sumOfDigits, productOfDigits); + } + + public static Integer calculateMaxPageScore(List user) { + int maxLeftPageScore = calculateMaxSumOrProduct(user.get(0)); + int maxRightPageScore = calculateMaxSumOrProduct(user.get(1)); + + return Math.max(maxLeftPageScore, maxRightPageScore); + } +} diff --git a/src/main/java/onboarding/Problem2.java b/src/main/java/onboarding/Problem2.java index ee836e9cac..5693fc23a3 100644 --- a/src/main/java/onboarding/Problem2.java +++ b/src/main/java/onboarding/Problem2.java @@ -2,7 +2,40 @@ public class Problem2 { public static String solution(String cryptogram) { - String answer = "answer"; - return answer; + + // 길이 검증 + if (cryptogram == null || cryptogram.length() < 1 || cryptogram.length() > 1000) { + return "error"; + } + // 알파벳 소문자 검증 + if (!cryptogram.matches("^[a-z]+$")) { + return "error"; + } + + StringBuilder sb = new StringBuilder(cryptogram); + + while (true) { + boolean changed = false; + int count = 1; + for (int i = 0; i < sb.length() - 1; i++) { + if (sb.charAt(i) == sb.charAt(i + 1)) { + count++; + if(i + 1 == sb.length() - 1) { + sb.delete(i - count + 2, sb.length()); + return sb.toString(); + } + } else { + if (count > 1) { + sb.delete(i - count + 1, i + 1); + changed = true; + i = Math.max(-1, i - count - 1); // 변경 후 이전 위치부터 다시 검사 + } + count = 1; + } + } + if (!changed) break; + } + + return sb.toString(); } } diff --git a/src/main/java/onboarding/Problem3.java b/src/main/java/onboarding/Problem3.java index 12e095d6e3..c814793711 100644 --- a/src/main/java/onboarding/Problem3.java +++ b/src/main/java/onboarding/Problem3.java @@ -1,8 +1,26 @@ package onboarding; +import java.util.Arrays; +import java.util.List; + public class Problem3 { public static int solution(int number) { int answer = 0; + if(number < 1 || number > 10000) { + return -1; + } + + List clapNumbers = Arrays.asList(3, 6, 9); + + for(int i = 1; i <= number; i++) { + List digits = Problem1.splitDigits(i); + for (Integer digit : digits) { + if (clapNumbers.contains(digit)) { + answer++; + } + } + } + return answer; } } diff --git a/src/main/java/onboarding/Problem4.java b/src/main/java/onboarding/Problem4.java index 9bc4334fa9..581062d21d 100644 --- a/src/main/java/onboarding/Problem4.java +++ b/src/main/java/onboarding/Problem4.java @@ -1,8 +1,36 @@ package onboarding; public class Problem4 { + + private static final int LOWERCASE_TRANSFORM_BASE = 219; + private static final int UPPERCASE_TRANSFORM_BASE = 155; + public static String solution(String word) { String answer = ""; + + if(word.length() < 1 || word.length() > 1000) { + return "error"; + } + + for(int i = 0; i < word.length(); i++) { + char c = word.charAt(i); + + if(c == ' ') { + answer += ' '; + continue; + } + + char newChar; + if(c >= 'a' && c <= 'z') { //소문자 + newChar = (char) (LOWERCASE_TRANSFORM_BASE - c); + } else if (c >= 'A' && c <= 'Z') { // 대문자 변환 + newChar = (char) (UPPERCASE_TRANSFORM_BASE - c); + } else { + newChar = c; // 알파벳이 아닌 경우 그대로 유지 + } + answer += newChar; + } + return answer; } } diff --git a/src/main/java/onboarding/Problem5.java b/src/main/java/onboarding/Problem5.java index d6c4dbe09b..a4daf48110 100644 --- a/src/main/java/onboarding/Problem5.java +++ b/src/main/java/onboarding/Problem5.java @@ -1,11 +1,33 @@ package onboarding; +import java.util.ArrayList; import java.util.Collections; import java.util.List; public class Problem5 { public static List solution(int money) { - List answer = Collections.emptyList(); + + if (money < 1 || money > 1000000) { + return null; + } + + List answer = new ArrayList<>(); + final List moneyUnit = List.of( + 50000, + 10000, + 5000, + 1000, + 500, + 100, + 50, + 10, + 1 + ); + + for (int i = 0; i < moneyUnit.size(); i++) { + answer.add(money / moneyUnit.get(i)); + money = money % moneyUnit.get(i); + } return answer; } } diff --git a/src/main/java/onboarding/Problem6.java b/src/main/java/onboarding/Problem6.java index f6c7b32344..2f38efb145 100644 --- a/src/main/java/onboarding/Problem6.java +++ b/src/main/java/onboarding/Problem6.java @@ -1,10 +1,72 @@ package onboarding; +import java.util.ArrayList; +import java.util.Comparator; import java.util.List; public class Problem6 { public static List solution(List> forms) { - List answer = List.of("answer"); + List answer = new ArrayList<>(); + if (forms.size() < 1 || forms.size() > 10000) { + return null; + } + + for (int i = 0; i < forms.size(); i++) { + String email = forms.get(i).get(0); + String name = forms.get(i).get(1); + + if (!isValidEmail(email) || !isValidNickname(name) || answer.contains(email)) { + continue; + } + + checkDuplicateSubstrings(forms, i, name, email, answer); + } + + answer.sort(Comparator.naturalOrder()); return answer; } -} + + private static void checkDuplicateSubstrings(List> forms, int currentIndex, String currentName, String currentEmail, List answer) { + for (int j = currentIndex + 1; j < forms.size(); j++) { + String compName = forms.get(j).get(1); + String compEmail = forms.get(j).get(0); + + if (answer.contains(compEmail)) { + continue; + } + + if (hasDuplicateSubstring(currentName, compName)) { + answer.add(compEmail); + if (!answer.contains(currentEmail)) { + answer.add(currentEmail); + } + } + } + } + + private static boolean hasDuplicateSubstring(String name1, String name2) { + for (int k = 0; k < name2.length() - 1; k++) { + String subString = name2.substring(k, k + 2); + if (name1.contains(subString)) { + return true; + } + } + return false; + } + + private static boolean isValidEmail(String email) { + if (email.length() < 11 || email.length() >= 20) { + return false; + } + String emailPattern = "^[a-zA-Z0-9._%+-]+@email\\.com$"; + return email.matches(emailPattern); + } + + private static boolean isValidNickname(String name) { + if (name.length() < 1 || name.length() >= 20) { + return false; + } + String nicknamePattern = "^[가-힣]+$"; + return name.matches(nicknamePattern); + } +} \ No newline at end of file diff --git a/src/main/java/onboarding/Problem7.java b/src/main/java/onboarding/Problem7.java index 365540f5cd..0ba547e9be 100644 --- a/src/main/java/onboarding/Problem7.java +++ b/src/main/java/onboarding/Problem7.java @@ -1,11 +1,109 @@ package onboarding; -import java.util.Collections; -import java.util.List; +import java.util.*; public class Problem7 { + public static List solution(String user, List> friends, List visitors) { - List answer = Collections.emptyList(); - return answer; + // 예외 처리 함수 호출 + validateInput(user, friends, visitors); + + List recommendedFriends = new ArrayList<>(5); + HashMap friendScores = new HashMap<>(); + + List userFriends = extractUserFriends(user, friends); + addMutualFriendPoints(user, friends, friendScores, userFriends); + calculateVisitorPoints(visitors, userFriends, friendScores); + + List> sortedFriendEntries = sortFriendScores(friendScores); + + for (int i = 0; i < Math.min(5, sortedFriendEntries.size()); i++) { + recommendedFriends.add(sortedFriendEntries.get(i).getKey()); + } + + return recommendedFriends; + } + + // 예외 처리 함수 + private static void validateInput(String user, List> friends, List visitors) { + // 사용자 ID 길이 및 알파벳 소문자 검증 + if (user == null || user.length() < 1 || user.length() > 30 || !user.matches("[a-z]+")) { + throw new IllegalArgumentException("사용자 ID는 1자 이상 30자 이하의 알파벳 소문자여야 합니다."); + } + + // friends 리스트 크기 및 각 원소 검증 + if (friends == null || friends.size() < 1 || friends.size() > 10000) { + throw new IllegalArgumentException("friends 리스트는 1 이상 10,000 이하이어야 합니다."); + } + for (List friendPair : friends) { + if (friendPair == null || friendPair.size() != 2) { + throw new IllegalArgumentException("friends 리스트의 각 원소는 정확히 2개의 아이디로 이루어져야 합니다."); + } + for (String id : friendPair) { + if (id == null || id.length() < 1 || id.length() > 30 || !id.matches("[a-z]+")) { + throw new IllegalArgumentException("친구 아이디는 1자 이상 30자 이하의 알파벳 소문자여야 합니다."); + } + } + } + + // visitors 리스트 크기 및 각 원소 검증 + if (visitors == null || visitors.size() > 10000) { + throw new IllegalArgumentException("visitors 리스트는 0 이상 10,000 이하이어야 합니다."); + } + for (String visitor : visitors) { + if (visitor == null || visitor.length() < 1 || visitor.length() > 30 || !visitor.matches("[a-z]+")) { + throw new IllegalArgumentException("방문자 아이디는 1자 이상 30자 이하의 알파벳 소문자여야 합니다."); + } + } + } + + // 사용자 친구 목록 추출 + private static List extractUserFriends(String user, List> friends) { + List userFriends = new ArrayList<>(); + for (List friendPair : friends) { + if (friendPair.contains(user)) { + String friend = friendPair.get(0).equals(user) ? friendPair.get(1) : friendPair.get(0); + userFriends.add(friend); + } + } + return userFriends; + } + + // 함께 아는 친구에게 점수 추가 + private static void addMutualFriendPoints(String user, List> friends, HashMap friendScores, List userFriends) { + for (String friend : userFriends) { + for (List mutualFriendPair : friends) { + if (mutualFriendPair.contains(friend) && !mutualFriendPair.contains(user)) { + String mutualFriend = mutualFriendPair.get(0).equals(friend) ? mutualFriendPair.get(1) : mutualFriendPair.get(0); + + int currentScore = friendScores.getOrDefault(mutualFriend, 0); + friendScores.put(mutualFriend, currentScore + 10); + } + } + } + } + + private static void calculateVisitorPoints(List visitors, List userFriends, HashMap friendScores) { + for (String visitor : visitors) { + if (!userFriends.contains(visitor)) { + int currentScore = friendScores.getOrDefault(visitor, 0); + friendScores.put(visitor, currentScore + 1); + } + } + } + + // 정렬 함수 + private static List> sortFriendScores(HashMap friendScores) { + List> sortedEntries = new ArrayList<>(friendScores.entrySet()); + + sortedEntries.sort((entry1, entry2) -> { + int scoreComparison = entry2.getValue().compareTo(entry1.getValue()); + if (scoreComparison == 0) { + return entry1.getKey().compareTo(entry2.getKey()); + } + return scoreComparison; + }); + + return sortedEntries; } -} +} \ No newline at end of file diff --git a/src/test/java/onboarding/ApplicationTest.java b/src/test/java/onboarding/ApplicationTest.java index 4cdf3ed0ef..0c2db114c2 100644 --- a/src/test/java/onboarding/ApplicationTest.java +++ b/src/test/java/onboarding/ApplicationTest.java @@ -33,6 +33,38 @@ void case3() { int result = -1; assertThat(Problem1.solution(pobi, crong)).isEqualTo(result); } + + @Test + void case4() { + List pobi = List.of(1, 2, 3); + List crong = List.of(4, 5); + int result = -1; + assertThat(Problem1.solution(pobi, crong)).isEqualTo(result); + } + + @Test + void case5() { + List pobi = List.of(399, 400); + List crong = List.of(3, 4); + int result = -1; + assertThat(Problem1.solution(pobi, crong)).isEqualTo(result); + } + + @Test + void case6() { + List pobi = List.of(102, 99); + List crong = List.of(4, 5); + int result = -1; + assertThat(Problem1.solution(pobi, crong)).isEqualTo(result); + } + + @Test + void case7() { + List pobi = List.of(3, 4); + List crong = List.of(200, 201); + int result = -1; + assertThat(Problem1.solution(pobi, crong)).isEqualTo(result); + } } @Nested @@ -50,6 +82,34 @@ void case2() { String result = ""; assertThat(Problem2.solution(cryptogram)).isEqualTo(result); } + + @Test + void case3() { + String cyptogram = "bowwwwwww"; + String result = "bo"; + assertThat(Problem2.solution(cyptogram)).isEqualTo(result); + } + + @Test + void case4() { + String cyptogram = "brrro"; + String result = "bo"; + assertThat(Problem2.solution(cyptogram)).isEqualTo(result); + } + + @Test + void case5() { + String cyptogram = "wwwwwwbrrrowwwwwww"; + String result = "bo"; + assertThat(Problem2.solution(cyptogram)).isEqualTo(result); + } + + @Test + void case6() { + String cyptogram = "ABt"; + String result = "error"; + assertThat(Problem2.solution(cyptogram)).isEqualTo(result); + } } @Nested @@ -67,6 +127,13 @@ void case2() { int result = 14; assertThat(Problem3.solution(number)).isEqualTo(result); } + + @Test + void case3() { + int number = -1; + int result = -1; + assertThat(Problem3.solution(number)).isEqualTo(result); + } } @Nested @@ -94,6 +161,12 @@ void case2() { List result = List.of(0, 1, 1, 0, 0, 0, 0, 0, 0); assertThat(Problem5.solution(money)).isEqualTo(result); } + + @Test + void case3() { + int money = 1000001; + assertThat(Problem5.solution(money)).isNull(); + } } @Nested