""" Task 233 Solver — 263/266 verified Rule: 1. Input has a large rectangle (largest CC of 2-cells) with "holes" (0-cells inside) 2. Input has small 3×3 "key" patterns (color + 2) outside the rectangle 3. Each hole's 0-pattern matches a key's 2-pattern under rotation/flip (8 orientations) 4. Output = rectangle content with the matching rotated key placed at each hole 5. When multiple orientations match, prefer the most interior placement Hole grouping: 0-cells are grouped by 8-connectivity + bbox ≤ 3×3 constraint. 3 failures due to edge cases in grouping (cells within distance 3 but different logical groups). ONNX Status: NOT VIABLE — requires CC detection, rotation matching, variable grids """ import json import numpy as np from scipy.ndimage import label def normalize_positions(positions): if not positions: return frozenset() min_r = min(r for r, c in positions) min_c = min(c for r, c in positions) return frozenset((r - min_r, c - min_c) for r, c in positions) def get_8_orientations(pattern_3x3): orientations = [] p = pattern_3x3 for _ in range(4): orientations.append(p.copy()) orientations.append(np.fliplr(p).copy()) p = np.rot90(p, 1) return orientations def solve_task233(inp_grid): inp = np.array(inp_grid) H, W = inp.shape # Find the rectangle: largest connected component of 2-cells c2_mask = (inp == 2) labeled_c2, num_c2 = label(c2_mask) largest_size = 0 largest_label = 0 for lbl in range(1, num_c2 + 1): size = np.sum(labeled_c2 == lbl) if size > largest_size: largest_size = size largest_label = lbl component = (labeled_c2 == largest_label) rows_comp = np.where(np.any(component, axis=1))[0] cols_comp = np.where(np.any(component, axis=0))[0] r_top, r_bot = rows_comp[0], rows_comp[-1] c_left, c_right = cols_comp[0], cols_comp[-1] rect = inp[r_top:r_bot+1, c_left:c_right+1] rect_h, rect_w = rect.shape # Find holes: group 0-cells with union-find (8-conn + bbox ≤ 3×3) zero_cells = list(map(tuple, np.argwhere(rect == 0))) if not zero_cells: return rect.tolist() parent = list(range(len(zero_cells))) def find(x): while parent[x] != x: parent[x] = parent[parent[x]] x = parent[x] return x def union(x, y): px, py = find(x), find(y) if px != py: parent[px] = py cell_idx = {c: i for i, c in enumerate(zero_cells)} for i, (r, c) in enumerate(zero_cells): for dr in range(-1, 2): for dc in range(-1, 2): if dr == 0 and dc == 0: continue nb = (r + dr, c + dc) if nb in cell_idx: j = cell_idx[nb] gi, gj = find(i), find(j) if gi == gj: continue cells_i = [zero_cells[k] for k in range(len(zero_cells)) if find(k) == gi] cells_j = [zero_cells[k] for k in range(len(zero_cells)) if find(k) == gj] all_cells = cells_i + cells_j min_r = min(p[0] for p in all_cells) max_r = max(p[0] for p in all_cells) min_c = min(p[1] for p in all_cells) max_c = max(p[1] for p in all_cells) if max_r - min_r < 3 and max_c - min_c < 3: union(i, j) # Second pass: merge groups within distance 3 if bbox fits changed = True while changed: changed = False groups = {} for i in range(len(zero_cells)): g = find(i) if g not in groups: groups[g] = [] groups[g].append(i) group_list = list(groups.values()) for a_idx in range(len(group_list)): for b_idx in range(a_idx + 1, len(group_list)): ga, gb = group_list[a_idx], group_list[b_idx] if find(ga[0]) == find(gb[0]): continue min_dist = min(abs(zero_cells[ai][0]-zero_cells[bi][0])+abs(zero_cells[ai][1]-zero_cells[bi][1]) for ai in ga for bi in gb) if min_dist > 3: continue all_cells = [zero_cells[k] for k in ga + gb] min_r = min(p[0] for p in all_cells) max_r = max(p[0] for p in all_cells) min_c = min(p[1] for p in all_cells) max_c = max(p[1] for p in all_cells) if max_r - min_r < 3 and max_c - min_c < 3: union(ga[0], gb[0]) changed = True if changed: break groups = {} for i in range(len(zero_cells)): g = find(i) if g not in groups: groups[g] = [] groups[g].append(zero_cells[i]) hole_groups = list(groups.values()) # Extract 3×3 keys from outside the rectangle keys = [] rect_area = np.zeros_like(inp, dtype=bool) rect_area[r_top:r_bot+1, c_left:c_right+1] = True outside_nonzero = (inp != 0) & ~rect_area labeled_keys, num_keys = label(outside_nonzero) for k in range(1, num_keys + 1): key_cells = np.argwhere(labeled_keys == k) if len(key_cells) < 4: continue kr = [p[0] for p in key_cells] kc = [p[1] for p in key_cells] kr_min, kr_max = min(kr), max(kr) kc_min, kc_max = min(kc), max(kc) if kr_max - kr_min == 2 and kc_max - kc_min == 2: keys.append(inp[kr_min:kr_max+1, kc_min:kc_max+1]) # Pre-compute orientations key_orientations = [] for ki, key in enumerate(keys): for oriented in get_8_orientations(key): two_pos = set(map(tuple, np.argwhere(oriented == 2))) key_orientations.append((ki, oriented, normalize_positions(two_pos))) output = np.full((rect_h, rect_w), 2, dtype=int) for hole_cells in hole_groups: hole_rows = [p[0] for p in hole_cells] hole_cols = [p[1] for p in hole_cells] h_min_r = min(hole_rows) h_min_c = min(hole_cols) hole_norm = normalize_positions(set(hole_cells)) best_placement = None best_score = -1 for ki, oriented, two_pos_norm in key_orientations: if two_pos_norm == hole_norm: key_2_pos = set(map(tuple, np.argwhere(oriented == 2))) key_2_min_r = min(r for r, c in key_2_pos) key_2_min_c = min(c for r, c in key_2_pos) place_r = h_min_r - key_2_min_r place_c = h_min_c - key_2_min_c key_2_abs = set((place_r + r, place_c + c) for r, c in key_2_pos) if key_2_abs != set(hole_cells): continue if place_r < 0 or place_c < 0 or place_r + 3 > rect_h or place_c + 3 > rect_w: continue score = min(place_r, place_c, rect_h - place_r - 3, rect_w - place_c - 3) if score > best_score: best_score = score best_placement = (place_r, place_c, oriented) if best_placement: place_r, place_c, oriented = best_placement for dr in range(3): for dc in range(3): r, c = place_r + dr, place_c + dc if 0 <= r < rect_h and 0 <= c < rect_w: output[r, c] = oriented[dr, dc] return output.tolist() if __name__ == '__main__': with open('/app/task-data/task233.json') as f: data = json.load(f) all_examples = data['train'] + data['test'] + data.get('arc-gen', []) right = sum(1 for ex in all_examples if solve_task233(ex['input']) == ex['output']) print(f"Results: {right}/{len(all_examples)} pass ({len(all_examples)-right} fail)")