Guest User

Untitled

a guest
Oct 16th, 2018
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.79 KB | None | 0 0
  1. ;;; hanoi.scm
  2. ;;;
  3. ;;; The function hanoi simulates solutions to Lucas's Tower of Hanoi puzzle.
  4. ;;;
  5. ;;; Written for CS 32, Fall 2005
  6. ;;; Copyright 2003, 2004, 2005 Robert R. Snapp
  7.  
  8. ;; Concise representation: The state of the Tower of Hanoi puzzle is
  9. ;; represented by a single list of integers. The first integer represents
  10. ;; the peg (1, 2, or 3) on which the smallest disk rests, the second
  11. ;; integer, the peg on which the second smallest disk rests, and so, on.
  12. ;;
  13. ;; Thus, the initial state is (1 1 ... 1), and the goal state is (3 3 ... 3).
  14. ;;
  15. (define make-list
  16. (lambda (n value)
  17. (cond ((= n 0) '())
  18. (else (cons value (make-list (- n 1) value))))))
  19.  
  20. ;; remove-all : symbol -> list
  21. ;; removes every occurence of symbol s from the list lst.
  22. ;; (This function is like anteater.)
  23. ;;
  24. ;; Examples: (remove-all 'a '(b a c a b)) -> (b c b), and
  25. ;; (remove-all 'z '(b a c a b)) -> (b a c a b).
  26. (define remove-all
  27. (lambda (s lst)
  28. (cond ((null? lst) '()); an empty list
  29. ((eq? s (car lst)) (remove-all s (cdr lst)))
  30. (else (cons (car lst) (remove-all s (cdr lst)))))))
  31.  
  32. ;; Creates an instance of the tower of Hanoi puzzle with n disks on one
  33. ;; tower, and no disks on the remaining two towers.
  34. (define initial-state
  35. (lambda (n)
  36. (make-list n 1)))
  37.  
  38. ;; (move-check? src-peg dst-peg state), where src-peg and dst-peg are
  39. ;; integers, and state is a list of integers, rturns true if the
  40. ;; smallest disk on peg src-peg can be moved to peg dst-peg, i.e., if
  41. ;; the first occurance of src-peg appears in the state list before
  42. ;; the first occurance of dst-peg. Thus
  43. ;; (move-check? 2 1 '(2 1 3 1 1 2 3)) => #t
  44. ;; as the smallest disk on peg 2 can be placed on the smallest disk
  45. ;; currently on peg 1; but,
  46. ;; (move-check? 1 2 '(2 1 3 1 1 2 3)) => #f.
  47. ;; Likewise,
  48. ;; (move-check? 1 2 '(3 3 3 3 3 3)) => #f,
  49. ;; as there aren't any disks on peg 1.
  50. (define move-check?
  51. (lambda (src-peg dst-peg state)
  52. (cond ((null? state) #f) ; There is no disk on src-peg!
  53. ((eq? (car state) src-peg) #t)
  54. ((eq? (car state) dst-peg) #f)
  55. (else (move-check? src-peg dst-peg (cdr state))))))
  56.  
  57. ;; Attempt to move the disk that is at the top of peg src-peg into the
  58. ;; top position of peg dst-peg. If the move is legal, then the new state
  59. ;; is returned. Otherwise, #f is returned.
  60. (define move-disk
  61. (lambda (src-peg dst-peg state)
  62. (cond ((null? state) #f) ; illegal move: src-peg is empty
  63. ((eq? (car state) dst-peg) #f) ; illegal-move: dst-peg contains a smaller disc.
  64. ((eq? (car state) src-peg) (cons dst-peg (cdr state))) ; perform the move and return.
  65. (else (cons (car state) (move-disk src-peg dst-peg (cdr state)))))))
  66.  
  67. ;; Applies a sequence of moves to the indicated state.
  68. (define sequential-move
  69. (lambda (move-list state)
  70. (if (null? move-list) ; Is the move-list empty?
  71. state
  72. (let* ((next-move (car move-list))
  73. (src-peg (car next-move))
  74. (dst-peg (cadr next-move))
  75. (next-state (move-disk src-peg dst-peg state)))
  76. (if next-state
  77. (begin
  78. (printf "Moving disk on peg ~a to peg ~a yields state ~a.\n"
  79. src-peg dst-peg next-state)
  80. (sequential-move (cdr move-list) next-state))
  81. (error 'sequential-move "Illegal move."))))))
  82.  
  83. ;; agent: integer integer n -> list
  84. ;; agent generates a list of legal moves in the form:
  85. ;;
  86. ;; ((src-peg1 dst-peg1) ... (src-pegn dst-pegn))
  87. ;;
  88. ;; that moves a stack of k disks from the home-peg to the target-peg.
  89. ;;
  90. ;; Example:
  91. ;; (agent 1 3 3) => ((1 3) (1 2) (3 2) (1 3) (2 1) (2 3) (1 3))
  92. ;;
  93. (define (agent home-peg target-peg n)
  94. (let ((spare-peg (car (remove-all home-peg (remove-all target-peg '(1 2 3))))))
  95. (if (<= n 0)
  96. '() ; an empyt list
  97. (append (agent home-peg spare-peg (- n 1))
  98. (list (list home-peg target-peg))
  99. (agent spare-peg target-peg (- n 1))))))
  100.  
  101.  
  102. ;; hanoi: integer -> list
  103. ;; solves and simulates the shortest solution to the tower of hanoi puzzle with n disks.
  104. ;; Since the function sequential-move is invoked, each intermediate state is displayed.
  105. ;; The final state, a list of n threes, is returned.
  106. ;;
  107. ;; Example (hanoi 3) => (3 3 3), and displays:
  108. ;;
  109. ;; Initial state = (1 1 1)
  110. ;; Moving disk on peg 1 to peg 3 yields state (3 1 1).
  111. ;; Moving disk on peg 1 to peg 2 yields state (3 2 1).
  112. ;; Moving disk on peg 3 to peg 2 yields state (2 2 1).
  113. ;; Moving disk on peg 1 to peg 3 yields state (2 2 3).
  114. ;; Moving disk on peg 2 to peg 1 yields state (1 2 3).
  115. ;; Moving disk on peg 2 to peg 3 yields state (1 3 3).
  116. ;; Moving disk on peg 1 to peg 3 yields state (3 3 3).
  117. ;;
  118.  
  119. (define (hanoi n)
  120. (let ((state (initial-state n)))
  121. (printf "Initial state = ~a\n" state)
  122. (sequential-move (agent 1 3 n) state)))
Add Comment
Please, Sign In to add comment