⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 queen.scm

📁 用scheme实现的八皇后
💻 SCM
字号:
;使用到的未定义的函数,属于List常用操作模式 

(define (accumulate proc initial sequence)                      ;accumlate 在List各元素上累积运算
  (if (null? sequence) 
      initial 
      (proc (car sequence) 
      (accumulate proc initial (cdr sequence))))) 

(define (flat-map proc seqs)                                    ;flat-map “放平了”,所以称flatmap
  (accumulate append () (map proc seqs))) 

 
(define (enumerate-interval low high)                           ;enumerate-interval 产生顺序递增的list
  (if (> low high) 
      '() 
      (cons low 
        (enumerate-interval (+ low 1) high)))) 

;--------------------------------------------我是分割线------------------------------------------------------------------------------------------------------

;代码部分

;legal函数用于判断皇后放在第k行是否合理
(define (legal? row arrangement)                                     
    (or (= row 1)                                                                          ;第一行无需判断 
    (null? (filter (lambda (first) (check first (car arrangement))) (cdr arrangement)))))  ; 若check函数为true则不合理


;check函数用于判断标号为place1 和 place2 的两个皇后的位置是否合理 
(define (check place1 place2)                                      
  (or(= (abs (- (car place1) (car place2))) 
      (abs (- (cadr place1) (cadr place2))))            ;是否在同一行上?
     (= (car place1) (car place2))))                    ;是否在同一列上?
 

;如果放在坐标为(x,y)是安全的 则加入结果set中
(define (join y x set)              
  (cons (list y x)set))                                    ;set中是(y x) 对应皇后的列和行 
 

;(compute chessboard)返回结果,第i个元素代表第i种结果,每个结果的第j成员代表这个结果中第j行皇后的所在列,递归地进行判断。 
(define (compute chessboard) 
  (define (computerow k)                                    ;参数k 调用时赋予初值 比如解决八皇后问题时k=8
    (if (= k 0)                                             ;若k=0 说明已经递归到最底层 有解
        (list '())                                          
        (filter (lambda (arrangement) (legal? k arrangement))   ;filter函数用于过滤所有不满足legal条件的 即不合法的放法            
         (flat-map  
          (lambda (set) 
            (map (lambda (y) (join y k set))                ;把所有k行中的每一列都加入left中     
                 (enumerate-interval 1 chessboard)))          
          (computerow (- k 1))))))                          ;递归地对k-1行进行相同处理
  (computerow chessboard)) 
 

;输出结果的编号i
(define(shownumber i)                                   
  (begin (display "No.")(display i)(display " solution:") (newline)))


;根据(car line)的值选择输出 与C中的switch语句功能一样
(define (show line)                                      
          (cond ((= (car line) 1) (begin (display "(Q * * * * * * *)") (newline))) 
                ((= (car line) 2) (begin (display "(* Q * * * * * *)") (newline))) 
                ((= (car line) 3) (begin (display "(* * Q * * * * *)") (newline))) 
                ((= (car line) 4) (begin (display "(* * * Q * * * *)") (newline))) 
                ((= (car line) 5) (begin (display "(* * * * Q * * *)") (newline))) 
                ((= (car line) 6) (begin (display "(* * * * * Q * *)") (newline))) 
                ((= (car line) 7) (begin (display "(* * * * * * Q *)") (newline))) 
                ((= (car line) 8) (begin (display "(* * * * * * * Q)") (newline))) 
                 )) 

  
;输出结果 结果中的第i个元素的值是j 表示的是皇后的坐标为(i,j)
(define(output result)                              
  (cond((null? result)  (newline))     
        ( else(show (car result))             
              (output (cdr result)))))               ;尾递归 迭代输出
 

;resultset表示结果集 通过调用output函数输出所有结果 每次取出结果集中的第一个放入firstset中进行输出
(define(outputset resultset)  
  (let((firstset (car resultset)) (leftset (cdr resultset)))
  (cond((null? resultset) (newline)(display "There are totally ")(display (- 92 (length resultset)))(display " kinds of arrangements.")) 
       (else (shownumber (- 93 (length resultset))) (output firstset) (outputset leftset)))))


;运行时只需调用queens函数即可 参数boardsize表示棋盘大小为boardsize×boardsize
(define (queens boardsize)                           
  (outputset  (compute boardsize)))   

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -