diff --git a/src/main/java/week1/problem1/Problem1.java b/src/main/java/week1/problem1/Problem1.java new file mode 100644 index 0000000..7407851 --- /dev/null +++ b/src/main/java/week1/problem1/Problem1.java @@ -0,0 +1,65 @@ +package main.java.week1.problem1; + +import java.util.Arrays; + +public class Problem1 { + + public Problem1() { + } + + public int solution1(int[] input) { + int output = 0; + for (int i : input) { + output += i; + } + return output; + } + + public int solution2_1(int[] input) { + if (input.length == 0) { + return 0; + } + if (input.length == 1) { + return input[0]; + } + int mid = input.length / 2; + return solution2_1(Arrays.copyOfRange(input, 0, mid)) + solution2_1(Arrays.copyOfRange(input, mid, input.length)); + } + + public int solution2_2(int[] input) { + return plus_1(input, input.length - 1); + } + + public int solution3(int[] input) { + return plus_2(input, input.length - 1, 0); + } + + public int solution4(int[] input) { + return plus_3(input, input.length - 1); + } + + private int plus_1(int[] input, int index) { + if (index < 0) { + return 0; + } + return input[index] + plus_1(input, index - 1); + } + + private int plus_2(int[] input, int index, int output) { + if (index < 0) { + return output; + } + return plus_2(input, index - 1, output + input[index]); + } + + private int plus_3(int[] input, int index) { + int output = 0; + while (true) { + if (index < 0) { + return output; + } + output += input[index]; + index--; + } + } +} \ No newline at end of file diff --git a/src/main/java/week1/problem1/README.md b/src/main/java/week1/problem1/README.md new file mode 100644 index 0000000..74a6533 --- /dev/null +++ b/src/main/java/week1/problem1/README.md @@ -0,0 +1,23 @@ +# 자료구조와 알고리즘 1주차 과제 - 총합 구하기 + +숫자의 배열을 받아서 총합을 구하는 함수를 구현해 주세요. + +## 요구 사항 + +1. 가장 익숙한 방법으로 문제를 해결해 주세요. +2. 이번에는 재귀 함수로 문제를 해결해 주세요. +3. 꼬리 재귀 함수로 바꿔보세요. +4. 꼬리 재귀 최적화를 통해서 최적화해 보세요. + +### 입력 예시 + +| numbers | return | +| --- | --- | +| [1, 2, 3, 4] | 10| +| [-1, 3, 8, 9, 10, 11] | 40 | +| [] | 0 | + +## 제한조건 + +- 모든 테스트를 통과해야 합니다. +- 스스로 문제 해결법을 떠올리기 위해 Copilot은 사용하지 말아주세요. diff --git a/src/main/java/week1/problem2/Problem2.java b/src/main/java/week1/problem2/Problem2.java new file mode 100644 index 0000000..9504ba6 --- /dev/null +++ b/src/main/java/week1/problem2/Problem2.java @@ -0,0 +1,52 @@ +package main.java.week1.problem2; + +public class Problem2 { + + public Problem2() { + } + + public int solution1(int input) { + if (input < 2) { + return input; + } + int[] dp = new int[input + 1]; + dp[0] = 0; + dp[1] = 1; + for (int i = 2; i <= input; i++) { + dp[i] = dp[i - 1] + dp[i - 2]; + } + return dp[input]; + } + + public int solution2(int input) { + if (input == 0 || input == 1) { + return input; + } + return solution2(input - 1) + solution2(input - 2); + } + + + public int solution3(int input) { + return plus_1(input, 0); + } + + public int solution4(int input) { + return plus_2(input, 0); + } + + private int plus_1(int input, int output) { + if (input == 0 || input == 1) { + return input; + } + return output + plus_1(input - 1, output) + plus_1(input - 2, output); + } + + private int plus_2(int input, int output) { + while(true) { + if (input == 0 || input == 1) { + return input; + } + return output + plus_2(input - 1, output) + plus_2(input - 2, output); + } + } +} diff --git a/src/main/java/week1/problem2/README.md b/src/main/java/week1/problem2/README.md new file mode 100644 index 0000000..dae19ac --- /dev/null +++ b/src/main/java/week1/problem2/README.md @@ -0,0 +1,33 @@ +# 자료구조와 알고리즘 1주차 과제 - 피보나치 수 + +피보나치 수는 첫째 및 둘째 항이 1이며 그 뒤의 모든 항은 바로 앞 두 항의 합인 +수열입니다. +n번째 피보나치 수를 구하는 함수를 작성해 주세요. + +## 요구 사항 + +1. 가장 익숙한 방법으로 문제를 해결해 주세요. +2. 이번에는 재귀 함수로 문제를 해결해 주세요. +3. 꼬리 재귀 함수로 바꿔보세요. +4. 꼬리 재귀 최적화를 통해서 최적화해 보세요. + +### 입력 예시 + +| n | return | +| --- | --- | +| 0 | 0| +| 1 | 1 | +| 2 | 1 | +| 3 | 2 | +| 4 | 3 | +| 5 | 5 | +| 6 | 8 | + +## 제한조건 + +- 모든 테스트를 통과해야 합니다. +- 스스로 문제 해결법을 떠올리기 위해 Copilot은 사용하지 말아주세요. + +## 참고 + +- [피보나치 수](https://ko.wikipedia.org/wiki/%ED%94%BC%EB%B3%B4%EB%82%98%EC%B9%98_%EC%88%98) diff --git a/src/main/java/week1/problem3/Problem3.java b/src/main/java/week1/problem3/Problem3.java new file mode 100644 index 0000000..63febd0 --- /dev/null +++ b/src/main/java/week1/problem3/Problem3.java @@ -0,0 +1,25 @@ +package main.java.week1.problem3; + +import java.util.ArrayDeque; + +public class Problem3 { + + public Problem3() { + } + + public String solution1(int input) { + if (input == 0) { + return "0"; + } + ArrayDeque stack = new ArrayDeque<>(); + while (input > 0) { + stack.push(input % 2); + input /= 2; + } + StringBuilder stringBuilder = new StringBuilder(); + while (!stack.isEmpty()) { + stringBuilder.append(stack.pop()); + } + return stringBuilder.toString(); + } +} diff --git a/src/main/java/week1/problem3/README.md b/src/main/java/week1/problem3/README.md new file mode 100644 index 0000000..2bbafbf --- /dev/null +++ b/src/main/java/week1/problem3/README.md @@ -0,0 +1,33 @@ +# 자료구조와 알고리즘 1주차 과제 - 이진수로 변환하기 + +주어진 10진수 숫자를 2진수 문자열로 변환하는 함수를 작성해 주세요. + +## 요구 사항 + +1. 가장 익숙한 방법으로 문제를 해결해 주세요. +2. 이번에는 재귀 함수로 문제를 해결해 주세요. +3. 꼬리 재귀 함수로 바꿔보세요. +4. 꼬리 재귀 최적화를 통해서 최적화해 보세요. + +### 입력 예시 + +| n | return | +| --- | --- | +| 0 | "0" | +| 1 | "1" | +| 2 | "10" | +| 3 | "11" | +| 4 | "100" | +| 5 | "101" | +| 6 | "110" | +| 7 | "111" | +| 8 | "1000" | + +## 제한조건 + +- 모든 테스트를 통과해야 합니다. +- 스스로 문제 해결법을 떠올리기 위해 Copilot은 사용하지 말아주세요. + +## 참고 + +- [이진법](https://ko.wikipedia.org/wiki/%EC%9D%B4%EC%A7%84%EB%B2%95) diff --git a/src/main/java/week1/problem4/Problem4.java b/src/main/java/week1/problem4/Problem4.java new file mode 100644 index 0000000..a26ba5f --- /dev/null +++ b/src/main/java/week1/problem4/Problem4.java @@ -0,0 +1,16 @@ +package main.java.week1.problem4; + +public class Problem4 { + + public Problem4() { + } + + public int solution1(String input) { + int output = 0; + String[] split = input.split(""); + for (int i = 0; i < split.length; i++) { + output += Integer.parseInt(split[i]) * Math.pow(2, split.length - i - 1); + } + return output; + } +} diff --git a/src/main/java/week1/problem4/README.md b/src/main/java/week1/problem4/README.md new file mode 100644 index 0000000..2bd5ac5 --- /dev/null +++ b/src/main/java/week1/problem4/README.md @@ -0,0 +1,33 @@ +w# 자료구조와 알고리즘 1주차 과제 - 이진수 10진수로 변환하기 + +주어진 2진수 문자열을 10진수 숫자로 변환하는 함수를 작성해 주세요. + +## 요구 사항 + +1. 가장 익숙한 방법으로 문제를 해결해 주세요. +2. 이번에는 재귀 함수로 문제를 해결해 주세요. +3. 꼬리 재귀 함수로 바꿔보세요. +4. 꼬리 재귀 최적화를 통해서 최적화해 보세요. + +### 입력 예시 + +| binaryCharacters | return | +| --- | --- | +| "0" | 0 | +| "1" | 1 | +| "10" | 2 | +| "11" | 3 | +| "100" | 4 | +| "101" | 5 | +| "110" | 6 | +| "111" | 7 | +| "1000" | 8 | + +## 제한조건 + +- 모든 테스트를 통과해야 합니다. +- 스스로 문제 해결법을 떠올리기 위해 Copilot은 사용하지 말아주세요. + +## 참고 + +- [이진법](https://ko.wikipedia.org/wiki/%EC%9D%B4%EC%A7%84%EB%B2%95) diff --git a/src/main/java/week1/problem5/Problem5.java b/src/main/java/week1/problem5/Problem5.java new file mode 100644 index 0000000..c97c713 --- /dev/null +++ b/src/main/java/week1/problem5/Problem5.java @@ -0,0 +1,17 @@ +package main.java.week1.problem5; + +public class Problem5 { + + public Problem5() { + } + + public int solution1(int a, int b) { + int max = Math.max(a, b); + int min = Math.min(a, b); + int r = max % min; + if (r == 0) { + return min; + } + return solution1(min, r); + } +} diff --git a/src/main/java/week1/problem5/README.md b/src/main/java/week1/problem5/README.md new file mode 100644 index 0000000..3160adf --- /dev/null +++ b/src/main/java/week1/problem5/README.md @@ -0,0 +1,33 @@ +최# 자료구조와 알고리즘 1주차 과제 - 유클리드 호제법으로 최대 공약수 구하기 + +> 2개의 자연수(또는 정식) a, b에 대해서 a를 b로 나눈 나머지를 r이라 하면(단, a>b), +> a와 b의 최대공약수는 b와 r의 최대공약수와 같다. 이 성질에 따라, b를 r로 나눈 +> 나머지 r'를 구하고, 다시 r을 r'로 나눈 나머지를 구하는 과정을 반복하여 나머지가 +> 0이 되었을 때 나누는 수가 a와 b의 최대공약수이다. + +위 정의에 따라 유클리드 호제법을 이용해서 최대 공약수를 구하는 함수를 작성해 주세요. + +## 요구 사항 + +1. 가장 익숙한 방법으로 문제를 해결해 주세요. +2. 이번에는 재귀 함수로 문제를 해결해 주세요. +3. 꼬리 재귀 함수로 바꿔보세요. +4. 꼬리 재귀 최적화를 통해서 최적화해 보세요. + +### 입력 예시 + +| a | b | return | +| --- | --- | --- | +| 4 | 12 | 4 | +| 3 | 7 | 1 | +| 16 | 72 | 8 | +| 9 | 12 | 3 | + +## 제한조건 + +- 모든 테스트를 통과해야 합니다. +- 스스로 문제 해결법을 떠올리기 위해 Copilot은 사용하지 말아주세요. + +## 참고 + +- [유클리드 호제법](https://ko.wikipedia.org/wiki/%EC%9C%A0%ED%81%B4%EB%A6%AC%EB%93%9C_%ED%98%B8%EC%A0%9C%EB%B2%95) diff --git a/src/test/java/week1/problem1/Problem1Test.java b/src/test/java/week1/problem1/Problem1Test.java new file mode 100644 index 0000000..a5438c0 --- /dev/null +++ b/src/test/java/week1/problem1/Problem1Test.java @@ -0,0 +1,66 @@ +package test.java.week1.problem1; + +import main.java.week1.problem1.Problem1; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class Problem1Test { + + private final Problem1 problem1 = new Problem1(); + private final int[] input1 = {1, 2, 3, 4}; + private final int[] input2 = {-1, 3, 8, 9, 10, 11}; + private final int[] input3 = {}; + private final int output1 = 10; + private final int output2 = 40; + private final int output3 = 0; + + @Test + void 숫자의_배열을_받아서_총합을_구한다_가장_익숙한_방법() { + Assertions.assertAll( + "총합 계산(for문)", + () -> Assertions.assertEquals(output1, problem1.solution1(input1)), + () -> Assertions.assertEquals(output2, problem1.solution1(input2)), + () -> Assertions.assertEquals(output3, problem1.solution1(input3)) + ); + } + + @Test + void 숫자의_배열을_받아서_총합을_구한다_재귀_분할_정복() { + Assertions.assertAll( + "총합 계산(재귀+분할 정복)", + () -> Assertions.assertEquals(output1, problem1.solution2_1(input1)), + () -> Assertions.assertEquals(output2, problem1.solution2_1(input2)), + () -> Assertions.assertEquals(output3, problem1.solution2_1(input3)) + ); + } + + @Test + void 숫자의_배열을_받아서_총합을_구한다_재귀_인덱스() { + Assertions.assertAll( + "총합 계산(재귀+인덱스)", + () -> Assertions.assertEquals(output1, problem1.solution2_2(input1)), + () -> Assertions.assertEquals(output2, problem1.solution2_2(input2)), + () -> Assertions.assertEquals(output3, problem1.solution2_2(input3)) + ); + } + + @Test + void 숫자의_배열을_받아서_총합을_구한다_꼬리_재귀() { + Assertions.assertAll( + "총합 계산(꼬리 재귀)", + () -> Assertions.assertEquals(output1, problem1.solution3(input1)), + () -> Assertions.assertEquals(output2, problem1.solution3(input2)), + () -> Assertions.assertEquals(output3, problem1.solution3(input3)) + ); + } + + @Test + void 숫자의_배열을_받아서_총합을_구한다_꼬리_재귀_최적화() { + Assertions.assertAll( + "총합 계산(꼬리 재귀 최적화)", + () -> Assertions.assertEquals(output1, problem1.solution4(input1)), + () -> Assertions.assertEquals(output2, problem1.solution4(input2)), + () -> Assertions.assertEquals(output3, problem1.solution4(input3)) + ); + } +} diff --git a/src/test/java/week1/problem2/Problem2Test.java b/src/test/java/week1/problem2/Problem2Test.java new file mode 100644 index 0000000..b48af27 --- /dev/null +++ b/src/test/java/week1/problem2/Problem2Test.java @@ -0,0 +1,35 @@ +package test.java.week1.problem2; + +import main.java.week1.problem2.Problem2; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +class Problem2Test { + + private final Problem2 problem2 = new Problem2(); + + @ParameterizedTest + @CsvSource(value = {"0:0", "1:1", "2:1", "3:2", "4:3", "5:5", "6:8"}, delimiter = ':') + void 피보나치_수를_구한다_상향식_동적_프로그래밍(int input, int output) { + Assertions.assertEquals(output, problem2.solution1(input)); + } + + @ParameterizedTest + @CsvSource(value = {"0:0", "1:1", "2:1", "3:2", "4:3", "5:5", "6:8"}, delimiter = ':') + void 피보나치_수를_구한다_재귀(int input, int output) { + Assertions.assertEquals(output, problem2.solution2(input)); + } + + @ParameterizedTest + @CsvSource(value = {"0:0", "1:1", "2:1", "3:2", "4:3", "5:5", "6:8"}, delimiter = ':') + void 피보나치_수를_구한다_꼬리_재귀(int input, int output) { + Assertions.assertEquals(output, problem2.solution3(input)); + } + + @ParameterizedTest + @CsvSource(value = {"0:0", "1:1", "2:1", "3:2", "4:3", "5:5", "6:8"}, delimiter = ':') + void 피보나치_수를_구한다_꼬리_재귀_최적화(int input, int output) { + Assertions.assertEquals(output, problem2.solution4(input)); + } +} \ No newline at end of file diff --git a/src/test/java/week1/problem3/Problem3Test.java b/src/test/java/week1/problem3/Problem3Test.java new file mode 100644 index 0000000..f7b20b6 --- /dev/null +++ b/src/test/java/week1/problem3/Problem3Test.java @@ -0,0 +1,17 @@ +package test.java.week1.problem3; + +import main.java.week1.problem3.Problem3; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +class Problem3Test { + + Problem3 problem3 = new Problem3(); + + @ParameterizedTest + @CsvSource(value = {"0:0", "1:1", "2:10", "3:11", "4:100", "5:101", "6:110", "7:111", "8:1000"}, delimiter = ':') + void 십진수를_이진수로_만든다_나머지_몫_정리(int input, String output) { + Assertions.assertEquals(output, problem3.solution1(input)); + } +} diff --git a/src/test/java/week1/problem4/Problem4Test.java b/src/test/java/week1/problem4/Problem4Test.java new file mode 100644 index 0000000..8282d63 --- /dev/null +++ b/src/test/java/week1/problem4/Problem4Test.java @@ -0,0 +1,17 @@ +package test.java.week1.problem4; + +import main.java.week1.problem4.Problem4; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +class Problem4Test { + + private Problem4 problem4 = new Problem4(); + + @ParameterizedTest + @CsvSource(value = {"0:0", "1:1", "10:2", "11:3", "100:4", "101:5", "110:6", "111:7", "1000:8"}, delimiter = ':') + void solution(String input, int output) { + Assertions.assertEquals(output, problem4.solution1(input)); + } +} \ No newline at end of file diff --git a/src/test/java/week1/problem5/Problem5Test.java b/src/test/java/week1/problem5/Problem5Test.java new file mode 100644 index 0000000..8d9bab2 --- /dev/null +++ b/src/test/java/week1/problem5/Problem5Test.java @@ -0,0 +1,17 @@ +package test.java.week1.problem5; + +import main.java.week1.problem5.Problem5; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +class Problem5Test { + + private Problem5 problem5 = new Problem5(); + + @ParameterizedTest + @CsvSource(value = {"4:12:4", "3:7:1", "16:72:8", "9:12:3"}, delimiter = ':') + void 유클리드_호제법을_사용하여_최대_공약수를_구한다_재귀(int a, int b, int output) { + Assertions.assertEquals(output, problem5.solution1(a, b)); + } +}