2015년 9월 5일 토요일

Living Clojure -- Week 2, Day 5

하루 빼먹어서 곧바로 이어 진행한다. 게다가 한문제라니!!! :-)

97번 Pascal's Triangle

(= (map __ (range 1 6))
   [     [1]
        [1 1]
       [1 2 1]
      [1 3 3 1]
     [1 4 6 4 1]])

파스칼 삼각형의 n 번째 줄을 계산하는 함수를 작성하는 것이다.

n번째 줄은 n-1번째 줄에 의존적이다. pair-wise sum 양쪽 끝에 1을 추가하면 된다.

(fn f[n]
  (if (= n 1) [1]
    (let [prev (f (dec n))]
      (conj
       (into [1] (map + prev (rest prev)))
       1))))

쥐어짜기!

  • (if)의 else branch가 없으면 nil이며, nil은 올바른 sequence값이다. (빈 시퀀스)
  • 원하는 결과타입이 있다면 into가 효과적이다. 첫 인자로 타입이 결정되고 두번째 인자는 무엇이든 시퀀스가 올수 있어서 편리하다. 
  • (conj) 등은 컬렉션 타입에 의존적이다!!!

;;64
(fn f[n]
  (if (> n 0)
    (let [p (conj (f (dec n)) 0)]
      (into [1] (map + p (rest p))))))

그러나 마음같아선 이런 함수를 lazy sequence로 만들고 싶다. iterate가 제격이다.

(def pascal (iterate (fn [prev]
                       (into [1] (map + prev (rest (conj prev 0))))) []))

그러면 문제처럼 (map __ (range 1 6)) 할 것을 (take 6 parcal)처럼 만들수도 있다.
덕분에 생각지도 않게 더 줄어버렸다.

;; 55
(fn [n]
  (nth (iterate
     #(into [1] (map + % (rest (conj % 0))))
     []) n))

partial로 더 줄일 수 있다. (1글자지만 -.-)

;; 54
(partial nth (iterate
              #(into [1] (map + % (rest (conj % 0))))
              []))



댓글 없음:

댓글 쓰기