2015년 9월 2일 수요일

Living Clojure -- Week 2, Day 3

갈수록 문제수가 줄어든다. 단순히 문제만 풀지 말라는 얘기인 듯..


문제 107 Simple clojures

(= [1 8 27 64] (map (__ 3) [1 2 3 4]))

Math/pow를 사용했더니 타입이 달라서 테스트가 실패한다. ClojureScript라면 될거 같다.

cljs.user=> (= 8 (.pow js/Math 2 3))
true

직접 pow를 구현하자니 안그래도 (fn)식이 다시 (fn)을 반환해야 해서 그냥 (repeat)을 이용하기로..

(fn [n] (fn [m] (reduce * (repeat n m))))

또는 partial을 이용하여

partial (fn [n m] (reduce * (repeat n m)))

그밖에,

partial (fn [n m] (reduce * (apply repeat [n m])))
partial (fn [& x] (-> apply * (apply repeat x)))
partial (fn [& x] (->> x (apply repeat) (apply *)))
..

그래도 (fn [n] #(apply * (repeat n %))) 이게 제일 간단한 듯.

(fn[n]#(int(Math/pow % n)))
partial #(int(Math/pow %2 %1))



문제 90 Cartesian Product

(= (__ #{1 2 3} #{4 5})
   #{[1 4] [2 4] [3 4] [1 5] [2 5] [3 5]})

이건, Korean Clojure User Group에서도 논의되었던 (for)의 동작을 알면 간단한 문제

(fn [as bs] (into #{} (for [a as b bs] [a b])))

#()을 사용하면

#(into #{} (for [a %1 b %2] [a b]))

into #{}를 사용할 필요도 없을 것 같다.

#(set (for [a %1 b %2] [a b]))

이건, sequence를 모나드로 보면 간단히 flatMap/map/vector다

(fn [as bs] (set (mapcat (fn[a] (map (fn[b] [a b]) bs)) as)))
(fn [as bs] (set (mapcat (fn[a] (mapcat (fn[b] (vector [a b])) bs)) as)))

(fn)이 세번이나 중첩되어서 보기 흉하다.

Haskell에서는 이미 liftM2로 추상화되어 있어서 굳이 list comprehension을 쓸 필요도 없다.

cp = liftM2 (,)





댓글 없음:

댓글 쓰기