diff --git a/README.md b/README.md index 8569700..b91ccec 100644 --- a/README.md +++ b/README.md @@ -8,15 +8,13 @@ ![매번 귀찮게 복붙하지 마세요](documentation/assets/3.png) ![그냥 실행만 하세요](documentation/assets/4.png) -## 어떻게 작동하나요? +## 어떻게 쓰면 되나요? -프로그램을 사용하려면 먼저 문제 번호를 입력하세요. -그러면 입력하신 번호로 디렉터리가 생성되며, 그 안에 `Main.java`와 `TestHelper.java` 파일이 자동으로 만들어집니다. 그 후에는 인텔리제이가 실행됩니다. - -`Main.java` 파일 내의 main 함수에서 알고리즘을 구현하고, 작성한 코드를 테스트하려면 `TestHelper.java`를 실행하면 됩니다. -그러면 문제 내 모든 테스트 케이스가 자동으로 수행됩니다. - -문제를 다 풀었으면, 백준에 `Main.java`를 복사하여 제출하면 됩니다. +0. **프로그램 실행** +1. **문제 번호 입력:** 시작하기 위해 문제 번호를 입력하세요. +2. **자동 설정:** 입력한 번호로 디렉터리가 생성되며, Main.java와 TestHelper.java 파일이 자동으로 준비됩니다. 이후 인텔리제이가 실행됩니다. +3. **코딩 및 테스트:** Main.java에서 알고리즘을 구현하고, TestHelper.java를 실행하여 코드를 테스트하세요. 모든 테스트 케이스가 자동으로 실행됩니다. +4. **제출:** 문제 해결이 완료되면, Main.java의 내용을 백준에 제출합니다. ## 요구 환경 @@ -28,7 +26,7 @@ ## 설치 및 사용 방법 1. [최신 릴리즈] 에서 `Baekjoon-java-starter.zip` 파일을 다운로드합니다. -2. **압축을 풀고,** 다음 명령어를 실행합니다. +2. **압축을 풀고,** 아래 명령어를 실행합니다. ```bash java -jar Baekjoon-java-starter.jar @@ -36,7 +34,7 @@ 3. 이제 백준 문제 번호를 입력하면 됩니다. -만일 기본으로 생성되는 `Main.java`의 템플릿이 마음에 들지 않는다면, [코드 템플릿 변경하기]을 참고해주세요. +기본으로 생성되는 Main.java 템플릿을 변경하고 싶다면, [코드 템플릿 변경하기]을 참조해주세요. **그 외 자세한 내용은 [사용 가이드]를 참고해주세요.** [코드 템플릿 변경하기]: documentation/DOCUMENTATION.md#생성되는-mainjava-파일의-템플릿-변경하기 @@ -49,14 +47,12 @@ ## 기여하기 -해당 프로젝트에 올라오는 이슈와 풀 리퀘스트는 언제나 환영합니다. -자세한건 [기여 가이드라인]을 참고해주세요. -미리 감사드립니다. +이 프로젝트에 대한 이슈와 풀 리퀘스트는 언제나 환영합니다. [기여 가이드라인]을 확인해 주세요. 감사합니다! [기여 가이드라인]: documentation/CONTRIBUTING.md ## 라이센스 -해당 프로젝트는 MIT 라이센스를 따릅니다. +이 프로젝트는 MIT 라이센스를 따릅니다. [![MIT Licence](https://badges.frapsoft.com/os/mit/mit.svg?v=103)](https://opensource.org/licenses/mit-license.php) diff --git a/documentation/DOCUMENTATION.md b/documentation/DOCUMENTATION.md index 4e09840..93c0de3 100644 --- a/documentation/DOCUMENTATION.md +++ b/documentation/DOCUMENTATION.md @@ -1,16 +1,22 @@ # 사용 가이드 +이 가이드는 프로그램 설정을 사용자 맞춤형으로 조정하는 방법을 설명합니다. + ## 설정 커스터 마이징 ### 개요 -프로그램을 실행하면, jar 파일이 있는 경로에 `config.json`이 생성됩니다. -이 파일을 수정하여 설정을 커스터마이징 할 수 있습니다. +프로그램 실행 시, `config.json` 파일이 jar 파일이 위치한 경로에 생성됩니다. 이 파일을 통해 다양한 설정을 커스터마이징할 수 있습니다. + +### 소스코드 폴더명 변경 + +**경로:** config.json > srcDirPrefix.value + +**설명:** 생성되는 소스코드 폴더의 접두사를 변경합니다. -### 생성되는 소스코드 폴더명 변경하기 +**기본값:** `p` -`config.json`의 `srcDirPrefix.value`을 수정하여, 생성되는 소스코드 폴더명의 `prefix`를 변경할 수 있습니다. -예시로 1000번 문제에서 `srcDirPrefix.value`을 `BOJ_`로 설정하면, `BOJ_1000` 폴더가 생성됩니다. 기본 설정 값은 `p`입니다. +**예시:** srcDirPrefix.value를 BOJ_로 설정하면, 1000번 문제에 대해 BOJ_1000 폴더가 생성됩니다. ```json { @@ -22,21 +28,13 @@ } ``` -### 생성되는 Main.java 파일의 템플릿 변경하기 +### Main.java 템플릿 변경 -`config.json`의 `mainCodeTemplate.value`을 수정하여, 생성되는 Main.java 파일의 템플릿을 변경할 수 있습니다. +**경로:** config.json > mainCodeTemplate.value -```json -{ - ... - "mainCodeTemplate": { - "value": "import java.util.Scanner;\n\n/*\n BAEKJOON {{number}} {{title}}\n https://www.acmicpc.net/problem/{{number}}\n*/\n\npublic class Main {\n\n public static void main(String[] args) {\n Scanner scanner = new Scanner(System.in);\n // 코드를 작성하세요.\n }\n}\n" - }, - ... -} -``` +**설명:** Main.java 파일 생성 시 사용되는 템플릿을 변경합니다. -기본 설정 값은 아래와 같습니다. +**기본 템플릿:** ```java import java.util.Scanner; @@ -55,18 +53,16 @@ public class Main { } ``` -#### 예약어 - -해당 기능에선 두가지 예약어를 지원합니다. +#### 예약어 사용 - `{{number}}`: 문제 번호 - `{{title}}`: 문제 제목 -해당 설정 값에 위 두가지 예약어를 사용하면, 각각 실제 값으로 치환됩니다. +#### 사용 팁 -#### 사용팁 +빠른 입출력이 필요한 경우, `BufferedReader`와 `BufferedWriter`를 사용하는 템플릿으로 수정할 수 있습니다. -만약 빠른 입출력을 위해 `BufferedReader`와 `BufferedWriter`를 사용하고 싶다면, 아래와 같이 템플릿을 수정하면 됩니다. +##### 예시 : ```java import java.io.BufferedReader; @@ -87,20 +83,19 @@ public class Main { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); // 코드를 작성하세요. - - bw.flush(); - bw.close(); - br.close(); } } ``` -### 생성되는 README.md 파일의 템플릿 변경하기 +### README.md 템플릿 변경 -`config.json`의 `markdownTemplate.value`을 수정하여, 생성되는 `README.md`의 파일 내용을 변경할 수 있습니다. -기본 설정 값은 아래와 같습니다. +**경로:** config.json > markdownTemplate.value -```markdown +**설명:** 생성되는 README.md 파일의 내용을 변경합니다. + +**기본 템플릿:** + +``` # {{title}} > 문제 번호 : {{number}}
@@ -113,24 +108,15 @@ public class Main { #### 예악어 -해당 기능에선 네가지 예약어를 지원합니다. - - `{{title}}`: 문제 제목 - `{{number}}`: 문제 번호 - `{{url}}`: 문제 출처 URL - `{{description}}`: 문제 설명 *(html 태그 포함)* -#### 비활성화 방법 +#### README 생성 비활성화 -`config.json`의 `enableReadme.value`를 `"true"` 대신 `"false"`로 수정하면, README.md 파일이 생성되지 않습니다. boolean -형태가 아닌 `"`로 감싸진 문자열로 입력해야 합니다. +**경로:** config.json > enableReadme.value -```json -{ - ... - "enableReadme": { - "value": "false" - }, - ... -} -``` +**설명:** README.md 파일 생성을 비활성화합니다. + +**비활성화 방법:** 값을 `false`로 설정합니다. 꼭 `"`로 감싸진 문자열로 입력해야 합니다. diff --git a/src/main/resources/code_sample/TestHelper.java b/src/main/resources/code_sample/TestHelper.java index 0e03134..570d4d9 100644 --- a/src/main/resources/code_sample/TestHelper.java +++ b/src/main/resources/code_sample/TestHelper.java @@ -1,17 +1,20 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.io.PrintStream; import java.lang.reflect.Field; import java.lang.reflect.Modifier; -import java.util.Collection; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; /** - * 이 테스트코드는 Baekjoon-java-starter 를 사용하여 + * 이 테스트 코드는 Baekjoon-java-starter를 사용하여 * 생성되었습니다. * - * @Author : PENEKhun + * @author PENEKhun */ public class TestHelper { @@ -67,11 +70,20 @@ public static void main(String[] args) { private static void captureInitialState() { try { Class clazz = Main.class; - Field[] fields = clazz.getDeclaredFields(); + var clonedClass = clazz.getConstructor().newInstance(); + Field[] fields = clonedClass.getClass().getDeclaredFields(); + System.out.println(Arrays.toString(fields)); + for (Field field : fields) { if (Modifier.isStatic(field.getModifiers())) { field.setAccessible(true); - initialStates.put(field, field.get(null)); + Object fieldValue = field.get(null); + try { + byte[] serializedField = SerializationUtils.serialize(fieldValue); + initialStates.put(field, serializedField); + } catch (IOException e) { + e.printStackTrace(); + } } } } catch (Exception e) { @@ -83,24 +95,22 @@ private static void resetToInitialState() { try { for (Map.Entry entry : initialStates.entrySet()) { Field field = entry.getKey(); - field.setAccessible(true); - Object value = entry.getValue(); - if (value instanceof Collection) { - ((Collection) value).clear(); - } else if (value instanceof Map) { - ((Map) value).clear(); - } else if (value instanceof StringBuilder) { - ((StringBuilder) value).setLength(0); - } else { - field.set(null, value); + byte[] serializedState = (byte[]) entry.getValue(); + try { + Object originalState = SerializationUtils.deserialize(serializedState); + field.setAccessible(true); + field.set(null, originalState); + } catch (IOException | ClassNotFoundException e) { + e.printStackTrace(); // Or handle more gracefully } } + } catch (IllegalAccessException e) { System.out.println(red("Main 클래스에 접근할 수 없습니다.")); } } - public static void printFail(int caseNumber, TestCase testCase, String message) { + private static void printFail(int caseNumber, TestCase testCase, String message) { System.out.printf(""" ====== %s ====== [입력 값] @@ -112,11 +122,11 @@ public static void printFail(int caseNumber, TestCase testCase, String message) System.out.println(message); } - public static String red(String message) { + private static String red(String message) { return "\u001B[31m%s\u001B[0m".formatted(message); } - public static class TestCase { + private static class TestCase { public String input; public String expectedOutput; @@ -126,4 +136,22 @@ public TestCase(String input, String expectedOutput) { this.expectedOutput = expectedOutput; } } + + public static class SerializationUtils { + + public static byte[] serialize(Object obj) throws IOException { + try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos)) { + oos.writeObject(obj); + return bos.toByteArray(); + } + } + + public static Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException { + try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes); + ObjectInputStream ois = new ObjectInputStream(bis)) { + return ois.readObject(); + } + } + } } \ No newline at end of file