Improve this function 2 =) 1 point by bOR_ 5759 days ago | 10 comments Very simple function this time, but therefore also very easy to write in a classical rather than lispy way.Given a 2 dimensional array such as made by`````` (def makeworld (x) (= world (n-of x (n-of x nil)))) (def showpos (row col) (errsafe ((world row) col))) `````` and filled with some numbers, how would you show the immediate surroundings of a number. A classical way would be to use two for loops and a bucket`````` (def observe (x y r) (let b nil (for i (* r -1) r (for j (* r -1) r (if (showpos (+ x j) (+ y i)) (= b (cons (showpos (+ x j) (+ y i)) b)) ))) b)) `````` What I've been playing with is using each, range and consif, but it still is the same structure. Any alternatives? maybe getting rid of the bucket by using accum?`````` (def observe (row col ran) (let bucket nil (each dr (range (* -1 ran) ran) (each dc (range (* -1 ran) ran) (= bucket (consif (showpos (+ row dr) (+ col dc)) bucket)))) bucket))``````
 1 point by almkglor 5759 days ago | link Assuming you want to use showpos (which is arguably slower since you have to traverse the list each time):`````` (mac w/collect body `(accum collect ,@body)) (def observe (x y r) (w/collect:for i (- x r) (+ x r) (for j (- y r) (+ y r) (awhen (showpos i j) (collect it))))) `````` If you want efficiency and still want to use list structures, you might want to skip 'showpos.-----
 1 point by bOR_ 5759 days ago | link There we go. That looks like a solution I was looking for :). and cut nicely takes care of out-of-bounds too.`` (map (fn (_) (cut _ (- row 1) (+ col 2))) (cut world (- row 1) (+ col 2)))``-----
 1 point by almkglor 5758 days ago | link `` (map [cut _ (- row r) (+ row r)] (cut world (- col r) (+ col r)))``-----
 1 point by bOR_ 5758 days ago | link From here on I adapted the function to the one I really needed (do something if one of the 8 neighbours of posx, posy is X). Because of that requirement it seemed easier to just gather the row - 1 and row + 1 and the row, col - 1 and row, col + 1, and join those in a list. This is what it ended up as:`````` (if (find X (flat:map [join (errsafe (world _))] (list (- row 1) (+ row 1) (- col 1) (+ col 1)))) ; do stuff ) `````` Thanks for the help!-----
 1 point by almkglor 5758 days ago | link `````` (flat:map [join (errsafe (world _))] (list (- row 1) (+ row 1) (- col 1) (+ col 1))) `````` This bit doesn't seem correct... world is addressed by row right? Why are you also addressing by column?-----
 1 point by tokipin 5759 days ago | link version using accum and aif`````` (def observe (row col range) (accum append (for i (- range) range (for j (- range) range (aif (showpos (+ row j) (+ col i)) (append it)))))) `````` i tried making a showpos using aand like so:`````` (def showpos (row col) (aand (world row) (it col))) `````` but it errors on out-of-bounds <_< i was hoping the errsafe was for using nil as a function-----