OCaml数独求解实现中fold_neighbours方法问题反馈请求
OCaml数独求解代码问题修复与优化建议
现有fold_neighbours的错误点
你写的fold_neighbours无法运行和是否拆分功能无关,首先存在几个基础语法和逻辑错误:
- 变量未定义:内部使用的
neigh、v'、g'、a、f、fold_vertices均未声明,和你传入的参数完全不匹配 - 接口适配错误:你定义的
Vertex是Map模块的实例,遍历折叠应该用内置的Vertex.fold方法,不存在你调用的fold_vertices函数 - 逻辑不匹配:你定义的函数参数
gamma全程未使用,折叠逻辑的入参、返回值和实际需求完全不对应
修正后的可运行实现
我们先明确fold_neighbours的核心功能:输入目标顶点v、数独棋盘game、折叠函数f、初始累加值acc,遍历棋盘中所有v的邻居(同行、同列、同3x3宫格),执行折叠操作,实现代码如下:
(* 折叠遍历目标顶点v的所有邻居,参数依次为:目标顶点、数独棋盘、折叠函数、初始累加值 *) let fold_neighbours v game f acc = let in_quadrant (x1, y1) (x2, y2) = x1 / 3 = x2 / 3 && y1 / 3 = y2 / 3 in let is_neighbour n = (* 排除顶点自身,判断是否同行/同列/同宫格 *) n <> v && (in_quadrant v n || fst v = fst n || snd v = snd n) in (* 调用Vertex.Map自带的fold方法遍历所有顶点 *) Vertex.fold (fun n num acc' -> if is_neighbour n then f n num acc' else acc' ) game acc
使用示例:获取指定顶点的邻居已经使用的数字集合,后续图着色选可用值时可以直接调用:
module IntSet = Set.Make(Int) let get_used_nums v game = fold_neighbours v game (fun _ num s -> IntSet.add num s) IntSet.empty
优化建议
- 可以把邻居判断逻辑
is_neighbour单独拆分为独立公共函数,后续着色判断冲突时可以直接复用 - 现有读取代码可以增加输入合法性校验:比如校验读取的棋盘是否为9x9规格,避免非法输入导致后续逻辑异常
print_board可以增加分隔线输出,模拟真实数独的格子边框,可读性更高- 你当前的棋盘直接存数字,建议用0表示待填充的空白格,后续求解递归逻辑可以直接判断数字是否为0来定位待填充顶点
内容的提问来源于stack exchange,提问作者mountain
相关产品推荐
相关产品推荐

