Neighbors (Chapter 15)

20 views
Skip to first unread message

Tom Koenig

unread,
Jun 14, 2012, 7:24:12 PM6/14/12
to land-o...@googlegroups.com
I was having trouble understanding the code for neighbors on page 314, so I worked up an alternative implementation based on a columns and row view:
(defun neighbors (pos)
  (let* ((s *board-size*) (r (truncate pos s)) (c (mod pos s))
         (r+ (1+ r)) (r- (1- r)) (c+ (1+ c)) (c- (1- c))
         (candidate-points (list (cons r- c-) (cons r- c) 
                           (cons r c-) (cons r c+) 
                           (cons r+ c) (cons r+ c+))))
     (labels ((on-grid-as-pos (point)
                 (let ((row (car point))
                       (col (cdr point)))
                    (and (>= col 0) (< col s) (>= row 0) (< row s)
                         (list (+ col (* row s)))))))
     (mapcan #'on-grid-as-pos candidate-points)))))

I have two language questions.  First,  I disliked having to use both truncate and mod to convert position to row and column, given that truncate returns both of these values.  However, I was unable to figure out how to a capture the second result within a let.  Any ideas?  Second, I dislike having to make each value returned by on-grid-as-pos be a list so I can use mapcan.  Is there another, map--- function that when applied to a list, evaluates to a list with only some of the (transformed) elements?

I'm also open to feed back on how 'lispy' this alternate implementation is.  As I say, I wrote it to be more understandable, although now that I understand the problem of finding neighbors, I find the book's implementation perfectly clear.   That version is about 25% faster, mostly because this version creates lots of lexical variables and thus causes more  GC.
Tom
Reply all
Reply to author
Forward
0 new messages