From 7bc072b3d9d701f07cc8f81e48a48c9145782c32 Mon Sep 17 00:00:00 2001 From: MR7star Date: Fri, 26 Dec 2025 01:11:38 +0530 Subject: [PATCH 01/11] Finished greedy logic --- main.py | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index 6e7fd8e..31bf1b6 100644 --- a/main.py +++ b/main.py @@ -84,7 +84,37 @@ def greedy_color_selector(graph, color) -> int: Also, don't just look at the immediate neighbors; consider the potential chain reactions that could occur by selecting a particular color. """ - pass + start_color = color[0] + best_color = start_color + best_size = -1 + + for candidate in range(1, 7): + if candidate == start_color: + continue + + temp_color = color[:] + queue = [0] + visited = set([0]) + temp_color[0] = candidate + + while queue: + u = queue.pop(0) + for v in graph[u]: + if v not in visited and temp_color[v] == start_color: + visited.add(v) + temp_color[v] = candidate + queue.append(v) + + size = len(visited) + + if size > best_size: + best_size = size + best_color = candidate + + return best_color + + + ######################################################################################## # ------------------------------ GAME WINDOW ------------------------------- From a21ce004c0e9e64e570ef7835433a086ec71fb58 Mon Sep 17 00:00:00 2001 From: MR7star Date: Fri, 26 Dec 2025 09:19:53 +0530 Subject: [PATCH 02/11] updated with sorting --- main.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/main.py b/main.py index 31bf1b6..337520c 100644 --- a/main.py +++ b/main.py @@ -84,9 +84,9 @@ def greedy_color_selector(graph, color) -> int: Also, don't just look at the immediate neighbors; consider the potential chain reactions that could occur by selecting a particular color. """ + start_color = color[0] - best_color = start_color - best_size = -1 + results = [] # (flooded_size, candidate_color) for candidate in range(1, 7): if candidate == start_color: @@ -105,13 +105,20 @@ def greedy_color_selector(graph, color) -> int: temp_color[v] = candidate queue.append(v) - size = len(visited) + results.append((len(visited), candidate)) + + # -------- SELECTION SORT (DESCENDING BY FLOODED SIZE) -------- + n = len(results) + for i in range(n): + max_idx = i + for j in range(i + 1, n): + if results[j][0] > results[max_idx][0]: + max_idx = j + results[i], results[max_idx] = results[max_idx], results[i] + # ------------------------------------------------------------ - if size > best_size: - best_size = size - best_color = candidate + return results[0][1] - return best_color From 0e04ce576064ae579ecea3db8604695361e2d628 Mon Sep 17 00:00:00 2001 From: MR7star Date: Fri, 26 Dec 2025 10:05:37 +0530 Subject: [PATCH 03/11] with boundary update --- main.py | 78 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 29 deletions(-) diff --git a/main.py b/main.py index 337520c..3cfa4b8 100644 --- a/main.py +++ b/main.py @@ -67,7 +67,7 @@ def grid_update(selected_color: int) -> None: pass -def greedy_color_selector(graph, color) -> int: +def greedy_color_selector(graph, color, C=6) -> int: """ Docstring for greedy_color_selector @@ -85,43 +85,63 @@ def greedy_color_selector(graph, color) -> int: """ - start_color = color[0] - results = [] # (flooded_size, candidate_color) + + n = len(color) - for candidate in range(1, 7): - if candidate == start_color: - continue + flooded = [False] * n + boundary = set() - temp_color = color[:] - queue = [0] - visited = set([0]) - temp_color[0] = candidate + flooded[0] = True + currentColor = color[0] - while queue: - u = queue.pop(0) - for v in graph[u]: - if v not in visited and temp_color[v] == start_color: - visited.add(v) - temp_color[v] = candidate - queue.append(v) + for u in graph[0]: + if not flooded[u]: + boundary.add(u) - results.append((len(visited), candidate)) + solution_seq = [] + moves = 0 - # -------- SELECTION SORT (DESCENDING BY FLOODED SIZE) -------- - n = len(results) - for i in range(n): - max_idx = i - for j in range(i + 1, n): - if results[j][0] > results[max_idx][0]: - max_idx = j - results[i], results[max_idx] = results[max_idx], results[i] - # ------------------------------------------------------------ + while boundary: + colorCount = [0] * (C + 1) - return results[0][1] + for v in boundary: + colorCount[color[v]] += 1 + colorPairs = [] + for c in range(1, C + 1): + colorPairs.append([colorCount[c], c]) + + for i in range(1, C): + key = colorPairs[i] + j = i - 1 + while j >= 0 and colorPairs[j][0] < key[0]: + colorPairs[j + 1] = colorPairs[j] + j -= 1 + colorPairs[j + 1] = key + + chosenColor = colorPairs[0][1] + + solution_seq.append(chosenColor) + moves += 1 + + newFlooded = [] + + for v in list(boundary): + if color[v] == chosenColor: + flooded[v] = True + newFlooded.append(v) + + for v in newFlooded: + boundary.remove(v) + for u in graph[v]: + if not flooded[u] and u not in boundary: + boundary.add(u) + + currentColor = chosenColor + + return moves, solution_seq - ######################################################################################## # ------------------------------ GAME WINDOW ------------------------------- From 8c79b64abe78eab31497bd2c4a9838452ba6df6f Mon Sep 17 00:00:00 2001 From: MR7star Date: Fri, 26 Dec 2025 10:16:15 +0530 Subject: [PATCH 04/11] return type color --- main.py | 53 ++++++++++++++--------------------------------------- 1 file changed, 14 insertions(+), 39 deletions(-) diff --git a/main.py b/main.py index 3cfa4b8..7ad40f7 100644 --- a/main.py +++ b/main.py @@ -84,8 +84,6 @@ def greedy_color_selector(graph, color, C=6) -> int: Also, don't just look at the immediate neighbors; consider the potential chain reactions that could occur by selecting a particular color. """ - - n = len(color) flooded = [False] * n @@ -98,48 +96,25 @@ def greedy_color_selector(graph, color, C=6) -> int: if not flooded[u]: boundary.add(u) - solution_seq = [] - moves = 0 - - while boundary: - colorCount = [0] * (C + 1) - - for v in boundary: - colorCount[color[v]] += 1 - - colorPairs = [] - for c in range(1, C + 1): - colorPairs.append([colorCount[c], c]) - - for i in range(1, C): - key = colorPairs[i] - j = i - 1 - while j >= 0 and colorPairs[j][0] < key[0]: - colorPairs[j + 1] = colorPairs[j] - j -= 1 - colorPairs[j + 1] = key - - chosenColor = colorPairs[0][1] - - solution_seq.append(chosenColor) - moves += 1 + colorCount = [0] * (C + 1) - newFlooded = [] + for v in boundary: + colorCount[color[v]] += 1 - for v in list(boundary): - if color[v] == chosenColor: - flooded[v] = True - newFlooded.append(v) + colorPairs = [] + for c in range(1, C + 1): + colorPairs.append([colorCount[c], c]) - for v in newFlooded: - boundary.remove(v) - for u in graph[v]: - if not flooded[u] and u not in boundary: - boundary.add(u) + for i in range(1, C): + key = colorPairs[i] + j = i - 1 + while j >= 0 and colorPairs[j][0] < key[0]: + colorPairs[j + 1] = colorPairs[j] + j -= 1 + colorPairs[j + 1] = key - currentColor = chosenColor + return colorPairs[0][1] - return moves, solution_seq From 53963c87a757a110e521572bf2e09946ce14294e Mon Sep 17 00:00:00 2001 From: MR7star Date: Fri, 26 Dec 2025 12:52:23 +0530 Subject: [PATCH 05/11] updated greedy --- main.py | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/main.py b/main.py index 7ad40f7..22a1b22 100644 --- a/main.py +++ b/main.py @@ -84,36 +84,47 @@ def greedy_color_selector(graph, color, C=6) -> int: Also, don't just look at the immediate neighbors; consider the potential chain reactions that could occur by selecting a particular color. """ + n = len(color) + start_color = color[0] flooded = [False] * n boundary = set() + # STEP 1: find current flooded region (BFS) + queue = [0] flooded[0] = True - currentColor = color[0] - - for u in graph[0]: - if not flooded[u]: - boundary.add(u) + while queue: + u = queue.pop(0) + for v in graph[u]: + if not flooded[v] and color[v] == start_color: + flooded[v] = True + queue.append(v) + + # STEP 2: build boundary of flooded region + for u in range(n): + if flooded[u]: + for v in graph[u]: + if not flooded[v]: + boundary.add(v) + + # STEP 3: greedy evaluation using boundary colorCount = [0] * (C + 1) for v in boundary: colorCount[color[v]] += 1 - colorPairs = [] + best_color = start_color + best_count = -1 + for c in range(1, C + 1): - colorPairs.append([colorCount[c], c]) + if c != start_color and colorCount[c] > best_count: + best_count = colorCount[c] + best_color = c - for i in range(1, C): - key = colorPairs[i] - j = i - 1 - while j >= 0 and colorPairs[j][0] < key[0]: - colorPairs[j + 1] = colorPairs[j] - j -= 1 - colorPairs[j + 1] = key + return best_color - return colorPairs[0][1] From 116028087fe7659c5a6be46d707a756d1720ba1b Mon Sep 17 00:00:00 2001 From: MR7star Date: Fri, 26 Dec 2025 13:13:55 +0530 Subject: [PATCH 06/11] with insertion sort --- main.py | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/main.py b/main.py index 22a1b22..f5151dc 100644 --- a/main.py +++ b/main.py @@ -84,14 +84,13 @@ def greedy_color_selector(graph, color, C=6) -> int: Also, don't just look at the immediate neighbors; consider the potential chain reactions that could occur by selecting a particular color. """ - n = len(color) start_color = color[0] flooded = [False] * n boundary = set() - # STEP 1: find current flooded region (BFS) + # Step 1: Find current flooded region (BFS) queue = [0] flooded[0] = True @@ -102,28 +101,38 @@ def greedy_color_selector(graph, color, C=6) -> int: flooded[v] = True queue.append(v) - # STEP 2: build boundary of flooded region + # Step 2: Build boundary for u in range(n): if flooded[u]: for v in graph[u]: if not flooded[v]: boundary.add(v) - # STEP 3: greedy evaluation using boundary + # Step 3: Count colors on boundary colorCount = [0] * (C + 1) - for v in boundary: colorCount[color[v]] += 1 - best_color = start_color - best_count = -1 - + # Step 4: Create (count, color) pairs + colorPairs = [] for c in range(1, C + 1): - if c != start_color and colorCount[c] > best_count: - best_count = colorCount[c] - best_color = c + if c != start_color: + colorPairs.append([colorCount[c], c]) + + # Step 5: INSERTION SORT (descending by count) + for i in range(1, len(colorPairs)): + key = colorPairs[i] + j = i - 1 + + while j >= 0 and colorPairs[j][0] < key[0]: + colorPairs[j + 1] = colorPairs[j] + j -= 1 + + colorPairs[j + 1] = key + + # Step 6: Return best color + return colorPairs[0][1] - return best_color From d1cda7181e23fe77d14dedff619e351654177835 Mon Sep 17 00:00:00 2001 From: MR7star Date: Thu, 19 Feb 2026 01:48:37 +0530 Subject: [PATCH 07/11] new simulated board using BFS --- dp.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 dp.py diff --git a/dp.py b/dp.py new file mode 100644 index 0000000..ef757c9 --- /dev/null +++ b/dp.py @@ -0,0 +1,28 @@ +def simulate_move(graph, current_color, move_color): + """ + State Transition Function (S → S′) + Creates a new hypothetical board after applying a move. + Does NOT modify the original board. + """ + + new_colors = list(current_color) + + start_node = 0 + old_color = new_colors[start_node] + + if old_color == move_color: + return new_colors + + #BFS + queue = [start_node] + visited = {start_node} + new_colors[start_node] = move_color + + while queue: + u = queue.pop(0) + for v in graph[u]: + if v not in visited and new_colors[v] == old_color: + visited.add(v) + new_colors[v] = move_color + queue.append(v) + return new_colors From 548ea841682cd3811a3f4bad28facb092dce2220 Mon Sep 17 00:00:00 2001 From: MR7star Date: Thu, 19 Feb 2026 15:29:07 +0530 Subject: [PATCH 08/11] Update : added boundary colors, checking for errors. --- dp.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/dp.py b/dp.py index ef757c9..9eaa4fb 100644 --- a/dp.py +++ b/dp.py @@ -26,3 +26,47 @@ def simulate_move(graph, current_color, move_color): new_colors[v] = move_color queue.append(v) return new_colors + +def get_flooded_size(graph, colors): + + """ + Utility Function + Returns size of flooded region starting from node 0. + """ + start_node = 0 + target_color = colors[start_node] + + queue = deque([start_node]) + visited = set([start_node]) + + while queue: + node = queue.popleft() + + for neighbour in graph[node]: + if neighbour not in visited and colors[neighbour] == target_color: + visited.add(neighbour) + queue.append(neighbour) + return len(visited) + +def boundary_colors(graph,colors): + start_node = 0 + base_color = colors[start_node] + + queue = deque([start_node]) + visited = set([start_node]) + + while queue: + node = queue.popleft() + for neighbour in graph[node]: + if neighbour not in visited and colors[neighbour] == base_color: + visited.add(neighbour) + queue.append(neighbour) + + boundary = set() + + for node in visited: + for neighbour in graph[node]: + if neighbour not in visited: + boundary.add(colors[neighbour]) + + return boundary From 4800ea57b44e2b2986bf3f3c05678f8fc7e25b3f Mon Sep 17 00:00:00 2001 From: MR7star Date: Thu, 19 Feb 2026 15:44:19 +0530 Subject: [PATCH 09/11] changes made --- dp.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dp.py b/dp.py index 9eaa4fb..2831afe 100644 --- a/dp.py +++ b/dp.py @@ -36,8 +36,8 @@ def get_flooded_size(graph, colors): start_node = 0 target_color = colors[start_node] - queue = deque([start_node]) - visited = set([start_node]) + queue = [start_node] + visited = {start_node} while queue: node = queue.popleft() @@ -52,8 +52,8 @@ def boundary_colors(graph,colors): start_node = 0 base_color = colors[start_node] - queue = deque([start_node]) - visited = set([start_node]) + queue = [start_node] + visited = {start_node} while queue: node = queue.popleft() From 63389f33fcde3720b59b6b6da5152adae4ef24e2 Mon Sep 17 00:00:00 2001 From: MR7star Date: Thu, 19 Feb 2026 15:55:29 +0530 Subject: [PATCH 10/11] minor changes --- dp.py | 75 +-------------------------------------------------------- main.py | 2 +- 2 files changed, 2 insertions(+), 75 deletions(-) diff --git a/dp.py b/dp.py index 2ce85ec..141d8bb 100644 --- a/dp.py +++ b/dp.py @@ -106,77 +106,4 @@ def dp_color_selector(graph, color) -> int: if move is None: return 1 - return move - -def simulate_move(graph, current_color, move_color): - """ - State Transition Function (S → S′) - Creates a new hypothetical board after applying a move. - Does NOT modify the original board. - """ - - new_colors = list(current_color) - - start_node = 0 - old_color = new_colors[start_node] - - if old_color == move_color: - return new_colors - - #BFS - queue = [start_node] - visited = {start_node} - new_colors[start_node] = move_color - - while queue: - u = queue.pop(0) - for v in graph[u]: - if v not in visited and new_colors[v] == old_color: - visited.add(v) - new_colors[v] = move_color - queue.append(v) - return new_colors - -def get_flooded_size(graph, colors): - - """ - Utility Function - Returns size of flooded region starting from node 0. - """ - start_node = 0 - target_color = colors[start_node] - - queue = [start_node] - visited = {start_node} - - while queue: - node = queue.popleft() - - for neighbour in graph[node]: - if neighbour not in visited and colors[neighbour] == target_color: - visited.add(neighbour) - queue.append(neighbour) - return len(visited) - -def boundary_colors(graph,colors): - start_node = 0 - base_color = colors[start_node] - - queue = [start_node] - visited = {start_node} - - while queue: - node = queue.popleft() - for neighbour in graph[node]: - if neighbour not in visited and colors[neighbour] == base_color: - visited.add(neighbour) - queue.append(neighbour) - - boundary = set() - - for node in visited: - for neighbour in graph[node]: - if neighbour not in visited: - boundary.add(colors[neighbour]) - - return boundary + return move \ No newline at end of file diff --git a/main.py b/main.py index 2681e62..d37b064 100644 --- a/main.py +++ b/main.py @@ -399,4 +399,4 @@ def draw_grid(color): iconlabel2 = tk.Label(root, image=icon2, bg="#282A36") iconlabel2.place(x=700, y=70, anchor="sw") -root.mainloop() +root.mainloop() \ No newline at end of file From 9a2af414636f89de91a561604fe5b91b7d41ec08 Mon Sep 17 00:00:00 2001 From: MR7star Date: Thu, 19 Feb 2026 16:06:52 +0530 Subject: [PATCH 11/11] Update : changes added to the dp.py file. --- dp.py | 64 +++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/dp.py b/dp.py index 141d8bb..c8ec0c6 100644 --- a/dp.py +++ b/dp.py @@ -3,46 +3,54 @@ SEARCH_DEPTH = 4 # Anything above 4 may cause lag def get_flooded_size_sim(graph, current_colors): - """Helper: Counts size of flooded region for a simulation state.""" - target_c = current_colors[0] - count = 0 - visited = {0} - q = [0] - while q: - u = q.pop(0) - count += 1 - for v in graph[u]: - if v not in visited and current_colors[v] == target_c: - visited.add(v) - q.append(v) - return count + start_node = 0 + target_color = current_colors[start_node] + + queue = [start_node] + visited = {start_node} + + while queue: + node = queue.pop(0) + + for neighbour in graph[node]: + if neighbour not in visited and current_colors[neighbour] == target_color: + visited.add(neighbour) + queue.append(neighbour) + + return len(visited) + -def simulate_move(graph, current_colors, move_color): +def simulate_move(graph, current_color, move_color): """ - Returns a NEW list of colors after applying a hypothetical move. - Does NOT change the global 'color' list. + State Transition Function (S → S′) + Creates a new hypothetical board after applying a move. + Does NOT modify the original board. """ - new_colors = list(current_colors) + + new_colors = list(current_color) + start_node = 0 - old_c = new_colors[start_node] - - if old_c == move_color: - return new_colors + old_color = new_colors[start_node] - # BFS to change color - q = [start_node] + if old_color == move_color: + return new_colors + + # BFS + queue = [start_node] visited = {start_node} new_colors[start_node] = move_color - - while q: - u = q.pop(0) + + while queue: + u = queue.pop(0) for v in graph[u]: - if v not in visited and new_colors[v] == old_c: + if v not in visited and new_colors[v] == old_color: visited.add(v) new_colors[v] = move_color - q.append(v) + queue.append(v) + return new_colors + def dp_solve(current_colors, depth, graph): """ Recursive DP Function with Memoization.