Spaces:
Sleeping
Sleeping
File size: 7,373 Bytes
a32ce1a acdd1bb a32ce1a acdd1bb a32ce1a 0df47bb a32ce1a 0df47bb a32ce1a 0df47bb a32ce1a 49adc3e acdd1bb a32ce1a acdd1bb 49adc3e acdd1bb 49adc3e acdd1bb 49adc3e a32ce1a acdd1bb a32ce1a fc56a10 a32ce1a acdd1bb a32ce1a acdd1bb a32ce1a 49adc3e a32ce1a acdd1bb 49adc3e acdd1bb 49adc3e acdd1bb 40d4f0c 49adc3e acdd1bb 40d4f0c 49adc3e acdd1bb 0df47bb 49adc3e 0df47bb acdd1bb 49adc3e acdd1bb 49adc3e acdd1bb 49adc3e acdd1bb 49adc3e acdd1bb 49adc3e acdd1bb 49adc3e acdd1bb 49adc3e acdd1bb 49adc3e acdd1bb f1e7496 acdd1bb 49adc3e acdd1bb 82f0837 acdd1bb a32ce1a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | import gradio as gr
from itertools import permutations
# ==========================================
# 1. SOLVER LOGIC
# ==========================================
# (Standard logic, same as before)
def apply_op(a, op, b):
if op == '+': return a + b
if op == '-': return a - b
if op == '×': return a * b
if op == '÷':
if b == 0 or a % b != 0: return None
return a // b
return None
def evaluate_line(n1, op1, n2, op2, n3):
high_precedence = {'×', '÷'}
if op2 in high_precedence and op1 not in high_precedence:
right = apply_op(n2, op2, n3)
if right is None: return None
return apply_op(n1, op1, right)
else:
left = apply_op(n1, op1, n2)
if left is None: return None
return apply_op(left, op2, n3)
def solve_puzzle(pool_str, *args):
# args contains all the grid inputs in the specific order we passed them
# Unpack based on the specific structure of the inputs list constructed below
try:
pool = [int(x.strip()) for x in pool_str.split(',')]
if len(pool) != 9: return [""] * 9
except ValueError: return [""] * 9
# Unpack args. The order matches the 'inputs' list in the UI section
# Rows: 1, 2, 3
r1 = [args[0], args[1], int(args[2])]
r2 = [args[3], args[4], int(args[5])]
r3 = [args[6], args[7], int(args[8])]
# Cols: 1, 2, 3 (Top Ops) & 4, 5, 6 (Bottom Ops) & Targets
c1 = [args[9], args[12], int(args[15])]
c2 = [args[10], args[13], int(args[16])]
c3 = [args[11], args[14], int(args[17])]
row_ops = [[r1[0], r1[1]], [r2[0], r2[1]], [r3[0], r3[1]]]
col_ops = [[c1[0], c1[1]], [c2[0], c2[1]], [c3[0], c3[1]]]
row_targets = [r1[2], r2[2], r3[2]]
col_targets = [c1[2], c2[2], c3[2]]
for p in permutations(pool):
# Checks
if evaluate_line(p[0], row_ops[0][0], p[1], row_ops[0][1], p[2]) != row_targets[0]: continue
if evaluate_line(p[3], row_ops[1][0], p[4], row_ops[1][1], p[5]) != row_targets[1]: continue
if evaluate_line(p[6], row_ops[2][0], p[7], row_ops[2][1], p[8]) != row_targets[2]: continue
if evaluate_line(p[0], col_ops[0][0], p[3], col_ops[0][1], p[6]) != col_targets[0]: continue
if evaluate_line(p[1], col_ops[1][0], p[4], col_ops[1][1], p[7]) != col_targets[1]: continue
if evaluate_line(p[2], col_ops[2][0], p[5], col_ops[2][1], p[8]) != col_targets[2]: continue
return [str(x) for x in p]
return ["?"] * 9
# ==========================================
# 2. GRID CONFIGURATION
# ==========================================
# We define the grid semantically:
# "SOL" = Solution Box (Non-editable output)
# "OP" = Operator (Dropdown input)
# "TGT" = Target (Editable input)
# "EQ" = Equals Sign
# "SPC" = Spacer (Empty)
GRID_LAYOUT = [
["SOL", "OP", "SOL", "OP", "SOL", "EQ", "TGT"], # Row 0
["OP", "SPC", "OP", "SPC", "OP", "SPC", "SPC"], # Row 1
["SOL", "OP", "SOL", "OP", "SOL", "EQ", "TGT"], # Row 2
["OP", "SPC", "OP", "SPC", "OP", "SPC", "SPC"], # Row 3
["SOL", "OP", "SOL", "OP", "SOL", "EQ", "TGT"], # Row 4
["EQ", "SPC", "EQ", "SPC", "EQ", "SPC", "SPC"], # Row 5
["TGT", "SPC", "TGT", "SPC", "TGT", "SPC", "SPC"] # Row 6
]
# CSS to make the grid look tight and clean
css = """
.tight-row { gap: 5px !important; margin-bottom: 5px; }
.sol-box textarea {
background-color: #6366f1 !important; color: white !important;
font-size: 20px !important; text-align: center !important; font-weight: bold;
}
.tgt-box textarea {
border: 2px solid #6366f1 !important; font-size: 18px !important;
text-align: center !important; font-weight: bold;
}
.center-html {
display: flex; justify-content: center; align-items: center;
font-size: 24px; font-weight: bold; height: 100%; color: #94a3b8;
}
"""
with gr.Blocks(css=css, theme=gr.themes.Soft()) as demo:
gr.Markdown("## 🧩 Programmatic Grid Solver")
with gr.Row():
pool_input = gr.Textbox(label="Number Pool", value="7, 14, 4, 210, 70, 4, 49, 81, 13")
solve_btn = gr.Button("🚀 Solve", variant="primary")
# This list will store our generated component objects so we can access them later
# to extract inputs or update outputs.
grid_refs = [[None for _ in range(7)] for _ in range(7)]
# We also keep a flat list of just the Solution boxes to easily map outputs
solution_outputs = []
# --- THE BUILDER LOOP ---
for r, row_config in enumerate(GRID_LAYOUT):
with gr.Row(equal_height=True, elem_classes="tight-row"):
for c, type_code in enumerate(row_config):
# 1. Solution Box (Output)
if type_code == "SOL":
comp = gr.Textbox(interactive=False, show_label=False, elem_classes="sol-box", scale=1)
solution_outputs.append(comp) # Store for output mapping
grid_refs[r][c] = comp
# 2. Operator (Input)
elif type_code == "OP":
comp = gr.Dropdown(["+", "-", "×", "÷"], value="+", container=False, scale=0.6, min_width=50)
grid_refs[r][c] = comp
# 3. Target (Input)
elif type_code == "TGT":
# Default values for demo purposes based on position
def_val = "0"
if r==0: def_val="227"
elif r==2: def_val="20"
elif r==4: def_val="74"
elif r==6 and c==0: def_val="90"
elif r==6 and c==2: def_val="147"
elif r==6 and c==4: def_val="49"
comp = gr.Textbox(value=def_val, show_label=False, container=False, elem_classes="tgt-box", scale=1)
grid_refs[r][c] = comp
# 4. Static Elements
elif type_code == "EQ":
gr.HTML('<div class="center-html">=</div>', scale=0.3)
elif type_code == "SPC":
gr.HTML('', scale=1) # Empty Spacer
# --- WIRING THE INPUTS ---
# Now we need to explicitly gather the inputs in the order the solver expects.
# We access them using the grid_refs matrix we populated in the loop.
solver_inputs = [pool_input]
# Row 1 Inputs (Op1, Op2, Target) -> Grid Coords: (0,1), (0,3), (0,6)
solver_inputs.extend([grid_refs[0][1], grid_refs[0][3], grid_refs[0][6]])
# Row 2 Inputs -> Grid Coords: (2,1), (2,3), (2,6)
solver_inputs.extend([grid_refs[2][1], grid_refs[2][3], grid_refs[2][6]])
# Row 3 Inputs -> Grid Coords: (4,1), (4,3), (4,6)
solver_inputs.extend([grid_refs[4][1], grid_refs[4][3], grid_refs[4][6]])
# Col Ops Top -> Grid Coords: (1,0), (1,2), (1,4)
solver_inputs.extend([grid_refs[1][0], grid_refs[1][2], grid_refs[1][4]])
# Col Ops Bottom -> Grid Coords: (3,0), (3,2), (3,4)
solver_inputs.extend([grid_refs[3][0], grid_refs[3][2], grid_refs[3][4]])
# Col Targets -> Grid Coords: (6,0), (6,2), (6,4)
solver_inputs.extend([grid_refs[6][0], grid_refs[6][2], grid_refs[6][4]])
# Execute
solve_btn.click(fn=solve_puzzle, inputs=solver_inputs, outputs=solution_outputs)
if __name__ == "__main__":
demo.launch() |