nx_math_games.nx source
↩ module page · 136 lines · 5028 B
1// nx_math_games.nx -- entry-level math games + puzzles + riddles for
2// the pedagogy bridge (kindergarten -> advanced).
3//
4// Per comprehensive-proofs + bits-up-pedagogy cardinal 2026-05-14:
5// substrate must bridge entry-level beginner -> advanced math via
6// games, riddles, fun puzzles. All primitives substrate-native; no
7// Python / JavaScript / external dependencies.
8//
9// Per "no null-where-null-shouldnt-be" cardinal 2026-05-14:
10// functions that can fail return *NxResult rather than -1 sentinels.
11// Callers MUST check nx_result_is_ok before unwrapping.
12
13// nx_safety_envelope:
14// intended_use: AUTO_APPLIED -- primitive-specific tuning queued
15// sil_target: SIL1
16// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail]
17// verdict: NOT_YET_EVALUATED
18
19import "nx_syscalls.nx"
20import "nx_runtime.nx"
21import "nx_tier.nx"
22import "nx_classical_unpatented.nx"
23import "nx_classical_unpatented_2.nx"
24import "nx_result.nx"
25
26// ===== Game 1: Guess the Number (binary-search teacher) ===============
27// Returns sealed status: cannot fail (any int comparison is well-defined).
28const NX_GAME_GUESS_LOW: nx_int = -1
29const NX_GAME_GUESS_HIGH: nx_int = 1
30const NX_GAME_GUESS_CORRECT: nx_int = 0
31
32func nx_game_guess_check(secret: nx_int, guess: nx_int) -> nx_int {
33 if guess < secret { return NX_GAME_GUESS_LOW }
34 if guess > secret { return NX_GAME_GUESS_HIGH }
35 return NX_GAME_GUESS_CORRECT
36}
37
38// ===== Game 2: Parity =================================================
39const NX_GAME_PARITY_EVEN: nx_int = 0
40const NX_GAME_PARITY_ODD: nx_int = 1
41
42func nx_game_parity(n: nx_int) -> nx_int {
43 if (n % 2) == 0 { return NX_GAME_PARITY_EVEN }
44 return NX_GAME_PARITY_ODD
45}
46
47// ===== Game 3: Find a Factor (Result-typed) ===========================
48// Returns Result<nx_int, NX_ERR_OUT_OF_RANGE> for n < 2 (no factor
49// concept defined for those inputs).
50func nx_game_find_factor(n: nx_int) -> *NxResult {
51 if n < 2 { return nx_result_err(NX_ERR_OUT_OF_RANGE) }
52 var d: nx_int = 2
53 while d * d <= n {
54 if (n % d) == 0 { return nx_result_ok(d) }
55 d = d + 1
56 }
57 return nx_result_ok(n)
58}
59
60// ===== Game 4: Pattern Next (Result-typed) ============================
61const NX_GAME_PATTERN_ARITH: nx_int = 1
62const NX_GAME_PATTERN_GEOM: nx_int = 2
63const NX_GAME_PATTERN_NONE: nx_int = 0
64
65func nx_game_pattern_kind(a: nx_int, b: nx_int, c: nx_int) -> nx_int {
66 if (b - a) == (c - b) { return NX_GAME_PATTERN_ARITH }
67 if a != 0 {
68 if (b * b) == (a * c) { return NX_GAME_PATTERN_GEOM }
69 }
70 return NX_GAME_PATTERN_NONE
71}
72
73// Returns Result. Err on pattern=NONE (no extrapolation defined).
74func nx_game_pattern_next(a: nx_int, b: nx_int, c: nx_int) -> *NxResult {
75 let kind: nx_int = nx_game_pattern_kind(a, b, c)
76 if kind == NX_GAME_PATTERN_ARITH { return nx_result_ok(c + (b - a)) }
77 if kind == NX_GAME_PATTERN_GEOM {
78 if b == 0 { return nx_result_err(NX_ERR_DIVIDE_BY_ZERO) }
79 return nx_result_ok((c * b) / a)
80 }
81 return nx_result_err(NX_ERR_INVALID_INPUT)
82}
83
84// ===== Riddle 1: Pigeonhole (Result-typed) ============================
85func nx_riddle_pigeonhole(n_pigeons: nx_int, n_holes: nx_int) -> *NxResult {
86 if n_holes <= 0 { return nx_result_err(NX_ERR_DIVIDE_BY_ZERO) }
87 if n_pigeons < 0 { return nx_result_err(NX_ERR_INVALID_INPUT) }
88 return nx_result_ok((n_pigeons + n_holes - 1) / n_holes)
89}
90
91// ===== Riddle 2: Triangle Number (Result-typed) ======================
92func nx_riddle_triangle_n(n: nx_int) -> *NxResult {
93 if n < 0 { return nx_result_err(NX_ERR_OUT_OF_RANGE) }
94 return nx_result_ok((n * (n + 1)) / 2)
95}
96
97// ===== Riddle 3: Hanoi (Result-typed) ================================
98func nx_riddle_hanoi_moves(n: nx_int) -> *NxResult {
99 if n < 0 { return nx_result_err(NX_ERR_OUT_OF_RANGE) }
100 var r: nx_int = 1
101 var i: nx_int = 0
102 while i < n { r = r * 2; i = i + 1 }
103 return nx_result_ok(r - 1)
104}
105
106// ===== Riddle 4: Coin Flips (Result-typed) ===========================
107func nx_riddle_coin_flip_outcomes(n: nx_int) -> *NxResult {
108 if n < 0 { return nx_result_err(NX_ERR_OUT_OF_RANGE) }
109 var r: nx_int = 1
110 var i: nx_int = 0
111 while i < n { r = r * 2; i = i + 1 }
112 return nx_result_ok(r)
113}
114
115// ===== Puzzle 1: Caesar cipher shift =================================
116// No invalid-input errors; out-of-range chars pass through unchanged.
117func nx_puzzle_caesar_decrypt(c: nx_int, k: nx_int) -> nx_int {
118 if c < 97 { return c }
119 if c > 122 { return c }
120 var d: nx_int = c - 97 - k
121 while d < 0 { d = d + 26 }
122 d = d % 26
123 return d + 97
124}
125
126// ===== Puzzle 2: Magic Square 3x3 sum check ==========================
127// Predicate; returns 0/1 sealed.
128func nx_puzzle_magic_3x3_check(a: nx_int, b: nx_int, c: nx_int) -> nx_int {
129 if (a + b + c) == 15 { return 1 }
130 return 0
131}
132
133// ===== Puzzle 3: Fibonacci bridge ====================================
134func nx_puzzle_fib(n: nx_int) -> nx_int {
135 return nx_fibonacci(n)
136}