Pascal's Triangle - Remove hack

I had a thought last night on how I could easily write a Pascal's Triangle generator basically just using partition and map. I tried writing it this morning, and it got slightly more complicated than I originally thought it would, although it's still pretty nice.

My main concern is the wrap "hack" that I'm using. I found two similar, but different ways of writing it. I can either wrap the input to the iteration function in 0s, or I can wrap the result of the iteration function in 1s. Both give the same result, but the need for a wrapping helper pollutes an otherwise nice ->> chain. If anyone can think of how I can avoid a separate anonymous function here, and ideally avoid wrapping the input/output in 0s/1s, I'd appreciate it. I'll take any other critique as well, although there isn't much else going on here.

Usage:

(let [pre-t (pascals-triangle-pre) ; Wrapping pre-processing
post-t (pascals-triangle-post) ; Wrapping post-processing
n 5]
(println (take n pre-t))
(println (take n post-t)))

([1] [1 1] [1 2 1] [1 3 3 1] [1 4 6 4 1])
([1] [1 1] [1 2 1] [1 3 3 1] [1 4 6 4 1])


(ns minesweeper.irrelevant.pas-tri)

(defn pascals-triangle-post []
(let [wrap #(vec (concat [1] % [1]))]
(iterate #(->> %
(partition 2 1)
(mapv (partial apply +'))
(wrap))
[1])))

(defn pascals-triangle-pre []
(let [wrap #(vec (concat [0] % [0]))]
(iterate #(->> %
(wrap)
(partition 2 1)
(mapv (partial apply +')))
[1])))


1 Answer

There's a simpler way.

To get the next line

• take two copies of the line,
• extend them respectively with 0 at the start and with 0 at the end, and
• add the corresponding elements.

In Clojure,

(defn pascal []
(iterate
#(mapv + (cons 0 %) (conj % 0))
[1]))

=> (take 5 (pascal))
([1] [1 1] [1 2 1] [1 3 3 1] [1 4 6 4 1])


This avoids the partitioning.

Not sure if it's what you're looking for, but showing off was irresistible.

• Cool, thanks. Can't complain half a year later. – Carcigenicate Jan 23 '19 at 21:31