{
"id": "292",
"prompt": "Write a proper four-function calculator: a 4x4 key grid (7 8 9 +, 4 5 6 -, 1 2 3 x, C 0 = divide), a readout bar, and immediate-execution semantics - pressing an operator folds any pending one first, equals collapses and clears the pending op, C resets everything, and division by zero yields 0. rustlite has no globals, so entry, accumulator, pending op and the start-fresh flag all live in state slots; map key index to digit, op code and glyph with small match helper fns.",
"solution_rl": "fn apply(op: i32, a: i32, b: i32) -> i32 {\n match op {\n 1 => a + b,\n 2 => a - b,\n 3 => a * b,\n 4 => if b == 0 { 0 } else { a / b },\n _ => b,\n }\n}\n\nfn key_digit(idx: i32) -> i32 {\n match idx {\n 0 => 7,\n 1 => 8,\n 2 => 9,\n 4 => 4,\n 5 => 5,\n 6 => 6,\n 8 => 1,\n 9 => 2,\n 10 => 3,\n 13 => 0,\n _ => -1,\n }\n}\n\nfn key_char(idx: i32) -> i32 {\n match idx {\n 3 => 43,\n 7 => 45,\n 11 => 42,\n 12 => 67,\n 14 => 61,\n 15 => 47,\n _ => 32,\n }\n}\n\nfn op_of(idx: i32) -> i32 {\n match idx {\n 3 => 1,\n 7 => 2,\n 11 => 3,\n 15 => 4,\n _ => 0,\n }\n}\n\nfn frame(t: i32) {\n host::display::clear(0x0d0d10);\n host::display::fill_rect(16, 24, 480, 70, 0x1a1e26);\n host::display::draw_number(36, 44, host::display::state_get(1), 0xffffff, 4);\n let pending: i32 = host::display::state_get(3);\n if pending != 0 {\n host::display::draw_char(460, 44, key_char(match pending {\n 1 => 3,\n 2 => 7,\n 3 => 11,\n _ => 15,\n }), 0xffcc33, 3);\n }\n\n let mut idx: i32 = 0;\n while idx < 16 {\n let x: i32 = 16 + (idx % 4) * 124;\n let y: i32 = 120 + (idx / 4) * 92;\n host::display::fill_rect(x, y, 116, 84, 0x232833);\n let d: i32 = key_digit(idx);\n if d >= 0 {\n host::display::draw_number(x + 48, y + 30, d, 0xffffff, 3);\n } else {\n host::display::draw_char(x + 48, y + 30, key_char(idx), 0xffcc33, 3);\n }\n idx = idx + 1;\n }\n\n let down: i32 = host::display::pointer_down();\n let prev: i32 = host::display::state_get(0);\n host::display::state_set(0, down);\n if down == 1 && prev == 0 {\n let px: i32 = host::display::pointer_x();\n let py: i32 = host::display::pointer_y();\n if px >= 16 && py >= 120 {\n let c: i32 = (px - 16) / 124;\n let r: i32 = (py - 120) / 92;\n if c < 4 && r < 4 {\n let k: i32 = r * 4 + c;\n let d2: i32 = key_digit(k);\n let entry: i32 = host::display::state_get(1);\n if d2 >= 0 {\n let mut e: i32 = entry;\n if host::display::state_get(4) == 1 {\n e = 0;\n host::display::state_set(4, 0);\n }\n if e < 1000000 {\n host::display::state_set(1, e * 10 + d2);\n }\n } else if k == 12 {\n host::display::state_set(1, 0);\n host::display::state_set(2, 0);\n host::display::state_set(3, 0);\n host::display::state_set(4, 0);\n } else if k == 14 {\n if host::display::state_get(3) != 0 {\n let res: i32 = apply(host::display::state_get(3), host::display::state_get(2), entry);\n host::display::state_set(2, res);\n host::display::state_set(1, res);\n host::display::state_set(3, 0);\n host::display::state_set(4, 1);\n }\n } else {\n if host::display::state_get(3) != 0 && host::display::state_get(4) == 0 {\n let res2: i32 = apply(host::display::state_get(3), host::display::state_get(2), entry);\n host::display::state_set(2, res2);\n host::display::state_set(1, res2);\n } else {\n host::display::state_set(2, entry);\n }\n host::display::state_set(3, op_of(k));\n host::display::state_set(4, 1);\n }\n }\n }\n }\n host::display::present();\n}\n",
"tags": [
"app",
"calculator",
"match"
]
}