Skip to content

Commit ac95991

Browse files
committed
solved(python): programmers
- 2025 프로그래머스 코드챌린지 1차 예선 / 홀짝트리
1 parent 1e231cf commit ac95991

File tree

4 files changed

+166
-0
lines changed

4 files changed

+166
-0
lines changed

programmers/2025_프로그래머스_코드챌린지_1차_예선/python/홀짝트리/__init__.py

Whitespace-only changes.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from collections import deque
2+
from typing import List, Dict, Set
3+
4+
5+
def solution(nodes: List[int], edges: List[List[int]]) -> List[int]:
6+
graph = {node: set() for node in nodes}
7+
for x, y in edges:
8+
graph[x].add(y)
9+
graph[y].add(x)
10+
11+
count, trees = [0, 0], find_trees(graph)
12+
for tree in trees:
13+
root_count, candidate = [0, 0], [None, None]
14+
15+
for node in tree:
16+
tree_type = 1 - int(node % 2 == len(graph[node]) % 2)
17+
root_count[tree_type] += 1
18+
candidate[tree_type] = node
19+
20+
if root_count[0] == 1:
21+
count[0] += 1
22+
if root_count[1] == 1:
23+
count[1] += 1
24+
25+
return count
26+
27+
28+
def find_trees(graph: Dict[int, Set[int]]) -> List[Set[int]]:
29+
trees, visited = [], set()
30+
for node in graph:
31+
if node in visited:
32+
continue
33+
34+
tree, queue = {node}, deque([node])
35+
while queue:
36+
node = queue.popleft()
37+
visited.add(node)
38+
39+
for child in graph[node]:
40+
if child not in visited:
41+
tree.add(child)
42+
queue.append(child)
43+
44+
trees.append(tree)
45+
46+
return trees
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
[
2+
{
3+
"params": [
4+
[
5+
11,
6+
9,
7+
3,
8+
2,
9+
4,
10+
6
11+
],
12+
[
13+
[
14+
9,
15+
11
16+
],
17+
[
18+
2,
19+
3
20+
],
21+
[
22+
6,
23+
3
24+
],
25+
[
26+
3,
27+
4
28+
]
29+
]
30+
],
31+
"expected": [
32+
1,
33+
0
34+
]
35+
},
36+
{
37+
"params": [
38+
[
39+
9,
40+
15,
41+
14,
42+
7,
43+
6,
44+
1,
45+
2,
46+
4,
47+
5,
48+
11,
49+
8,
50+
10
51+
],
52+
[
53+
[
54+
5,
55+
14
56+
],
57+
[
58+
1,
59+
4
60+
],
61+
[
62+
9,
63+
11
64+
],
65+
[
66+
2,
67+
15
68+
],
69+
[
70+
2,
71+
5
72+
],
73+
[
74+
9,
75+
7
76+
],
77+
[
78+
8,
79+
1
80+
],
81+
[
82+
6,
83+
4
84+
]
85+
]
86+
],
87+
"expected": [
88+
2,
89+
1
90+
]
91+
}
92+
]
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import json
2+
import os
3+
import unittest
4+
5+
from parameterized import parameterized
6+
7+
from .main import solution
8+
9+
10+
def load_sample(filename: str):
11+
path = os.path.join(os.path.dirname(os.path.abspath(__file__)), filename)
12+
13+
with open(path, "r") as file:
14+
return [(case["params"], case["expected"]) for case in json.load(file)]
15+
16+
17+
class TestCase(unittest.TestCase):
18+
@parameterized.expand(load_sample("sample.json"))
19+
def test_case(self, params: list, expected: any):
20+
# When
21+
result = solution(*params)
22+
23+
# Then
24+
self.assertEqual(expected, result)
25+
26+
27+
if __name__ == "__main__":
28+
unittest.main()

0 commit comments

Comments
 (0)