rogermt's picture
Move own-solver/neurogolf_solver/solvers/mode.py to own-solver/
2c8b675 verified
#!/usr/bin/env python3
"""Mode fill solver — output = solid fill of most common input color.
v5.2: Solves Task 129 (score 19.451).
Uses runtime ReduceSum→ArgMax→Expand for variable mode across inputs.
Falls through to s_constant when mode is fixed across all examples.
"""
import numpy as np
from onnx import helper, numpy_helper, TensorProto
from ..onnx_helpers import mk, _make_int64_init, _build_pad_node
from ..data_loader import get_exs, fixed_shapes
from ..constants import GH, GW
def s_mode_fill(td):
"""Mode fill: output is entirely the most common color from input.
Uses runtime ArgMax to handle variable mode across inputs."""
exs = get_exs(td)
for inp, out in exs:
if inp.shape != out.shape:
return None
vals, counts = np.unique(inp, return_counts=True)
mode = vals[np.argmax(counts)]
if not np.all(out == mode):
return None
# Check if mode is always the same color
modes = set()
for inp, out in exs:
vals, counts = np.unique(inp, return_counts=True)
modes.add(vals[np.argmax(counts)])
if len(modes) == 1:
return None # Let s_constant handle it
sp = fixed_shapes(td)
if sp is None:
return None
(IH, IW), (OH, OW) = sp
if (IH, IW) != (OH, OW):
return None
pad_h, pad_w = GH - IH, GW - IW
inits = [
_make_int64_init('sl_st', [0, 0, 0, 0]),
_make_int64_init('sl_en', [1, 10, IH, IW]),
_make_int64_init('rs_axes_mode', [2, 3]),
numpy_helper.from_array(np.arange(10, dtype=np.int64).reshape(1, 10, 1, 1), 'classes'),
]
nodes = [
helper.make_node('Slice', ['input', 'sl_st', 'sl_en'], ['cropped']),
helper.make_node('ReduceSum', ['cropped', 'rs_axes_mode'], ['hist'], keepdims=1),
helper.make_node('ArgMax', ['hist'], ['mode_idx'], axis=1, keepdims=1),
helper.make_node('Equal', ['mode_idx', 'classes'], ['eq']),
helper.make_node('Cast', ['eq'], ['mode_oh'], to=TensorProto.FLOAT),
helper.make_node('Expand', ['mode_oh', 'sl_en'], ['expanded']),
]
nodes.append(_build_pad_node('expanded', 'output', pad_h, pad_w, inits))
return mk(nodes, inits)