solve: [W02] SWEA 26070, 26071, 5656, 5658 - #10
Conversation
- [SWEA 26070] 보석 수집 로봇 - [SWEA 5566] 벽돌 깨기 - [SWEA 5658] 보물상자 비밀번호 - [SWEA 26071] 블록 제거 게임
📝 WalkthroughWalkthrough네 개의 SWEA 문제 풀이 문서와 Python 구현을 추가했다. 0-1 BFS, 구간 DP, BFS·백트래킹 시뮬레이션, 덱 기반 16진수 조합 탐색을 각각 사용하며 테스트 입력 처리와 복잡도 설명을 포함한다. Changes보석 수집 로봇
블록 제거 게임
벽돌 깨기
보물상자 비밀번호
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 9
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@studies/week-02/yeseolee/26071-블록` 제거 게임.md:
- Around line 115-128: Update the explanation for solution to explicitly state
that permutations(range(1, n - 1), n - 2) explores (N-2)! orders and get_score
can take O(N²) per order, yielding worst-case O((N-2)!·N²) per test case and
causing TLE as input size grows. Replace the vague “exponential growth”
description with this concrete complexity analysis.
- Around line 115-125: 비교용 코드에서 solution이 사용하는 permutations를 정의된 이름으로 만들 수 있도록
itertools의 permutations를 import하세요. solution과 get_score의 기존 로직은 변경하지 말고, 해당 코드
블록의 import 영역에 추가하세요.
- Around line 20-26: 시간 복잡도 설명에 현재 O(N³) 분석이 단일 테스트 케이스 기준임을 명시하고, T개 테스트 케이스를
모두 처리하는 전체 복잡도를 O(T·N³) 또는 O(ΣN_t³)로 추가해 주세요.
In `@studies/week-02/yeseolee/5566-벽돌` 깨기.md:
- Line 124: Update the Markdown immediately after the “### 🧠 회고 (선택)” heading
to include a blank line before the following content, satisfying Markdownlint
MD022.
- Line 1: 문서의 문제 번호를 5566에서 5656으로 통일하세요. 파일명을 5656-벽돌 깨기.md로 변경하고, 문서 제목과 내부
링크에 남아 있는 5566 표기도 5656으로 수정하세요.
- Around line 21-24: 복잡도 설명을 실제 _blast의 반복 구조에 맞게 수정하세요. 방문한 벽돌마다 반경에 비례해 최대 4 *
(R - 1)개 위치를 검사하므로, R을 최대 벽돌 값으로 정의하고 전체 시간 복잡도를 O(W^N * W * H * R)로 명시하세요. R이
문제 제약상 상수인 경우에만 기존 표현으로 단순화할 수 있음을 덧붙이고, “모든 칸을 한 번씩 순회”한다는 설명은 제거하거나 정확히 수정하세요.
- Around line 96-107: Update _backtracking’s column iteration to track empty
columns with a has_empty_column flag and invoke _backtracking(tries - 1, cnt)
only once when at least one column is empty; keep non-empty column branching and
board restoration unchanged.
In `@studies/week-02/yeseolee/5658-보물상자` 비밀번호.md:
- Around line 44-51: Update the convert function to use Python’s built-in int
conversion with base 16 instead of manually iterating and calculating
hexadecimal digits, and rename its str parameter to avoid shadowing the built-in
type.
- Around line 59-63: 각 회전에서 deque를 네 번 리스트로 변환하지 않도록 `for _ in range(n // 4)`
루프의 시작 시점에 `que`를 한 번만 리스트로 스냅샷하고, 네 구간 계산이 동일한 스냅샷을 재사용하게 수정하세요. `convert`, 회전
처리, `hubo` 수집 및 최종 정렬 동작은 그대로 유지하세요.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 442a195c-0b3d-4806-bdae-43324fa9cd72
📒 Files selected for processing (4)
studies/week-02/yeseolee/26070-보석 수집 로봇.mdstudies/week-02/yeseolee/26071-블록 제거 게임.mdstudies/week-02/yeseolee/5566-벽돌 깨기.mdstudies/week-02/yeseolee/5658-보물상자 비밀번호.md
| ## 2. 시간 복잡도 | ||
|
|
||
| **O(N³)** — | ||
|
|
||
| * DP 테이블의 상태(State) 개수는 `i`부터 `j`까지의 조합이므로 O(N²) | ||
| * 각 상태 `dp[i][j]`를 계산할 때, 분할점 `mid`를 `i`부터 `j`까지 순회하며 최댓값을 찾으므로 O(N)의 시간이 추가로 소요 | ||
| * 따라서 총 O(N²) * O(N) = O(N³) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
전체 입력 기준 복잡도도 명시해 주세요.
현재 O(N³) 계산은 테스트 케이스 1개 기준으로는 맞습니다. 다만 실제 코드는 T개 테스트 케이스를 순회하므로 전체 시간 복잡도는 O(T·N³)(또는 O(ΣN_t³))입니다. 문서에 “테스트 케이스 1개 기준”이라고 명시해 주세요.
수정 예시
-**O(N³)** —
+**테스트 케이스 1개 기준 O(N³), 전체 입력 기준 O(T·N³)** —📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ## 2. 시간 복잡도 | |
| **O(N³)** — | |
| * DP 테이블의 상태(State) 개수는 `i`부터 `j`까지의 조합이므로 O(N²) | |
| * 각 상태 `dp[i][j]`를 계산할 때, 분할점 `mid`를 `i`부터 `j`까지 순회하며 최댓값을 찾으므로 O(N)의 시간이 추가로 소요 | |
| * 따라서 총 O(N²) * O(N) = O(N³) | |
| ## 2. 시간 복잡도 | |
| **테스트 케이스 1개 기준 O(N³), 전체 입력 기준 O(T·N³)** — | |
| * DP 테이블의 상태(State) 개수는 `i`부터 `j`까지의 조합이므로 O(N²) | |
| * 각 상태 `dp[i][j]`를 계산할 때, 분할점 `mid`를 `i`부터 `j`까지 순회하며 최댓값을 찾으므로 O(N)의 시간이 추가로 소요 | |
| * 따라서 총 O(N²) * O(N) = O(N³) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@studies/week-02/yeseolee/26071-블록` 제거 게임.md around lines 20 - 26, 시간 복잡도 설명에
현재 O(N³) 분석이 단일 테스트 케이스 기준임을 명시하고, T개 테스트 케이스를 모두 처리하는 전체 복잡도를 O(T·N³) 또는
O(ΣN_t³)로 추가해 주세요.
Source: Path instructions
| def solution(n, arr): | ||
| if n == 1: | ||
| return arr[0] | ||
| if n == 2: | ||
| return max(arr) * 2 | ||
|
|
||
| max_score = 0 | ||
| ps = permutations(range(1,n-1), n-2) | ||
|
|
||
| for p in ps: | ||
| score = get_score(n,arr[::],p) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
비교용 코드에 permutations import를 추가해 주세요.
현재 코드 블록에는 from itertools import permutations가 없어 그대로 실행하면 NameError가 발생합니다.
수정 예시
+from itertools import permutations
+
def solution(n, arr):📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def solution(n, arr): | |
| if n == 1: | |
| return arr[0] | |
| if n == 2: | |
| return max(arr) * 2 | |
| max_score = 0 | |
| ps = permutations(range(1,n-1), n-2) | |
| for p in ps: | |
| score = get_score(n,arr[::],p) | |
| from itertools import permutations | |
| def solution(n, arr): | |
| if n == 1: | |
| return arr[0] | |
| if n == 2: | |
| return max(arr) * 2 | |
| max_score = 0 | |
| ps = permutations(range(1,n-1), n-2) | |
| for p in ps: | |
| score = get_score(n,arr[::],p) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@studies/week-02/yeseolee/26071-블록` 제거 게임.md around lines 115 - 125, 비교용 코드에서
solution이 사용하는 permutations를 정의된 이름으로 만들 수 있도록 itertools의 permutations를
import하세요. solution과 get_score의 기존 로직은 변경하지 말고, 해당 코드 블록의 import 영역에 추가하세요.
| def solution(n, arr): | ||
| if n == 1: | ||
| return arr[0] | ||
| if n == 2: | ||
| return max(arr) * 2 | ||
|
|
||
| max_score = 0 | ||
| ps = permutations(range(1,n-1), n-2) | ||
|
|
||
| for p in ps: | ||
| score = get_score(n,arr[::],p) | ||
| max_score = max(max_score,score) | ||
|
|
||
| return max_score |
There was a problem hiding this comment.
🚀 Performance & Scalability | 🟡 Minor | ⚡ Quick win
순열 구현의 실제 복잡도와 TLE 위험을 구체적으로 기록해 주세요.
permutations(range(1, n - 1), n - 2)는 (N-2)!개의 순서를 탐색하고, 각 순서의 get_score도 최악 O(N²)까지 걸릴 수 있습니다. 따라서 테스트 케이스당 최악 복잡도는 O((N-2)!·N²) 수준이며, 입력이 조금만 커져도 시간 초과가 발생합니다. 현재의 “기하급수적으로 증가”라는 설명을 이 근거로 보완해 주세요.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@studies/week-02/yeseolee/26071-블록` 제거 게임.md around lines 115 - 128, Update
the explanation for solution to explicitly state that permutations(range(1, n -
1), n - 2) explores (N-2)! orders and get_score can take O(N²) per order,
yielding worst-case O((N-2)!·N²) per test case and causing TLE as input size
grows. Replace the vague “exponential growth” description with this concrete
complexity analysis.
Source: Path instructions
| @@ -0,0 +1,125 @@ | |||
| # [SWEA 5566] 벽돌 깨기 | |||
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
문제 번호를 5656으로 통일해 주세요.
PR 목표와 파일 경로는 SWEA 5656인데 제목과 파일명은 5566으로 되어 있습니다. 파일을 studies/week-02/yeseolee/5656-벽돌 깨기.md로 변경하고 제목·링크도 함께 확인해 주세요. SWEA 자료에서도 5656은 벽돌 깨기 문제로 식별됩니다. (swexpertacademy.com)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@studies/week-02/yeseolee/5566-벽돌` 깨기.md at line 1, 문서의 문제 번호를 5566에서 5656으로
통일하세요. 파일명을 5656-벽돌 깨기.md로 변경하고, 문서 제목과 내부 링크에 남아 있는 5566 표기도 5656으로 수정하세요.
| **O(W^N * W * H)** — | ||
|
|
||
| * 구슬을 떨어뜨릴 열을 선택하는 경우의 수는 최대 **W^N** | ||
| * 매 경우마다 연쇄 폭발을 처리하는 BFS와 중력 작용 함수가 실행되며, 이는 보드의 모든 칸을 한 번씩 순회하므로 **O(W * H)** |
There was a problem hiding this comment.
🚀 Performance & Scalability | 🟡 Minor | ⚡ Quick win
BFS 비용을 복잡도에 반영해 주세요.
_blast는 방문한 벽돌마다 4 * (radius - 1)개 위치를 검사하므로, R = 최대 벽돌 값으로 두면 전체 복잡도는 O(W^N * W * H * R)입니다. R이 문제 제약상 상수일 때만 현재의 O(W^N * W * H)로 단순화할 수 있으며, “모든 칸을 한 번씩 순회”한다는 설명은 정확하지 않습니다.
경로 지침의 시간 복잡도 검증 요구에 따라 실제 반복문 기준으로 계산했습니다.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@studies/week-02/yeseolee/5566-벽돌` 깨기.md around lines 21 - 24, 복잡도 설명을 실제
_blast의 반복 구조에 맞게 수정하세요. 방문한 벽돌마다 반경에 비례해 최대 4 * (R - 1)개 위치를 검사하므로, R을 최대 벽돌
값으로 정의하고 전체 시간 복잡도를 O(W^N * W * H * R)로 명시하세요. R이 문제 제약상 상수인 경우에만 기존 표현으로 단순화할 수
있음을 덧붙이고, “모든 칸을 한 번씩 순회”한다는 설명은 제거하거나 정확히 수정하세요.
Source: Path instructions
| for x in range(w): | ||
| for y in range(h - 1, -1, -1): | ||
| if board[x][y] != 0: | ||
| prev_board = [row[:] for row in board] | ||
| cur_cnt = _blast(x, y) | ||
| _gravity() | ||
| _backtracking(tries - 1, cnt + cur_cnt) | ||
| board = prev_board | ||
| break | ||
| else: | ||
| # 허공 | ||
| _backtracking(tries - 1, cnt) |
There was a problem hiding this comment.
🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win
빈 열 재귀 호출을 한 번으로 합쳐 주세요.
빈 열마다 보드 상태가 전혀 바뀌지 않은 동일한 _backtracking(tries - 1, cnt)를 호출합니다. 빈 열이 여러 개면 동일한 탐색을 중복 수행하므로, has_empty_column 플래그로 빈 열 분기를 한 번만 실행하면 됩니다.
개선 예시
+ has_empty_column = False
for x in range(w):
for y in range(h - 1, -1, -1):
if board[x][y] != 0:
...
board = prev_board
break
else:
- # 허공
- _backtracking(tries - 1, cnt)
+ has_empty_column = True
+
+ if has_empty_column:
+ _backtracking(tries - 1, cnt)경로 지침의 SWEA 시간 제한 및 비효율 탐색 점검 요구를 적용했습니다.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| for x in range(w): | |
| for y in range(h - 1, -1, -1): | |
| if board[x][y] != 0: | |
| prev_board = [row[:] for row in board] | |
| cur_cnt = _blast(x, y) | |
| _gravity() | |
| _backtracking(tries - 1, cnt + cur_cnt) | |
| board = prev_board | |
| break | |
| else: | |
| # 허공 | |
| _backtracking(tries - 1, cnt) | |
| has_empty_column = False | |
| for x in range(w): | |
| for y in range(h - 1, -1, -1): | |
| if board[x][y] != 0: | |
| prev_board = [row[:] for row in board] | |
| cur_cnt = _blast(x, y) | |
| _gravity() | |
| _backtracking(tries - 1, cnt + cur_cnt) | |
| board = prev_board | |
| break | |
| else: | |
| has_empty_column = True | |
| if has_empty_column: | |
| _backtracking(tries - 1, cnt) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@studies/week-02/yeseolee/5566-벽돌` 깨기.md around lines 96 - 107, Update
_backtracking’s column iteration to track empty columns with a has_empty_column
flag and invoke _backtracking(tries - 1, cnt) only once when at least one column
is empty; keep non-empty column branching and board restoration unchanged.
Source: Path instructions
|
|
||
| --- | ||
|
|
||
| ### 🧠 회고 (선택) |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Heading 뒤에 빈 줄을 추가해 주세요.
Markdownlint MD022 경고가 발생하므로 ### 🧠 회고 (선택) 다음에 빈 줄을 추가해야 합니다.
🧰 Tools
🪛 markdownlint-cli2 (0.23.1)
[warning] 124-124: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@studies/week-02/yeseolee/5566-벽돌` 깨기.md at line 124, Update the Markdown
immediately after the “### 🧠 회고 (선택)” heading to include a blank line before
the following content, satisfying Markdownlint MD022.
Source: Linters/SAST tools
| def convert(str): | ||
| result = 0 | ||
| n = 1 | ||
| for ch in str[::-1]: | ||
| num = 10 + ord(ch) - ord("A") if (ord("A") <= ord(ch) <= ord("F")) else int(ch) | ||
| result += num * n | ||
| n *= 16 | ||
| return result |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
16진수 변환은 표준 내장 함수로 단순화하세요.
현재 구현은 입력 범위에서 동작하지만, 수동 변환 로직과 str 내장 타입명 가림이 불필요합니다. int(hex_string, 16)을 사용하면 코드가 짧아지고 변환 로직의 유지보수 위험도 줄어듭니다.
♻️ 제안 코드
-def convert(str):
- result = 0
- n = 1
- for ch in str[::-1]:
- num = 10 + ord(ch) - ord("A") if (ord("A") <= ord(ch) <= ord("F")) else int(ch)
- result += num * n
- n *= 16
- return result
+def convert(hex_string):
+ return int(hex_string, 16)경로 지침의 관용적 구현 및 가독성 개선 요구에 따라 제안합니다.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def convert(str): | |
| result = 0 | |
| n = 1 | |
| for ch in str[::-1]: | |
| num = 10 + ord(ch) - ord("A") if (ord("A") <= ord(ch) <= ord("F")) else int(ch) | |
| result += num * n | |
| n *= 16 | |
| return result | |
| def convert(hex_string): | |
| return int(hex_string, 16) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@studies/week-02/yeseolee/5658-보물상자` 비밀번호.md around lines 44 - 51, Update the
convert function to use Python’s built-in int conversion with base 16 instead of
manually iterating and calculating hexadecimal digits, and rename its str
parameter to avoid shadowing the built-in type.
Source: Path instructions
| for _ in range(n // 4): | ||
| for i in range(4): | ||
| hubo.add(convert("".join(list(que)[(n // 4) * i : (n // 4) * (i + 1)]))) | ||
| que.append(que.popleft()) | ||
| return sorted(list(hubo), reverse=True)[k - 1] |
There was a problem hiding this comment.
🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win
회전마다 deque를 한 번만 리스트로 변환하세요.
현재 각 회전에서 list(que)를 네 번 생성합니다. 복잡도 자체는 정렬 비용 O(N log N)까지 포함해도 전체 O(N²)로 문서 설명이 맞지만, 스냅샷을 한 번만 만들면 불필요한 변환을 줄일 수 있습니다.
⚡ 제안 코드
+ side = n // 4
for _ in range(n // 4):
+ rotated = list(que)
for i in range(4):
- hubo.add(convert("".join(list(que)[(n // 4) * i : (n // 4) * (i + 1)])))
+ start = side * i
+ hubo.add(convert("".join(rotated[start : start + side])))
que.append(que.popleft())
- return sorted(list(hubo), reverse=True)[k - 1]
+ return sorted(hubo, reverse=True)[k - 1]경로 지침의 SWEA 시간 제한 관점에서 반복 변환을 줄이는 대안입니다.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| for _ in range(n // 4): | |
| for i in range(4): | |
| hubo.add(convert("".join(list(que)[(n // 4) * i : (n // 4) * (i + 1)]))) | |
| que.append(que.popleft()) | |
| return sorted(list(hubo), reverse=True)[k - 1] | |
| side = n // 4 | |
| for _ in range(n // 4): | |
| rotated = list(que) | |
| for i in range(4): | |
| start = side * i | |
| hubo.add(convert("".join(rotated[start : start + side]))) | |
| que.append(que.popleft()) | |
| return sorted(hubo, reverse=True)[k - 1] |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@studies/week-02/yeseolee/5658-보물상자` 비밀번호.md around lines 59 - 63, 각 회전에서
deque를 네 번 리스트로 변환하지 않도록 `for _ in range(n // 4)` 루프의 시작 시점에 `que`를 한 번만 리스트로
스냅샷하고, 네 구간 계산이 동일한 스냅샷을 재사용하게 수정하세요. `convert`, 회전 처리, `hubo` 수집 및 최종 정렬 동작은
그대로 유지하세요.
Source: Path instructions
📌 이번 PR 내용
✅ 푼 문제 (SWEA)
🧾 5요소 체크리스트
각 풀이에 아래 5요소를 모두 작성했는지 확인합니다.
📋 규칙 체크
studies/week-XX/<깃허브ID>/<문제번호>-<문제이름>.md)💬 리뷰어에게
혹시 디버깅에서 해맸던 파트가 있다면 함께 공유부탁드립니다.
🧠 이번 주 회고 (한 줄)
DP에 약하다는 것을 깨달았습니다. 추가로 좀 풀어봐야 할듯합니다.