Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (defun nim-bot-play (heaps &key (misere nil))
- (let ((game-sum (reduce #'(lambda (size acc) (boole boole-xor size acc)) heaps))
- (num-heaps (length heaps)))
- (if (zerop game-sum)
- ;;If nim sum of the game is zero, then take the entire first non-empty
- ;; heap
- (loop
- for size in heaps
- for num from 1 to num-heaps
- when (> size 0)
- return `(:take ,size :from-heap ,num))
- (let ((even-or-odd-p (if misere #'oddp #'evenp))
- (heaps-bigger-than-two (loop for size in heaps count (> size 2))))
- (if (zerop heaps-bigger-than-two)
- ;; If there are no more heaps left with more than two elements
- ;; then leave an even number of heaps of size 1 for non-misere
- ;; or an odd number of heaps of size 1 for misere
- (loop
- for size in heaps
- for num from 1 to num-heaps
- when (= size 2)
- return `(:take
- ,(if (funcall even-or-odd-p
- (loop for size in heaps count (= size 1)))
- size
- (1- size))
- :from-heap ,num))
- ;; Otherwise, remove the number of elements equivilent to the
- ;; nim sum of the game from the first heap that has greater or
- ;; equal number of members to the nim sum
- (loop
- for size in heaps
- for num from 1 to num-heaps
- when (> size (boole boole-xor size game-sum))
- return `(:take ,game-sum :from-heap ,num)))))))
Add Comment
Please, Sign In to add comment