You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OCAML代码精简咨询:attack与attacked函数的更短实现

简化OCaml中attack和attacked函数的方案

当然可以!咱们来一步步优化这两个函数,让代码更简洁易读,同时贴合OCaml的函数式编程风格。

原代码回顾

先把原代码贴出来方便对比:

let board = [|('a', 1); ('b', 2); ('c', 3); ('d', 4);('e', 5); ('f', 6); ('g', 7); ('h', 8)|];;
let int_of_col letter = int_of_char letter-96;;
let abs x = if x < 0 then - x else x;;
let attack (a,x)(b,y) = ((int_of_col a - int_of_col b)*(x-y)) = 0 || (abs(int_of_col a - int_of_col b) = abs(x-y));;
let attacked listing = let out = Array.make 8 false in for i=0 to 7 do for j=0 to 7 do if(i != j) then if(attack listing.(i) listing.(j)) then out.(i) <- true done done; out;;

优化1:简化attack函数

首先,咱们可以去掉单独的int_of_col函数,直接在attack里用标准库的Char.code计算列差,同时把条件拆解得更直观(同列、同行、对角线三种情况):

let attack (a, x) (b, y) =
  let col_diff = Char.code a - Char.code b in
  col_diff = 0 || x = y || abs col_diff = abs (x - y)
  • 用Char.code替代自定义的int_of_col,避免了魔法数字96,更符合OCaml惯用写法;
  • 把原代码中((col_diff)*(x-y))=0拆成col_diff=0 || x=y,逻辑更清晰,可读性更强;
  • 原代码里的自定义abs可以直接替换成OCaml标准库的Stdlib.abs,不用重复实现。

优化2:简化attacked函数

原代码用嵌套for循环修改可变数组,咱们可以用OCaml的函数式工具Array.mapi和Array.existsi来实现,避免可变状态,代码更紧凑:

let attacked queens =
  Array.mapi (fun i q ->
    Array.existsi (fun j q' -> j <> i && attack q q') queens
  ) queens
  • Array.mapi遍历数组的每个元素和对应索引,帮我们处理每个皇后的位置;
  • Array.existsi检查数组中是否存在满足条件的元素(这里是索引j不等于i,且两个皇后互相攻击);
  • 完全去掉了可变数组out的操作,符合函数式编程的无副作用原则,代码更简洁。

整合后的完整代码

把所有优化整合起来,最终代码如下:

let board = [|('a', 1); ('b', 2); ('c', 3); ('d', 4); ('e', 5); ('f', 6); ('g', 7); ('h', 8)|]

let attack (a, x) (b, y) =
  let col_diff = Char.code a - Char.code b in
  col_diff = 0 || x = y || abs col_diff = abs (x - y)

let attacked queens =
  Array.mapi (fun i q ->
    Array.existsi (fun j q' -> j <> i && attack q q') queens
  ) queens

这样代码不仅更简洁,可读性也大大提升,同时保留了原有的功能~

内容的提问来源于stack exchange,提问作者A .45 Enthusiast

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:27:55