我是 ocaml 新手。我正在尝试实现 doMove :int list -> int list -> move -> int list。
第一个参数是罐子的卷列表, 第二个 - 描述罐子当前内容的列表,以及 第三——要执行的动作。
结果是一个描述 jar 更新内容的列表。您可以假设列表的长度始终相同,没有罐子包含的水多于其体积,并且移动中的索引是有效的。
例如调用doMove[5; 2] [5; 0] (Transfer (1, 0)) 应该产生一个列表 [3; 2].
我遇到的错误是 “该表达式具有 int list 类型,但预期的表达式为类型 整数”
type move = Transfer of int * int
let rec nth lst x =
match lst with
| [] -> raise (Failure "Not Found")
| h :: t -> if x = 0 then h else nth t (x - 1)
let min x y = if x > y then y else x
let rec mapi f index list =
match list with
| [] -> []
| x :: xs ->
let result = f index x in
result :: mapi f (index + 1) xs
let fst (a, _) = a
let snd (_, b) = b
let rec doMove jar_volumes jar_content move =
let transfer_water_from_M_to_N m n jar_volumes jar_content =
let jarM_volume_index = nth jar_volumes m in
let jarN_volume_index = nth jar_volumes n in
let jarM_content_index = nth jar_content m in
let jarN_content_index = nth jar_content n in
if jarM_content_index > 0 && jarN_content_index < jarN_volume_index then
let compare_min_amount = min jarM_content_index (jarN_volume_index - jarN_content_index) in
let new_jarM_content = jarM_content_index - compare_min_amount in
let new_jarN_content = jarN_content_index + compare_min_amount in
(new_jarM_content, new_jarN_content)
else
(jarM_content_index, jarN_content_index)
in
match move with
| Transfer (m, n) ->
let updated_jar_content =
mapi (fun i content ->
if i = m then fst (transfer_water_from_M_to_N m n jar_volumes jar_content)
else if i = n then snd (transfer_water_from_M_to_N m n jar_volumes jar_content)
else content)
jar_content
in
updated_jar_content
我认为问题在于updated_jar_content。但是,我不知道如何解决它。有人可以帮我吗?非常感谢...
在 utop 中快速运行代码可确认您所看到的错误与
jar_content
有关。
这是因为您的
mapi
函数需要三个参数:函数、索引和列表。您已经给了它两个:函数和列表。由于 OCaml 函数可以部分应用,因此您可以为其提供两个参数,但参数的顺序很重要。要修复此错误,请为其提供额外的 0
参数。
match move with
| Transfer (m, n) ->
let updated_jar_content =
mapi (fun i content ->
if i = m then fst (transfer_water_from_M_to_N m n jar_volumes jar_content)
else if i = n then snd (transfer_water_from_M_to_N m n jar_volumes jar_content)
else content)
0 jar_content
in
updated_jar_content;;
现在,可以编译了,但仍然没有产生正确的结果,因此还有更多工作要做。
utop # doMove [5;2] [5;0] (Transfer (1, 0));;
- : int list = [5; 0]