【问题标题】:Random answers when dealing with lists in OCaml处理 OCaml 中的列表时的随机答案
【发布时间】:2013-10-21 01:55:37
【问题描述】:

我正在尝试制作一个函数来获取生命游戏中活细胞的数量。 目标是查看一个 int list 列表,并在给定单元格坐标的情况下,返回它旁边的存活单元格的数量。
问题是我的函数似乎完全随机回答,我看不出是什么在代码中导致此问题
这是一个班级作业,所以我不要求一个具体的答案,只是提示问题可能出在哪里

这是我的代码:

(* nth : reimplementation of List.nth that returns 0 if there is no such
 * element
 * [int list -> int -> int] *)

 let rec nth l n =
    match l with
        | [] -> 0
        | a::l -> if n = 0 
            then a 
            else nth l (n-1);;

(* get_cell : given a couple of coordinates, returns the value at the
 * coordinates on the matrix 
 * [int * int -> int list list -> int] *)

let rec get_cell (x,y) matrix = 
    match (List.nth matrix y) with
        | [] -> empty
        | l  -> nth l x;;

(* count_neighbours : given a couple of coordinates and a matrix, returns the 
 * number of alive cells in the neighborhood of the designed cell 
 * [int * int -> int list list -> int] *)

let count_neighbours (x,y) matrix =
    let neighbors = [ (x-1,y-1); (x-1,y); (x-1,y+1); 
                      (x,y-1); (x,y+1);
                      (x+1,y-1); (x+1,y); (x+1,y+1); ] in
    let rec aux = (function 
        | [] -> 0
        | h::t -> (get_cell h matrix) + aux (t)
    ) in
    aux neighbors;;

这是一个示例会话:

# let test_board = [[0; 1; 1; 1; 1]; [1; 0; 0; 0; 0]; [1; 0; 1; 0; 0]; [0; 1; 0; 0; 0];
   [0; 1; 1; 0; 1]];;
val test_board : int list list =
  [[0; 1; 1; 1; 1]; [1; 0; 0; 0; 0]; [1; 0; 1; 0; 0]; [0; 1; 0; 0; 0];
   [0; 1; 1; 0; 1]]
# count_neighbours (3,3) test_board;;
- : int = 3
# get_cell (2,2) test_board;;
- : int = 1
# get_cell (2,3) test_board;;
- : int = 0
# get_cell (2,4) test_board;;
- : int = 1
# get_cell (3,2) test_board;;
- : int = 0
# get_cell (3,4) test_board;;
- : int = 0
# get_cell (4,2) test_board;;
- : int = 0
# get_cell (4,3) test_board;;
- : int = 0
# get_cell (4,4) test_board;;
- : int = 1

如您所见,随机结果... 感谢您的帮助。

【问题讨论】:

    标签: list recursion ocaml


    【解决方案1】:

    据我了解,它不是完全随机,除非您指定随机性。 :-)

    我很确定使用正确的坐标来获取您的单元格只是一件小事。既然你提到这是一项家庭作业,我只会指出你要找到解决方案,而不是马上解决。

    List.nth test_board x 给了你什么? x 是您在上面输入的任何数字。

    在做了一些小的调整后,我给了我这个结果:

    # get_cell (2,4) test_board;;
    - : int = 0
    # count_neighbours (3,3) test_board;;
    - : int = 3
    

    祝你好运。

    编辑 至于count_neighbours 的实现,如果您将其视为如下所示的列表列表,将会有所帮助。

    拿你的test_board,oCaml 编译器看起来像这样:

        0  1  2  3  4
    0  [0; 1; 1; 1; 1];
    1  [1; 0; 0; 0; 0]; 
    2  [1; 0; 1; 0; 0]; 
    3  [0; 1; 0; **0**; 0];
    4  [0; 1; 1; 0; 1];
    

    我已突出显示与(3, 3) 对应的单元格。那里显示了三个1s - 左上角、左下角和右下角。

    【讨论】:

    • 感谢您的意见,但我很困惑:# count_neighbours (3,3) test_board;; 不应该返回 - : int = 3,而是应该返回 - : int = 1,如果我没记错的话。
    • 那是因为沿着单元格(3,3)的对角线有3个1s。查看count_neighbours 的实现以及如何构建neighours 列表。所以,一旦你得到所有的1s,你只是把它们加起来。
    • 我知道这一点,但我似乎找不到这三个1s。对角线由000 010 100 组成,如果我错了请纠正我,但看起来我们看的不是同一个对角线......
    • 查看我的编辑。在(x, y) - x 代表行,y 代表列。也就是说,在您的实现中,您可能还应该检查列表边界,以免意外查找不在列表范围内的元素。
    • 好吧,我没明白列表是从 0 开始编号的 :) 感谢您的帮助!
    猜你喜欢
    • 2019-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多