Skip to content

Instantly share code, notes, and snippets.

@ericnormand
Last active February 16, 2021 15:06
Show Gist options
  • Save ericnormand/93901ecca1dadf188de40626847ba933 to your computer and use it in GitHub Desktop.
Save ericnormand/93901ecca1dadf188de40626847ba933 to your computer and use it in GitHub Desktop.
412 PurelyFunctional.tv Newsletter

Land perimeter

A grid of 1s and 0s shows the location of land and water. A 1 represents a square full of land, a 0 represents a square full of water. Your job is to calculate the perimeter of the land, both as it touches water and touches the edge.

A grid with a single square filled with land has a perimeter of 4, since there are four sides:

(perimeter [[1]]) ;=> 4

Likewise, a single square filled with water has a perimeter of 0:

(perimeter [[0]]) ;=> 0

Two squares of land next to each other share an edge, which reduces the perimeter:

(perimeter [[1 1]]) ;=> 6

The edge of the grid is like an implicit encircling of water:

(perimeter [[1 1]
            [1 1]]) ;=> 8
(perimeter [[0 0 0 0]
            [0 1 1 0]
            [0 1 1 0]
            [0 0 0 0]]) ;=> 8 (same!)

Here are some other weird shapes:

(perimeter [[1 1 1 1 1 1]
            [1 0 0 0 0 1]
            [1 0 1 1 0 1]
            [1 0 0 0 0 1]
            [1 1 1 1 1 1]]) ;=> 42

(perimeter [[0 1 0 0]
            [1 1 1 0]
            [0 1 0 0]
            [1 1 0 0]]) ;=> 16

Thanks to this site for the challenge idea where it is considered Expert in JavaScript. The problem has been modified from the original.

Please submit your solutions as comments on this gist.

@RedPenguin101
Copy link

(defn all-coordinates [rows]
  (cartesian-product
   (range (count rows))
   (range (count (first rows)))))

(defn neighbours [[x y]]
  [[(dec x) y] [(inc x) y]
   [x (dec y)] [x (inc y)]])

(defn free-edges [grid coord]
  (->> (neighbours coord)
       (keep #(get-in grid %))
       (reduce +)
       (- 4)))

(defn perimeter [grid]
  (->> (all-coordinates grid)
       (remove #(zero? (get-in grid %)))
       (map #(free-edges grid %))
       (apply +)))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment