rogermt commited on
Commit
3255708
·
verified ·
1 Parent(s): acab118

Add task277 solver (266/266 PASS) - smallest CC recoloring

Browse files
Files changed (1) hide show
  1. medal-solvers/task277_solver_266.py +72 -0
medal-solvers/task277_solver_266.py ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Task 277 Solver — Smallest connected component recoloring (266/266 PASS).
2
+
3
+ Rule:
4
+ 1. Input is 10x10 with separate shapes made of color 8 on background 0
5
+ 2. Find 8-connected components of color 8
6
+ 3. The component with the SMALLEST area (pixel count) gets recolored to 2
7
+ 4. All other components get recolored to 1
8
+
9
+ ONNX viability:
10
+ - Requires connected-component detection (8-connected)
11
+ - On 10x10 grid, MaxPool-based CC detection needs ~20-30 iterations × ~5 nodes = 100-150 nodes
12
+ - Base: 56 nodes, profiled score 13.30
13
+ - Even with CC: ~150 nodes * 400 bytes = 60K memory + params → score ~14.1
14
+ - **POTENTIALLY VIABLE** — score 14.1 vs base 13.30 → gain +0.8
15
+ - But CC detection in ONNX is fragile and complex to build correctly
16
+
17
+ CC approach for ONNX:
18
+ 1. Initialize label grid = nonzero_mask * (row*10 + col + 1) [unique labels]
19
+ 2. Repeat 20 times: MaxPool(3x3) the label grid, masked by nonzero_mask
20
+ 3. After convergence, each CC has the same max label
21
+ 4. Count pixels per label → find minimum count label → mask it as color 2
22
+ 5. Remaining → color 1
23
+
24
+ Challenge: Step 4 requires comparing per-label counts, which is hard without dynamic shapes.
25
+ Alternative: could potentially use the fact that shapes are always rectangular frames or solid blocks.
26
+
27
+ Status: Rule cracked (266/266), ONNX build pending — needs careful CC implementation.
28
+ """
29
+ import numpy as np
30
+ import json
31
+ from scipy import ndimage
32
+
33
+
34
+ def solve_277(inp_grid):
35
+ """Smallest CC gets color 2, all others get color 1. 266/266 PASS."""
36
+ inp = np.array(inp_grid)
37
+ out = np.zeros_like(inp)
38
+
39
+ # Find 8-connected components of color 8
40
+ mask = (inp == 8).astype(int)
41
+ labeled, n = ndimage.label(mask, structure=np.ones((3, 3)))
42
+
43
+ if n == 0:
44
+ return out
45
+
46
+ # Find smallest component by area
47
+ areas = []
48
+ for i in range(1, n + 1):
49
+ areas.append(((labeled == i).sum(), i))
50
+
51
+ min_area = min(a for a, _ in areas)
52
+
53
+ for area, idx in areas:
54
+ component = (labeled == idx)
55
+ if area == min_area:
56
+ out[component] = 2
57
+ else:
58
+ out[component] = 1
59
+
60
+ return out
61
+
62
+
63
+ if __name__ == '__main__':
64
+ from pathlib import Path
65
+ task_data = Path('/app/task-data')
66
+ if not task_data.exists():
67
+ task_data = Path(__file__).parent.parent / 'task-data'
68
+ with open(task_data / 'task277.json') as f:
69
+ data = json.load(f)
70
+ all_ex = data['train'] + data['test'] + data.get('arc-gen', [])
71
+ right = sum(1 for ex in all_ex if np.array_equal(solve_277(ex['input']), np.array(ex['output'])))
72
+ print(f'task277: {right}/{len(all_ex)} PASS')