我们在课堂上为方案制作了一个矩阵库(此处的文档: http ://www.cs.indiana.edu/cgi-pub/c211/wombat/docs/c211-matrix.htm
所以作为一个小项目,我决定用矩阵做一个数独求解器。(这不是功劳,这是作为一种在测试前使用矩阵的练习而给出的)。
到目前为止,我已经大部分时间完成了该程序,我只是停留在几个最终功能上。
我想编写一个名为 check-block 的函数,它将取一个西北角行、一个西北角列和一个值,并检查该值是否可以进入该块。所以基本上是 Sudoku 3X3 盒子之一的左上角,它需要检查数字是否已经全部准备好。我在下面有一个 check-row 和 check-col 函数,它检查每个特定的行和列,看看是否有一个数字可以去那里,但它每次都从第一列或第一平方开始,不知道如何让它开始从给定的西北角。
它会像这样开始:
(define (check-block nwr nwc val))
我假设我将不得不使用某种循环来检查块的每个部分。
在此之后我想写一些叫做有效的东西?它采用行索引 r、列索引 c 和值 val 并检查是否可以将值放在给定位置。
这两个我真的很坚持,然后结束它,我知道如何将其视为算法的立场。我还需要四个函数来解决,try-row、try-cell 和 try-value。
这个想法是,solve 简单地调用 try-row 0,它从第 0 行开始填充拼图。try-row 过程假定所有先前的行都已正确填充,如果拼图没有完成,则尝试通过调用 (尝试细胞 r 0)。过程 try-cell 假定所有前面的行和左侧的列都已正确填充。如果当前行已满,则继续到下一行。如果当前单元格不为空白,则跳过它。否则,如果当前单元格为空白,则调用 (try-value rc 1) 尝试用 1 填充当前单元格。try-value 过程获取单元格的坐标和要放置在给定位置的值 v . 如果值超过 9,则过程失败,返回。如果可以放入给定值,则该过程尝试下一个值。如果可以输入给定值,则修改棋盘,然后通过尝试填充下一个单元格来继续计算。如果尝试填充下一个失败,则删除添加的值,并尝试下一个值。
所以这是我到目前为止的代码:
;This function defines an empty cell as _
(define empty #\_)
;This makes it so there are 9 rows in the matrix
(define rows 9)
;This makes it so there are 9 columns in the matrix
(define cols 9)
;This makes it soa block size is considered 3X3
(define block-size 3)
;This makes board be the matri
(define board (make-matrix rows cols empty))
;This function physically builds the matrix
(define read-puzzle
(lambda (fname)
(with-input-from-file
fname
(lambda ()
(let row-loop ([r 0])
(unless (= r rows)
(let col-loop ([c 0])
(if (= c cols)
(row-loop (add1 r))
(begin
(matrix-set! board r c (read-cell))
(col-loop (add1 c)))))))))))
;This reads what cell has what value
(define read-cell
(lambda () (let ([c (read)]) (if (eq? c '-) empty c))))
;This function checks a specific cell to see if it is blank or has a value
(define (blank? r c)
(equal? empty (matrix-ref board r c)))
;This clears the board to an empty 9x9 matrix
(define (clear-board)
(set! board (make-matrix rows cols empty)))
;This function checks if the value given can be put in that row by checking
;if that value all ready occurs in that row giving #t if it doesnt occur and
;#f if it does occur
(define (check-row r val)
(define (cr-helper r c val)
(cond
[(>= c cols) #t]
[(equal? val (matrix-ref board r c)) #f]
[else (cr-helper r (add1 c) val)]))
(cr-helper r 0 val))
;This function checks if the value given can be put in that column by checking
;if that value all ready occurs in that column giving #t if it doesnt occur and
;#f if it does occur
(define (check-col c val)
(define (cc-helper r c val)
(cond
[(>= r rows) #t]
[(equal? val (matrix-ref board r c)) #f]
[else (cc-helper (add1 r) c val)]))
(cc-helper 0 c val))