2015년 8월 27일 목요일

Living Clojure -- Week 1, Day 3

4Clojure 문제를 순서대로 진행하는 것이 아니라 듬성 듬성 진행한다.

37번 regular expression 문제.
(re-seq)함수는 첫번째 인자인 정규표현식으로 두번째 인자인 문자열에서 검색하여 찾은 것을 lazy sequence로 반환하는 모양이다. ***seq 인 함수들이 모두 같은 목적을 가진다고 볼 수 있겠다. (tree-seq)처럼...

어제 54번까지 풀면서  37번은 해 버렸음.


57번 단순 재귀 문제.
((fn foo [x] (when (> x 0) (conj (foo (dec x)) x))) 5) 의 결과를 물어보는데..

이 문제는 Clojure의 기초를 조금 알아야 한다.
  • (fn)폼에서도 이름(옵셔널)을 줘서 재귀함수를 작성할 수 있음 (JavaScript와 마찬가지)
  • (when)매크로는 조건을 만족하지 않을 때 nil값
  • (conj nil x)은 '(x), 즉 vector가 아닌 list. 여기서 nil은 말하자면 빈 리스트. (이부분은 앞으로도 자주 헷갈릴 것 같다. Scheme 언어들은 nil과 '()이 같다. 그런데 Clojure에서는 nli과 '()이 다르지만 conj나 into처럼 collection자리에 쓰이는 경우는 nil이 '() 의미로 사용된다.)
    • 리스트에서 (conj coll x) == (cons x coll)과 같아서 앞에 x를 붙인다.

68번 loop/recur 재귀 문제.
(loop [x 5 result []]
  (if (> x 0)
    (recur (dec x) (conj result (+ 2 x)))
    result)))

accumulator를 이용하는 일반적인 linear recursion이다.


71번 (->)
(= (__ (sort (rest (reverse [2 5 4 1 3 6]))))
   (-> [2 5 4 1 3 6] (reverse) (rest) (sort) (__))
   5)
처음엔 (sort(rest(reverse...)))의 결과를 말하라는 건줄 착각했다. 가만보니 해당 식을 (->)매크로로 바꿔쓸 수 있음을 보여주는 문제이고, 5라는 값이 나오는 함수 아무거나 넣어주면 된다.


72번 (->>)
(= (__ (map inc (take 3 (drop 2 [2 5 4 1 3 6]))))
   (->> [2 5 4 1 3 6] (drop 2) (take 3) (map inc) (__))
   11)
이번에도 11을 반환하는 아무 함수. 참, 인자는 하나 있어야 한다.  하스켈로 보자면 \_->11

reduce +를 사용할 수도 apply +를 사용할 수도 있다. (fn[_]11)


145번 (for)
(= __ (for [x (range 40)
            :when (= 1 (rem x 4))]
        x))

(for)폼의 다양한 모양을 확인해보라는 문제. 특히 세번째 코드를 만들어낸 출제자가 참 신기하다. :let, :while, :when 등이 있으나, map/filter/reduce 등의 기본에 익숙하면 그냥 이걸 쓰는게 나을지도.

(= __ (for [x (iterate #(+ 4 %) 0)
            :let [z (inc x)]
            :while (< z 40)]
        z))
(= __ (for [[x y] (partition 2 (range 20))]
        (+ x y)))


댓글 없음:

댓글 쓰기