3주차만 하면 4Cloure 문제풀이는 끝난다. Code Golf 하는 재미가 있었는데, 벌써 아쉬움이 ..
Living Clojure에서 제시하는 이번주 주요 토픽은...
Living Clojure에서 제시하는 이번주 주요 토픽은...
- Control flow
- Recursion
- Data transformation
자, 3주차 1일째 시작!
(= (__ '(:a (:b nil nil) nil))
true)
(= (__ '(:a (:b nil nil)))
false)
시퀀스가 이진트리인지 확인하는 함수를 작성하는 문제. 각 노드는 nil이거나 양쪽 자식이 모두 있어야 한다.
위의 예는 :a 루트에 왼쪽 자식만 :b 가 있는 경우를 제대로 표현한 것과 그렇지 않은 것을 보여준다. 즉, root 뒤에 딱 두개의 요소만 있는지 확인하는 문제다.
(fn f[s]
(if (nil? s) true
(let [[root left right & more] (seq s)]
(if (empty? more) (and (f left) (f right))
false))))
틀린답. 두번째 if에서 sequence가 3개를 넘는지만 체크하므로 틀린 답이다. sequence에서 두번째/세번째 요소를 가져오는 방법을 binding(destructuring)으로 풀고 싶은데, 그러자면 core.match 라이브러리를 사용해야 하나보다.
아하! if-let이 있지 않을까? 있다! https://clojuredocs.org/clojure.core/if-let
(fn f[s]
(if (nil? s) true
(if-let [[root left right] (seq s)]
(and (f left) (f right))
false)))
If-let binding 패턴이 맞지 않을 때 else 브랜치를 타겠거니 했으나 그렇게 동작하지는 않는 모양이다.
;;98
(fn f[s]
(cond
(nil? s) true
(not (sequential? s)) false
(= 3 (count s)) (and (f (second s)) (f (nth s 2)))
:else false))
두번째 sequential? 체크를 빼먹어서 틀렸다가 바로잡았다. 타입을 런타임 체크로 따져줘야 한다는 점이 매우 번거롭다.
;; 72
(fn f[s]
(or
(nil? s)
(and (sequential? s) (= 3 (count s)) (f (second s)) (f (nth s 2)))))
(= (__ '(:a (:b nil nil) (:b nil nil))) true)
(= (__ '(:a (:b nil nil) nil)) false)
이진트리에서 좌우가 대칭인지 판별하는 함수를 작성하는 문제.
tree-seq로 sequence를 만들어 reverse와 같은지 볼 수 있지 않을까? 하지만 tree-seq는 부모먼저 자식 나중이다. 만약 sequence로 만들어서 풀고 싶다면 in order 로 sequence를 만들어야 한다.
(fn [t]
(let [in-order (fn f[t] (if (nil? t) [] (concat (f (second t)) (vector (first t)) (f (nth t 2)))))
s1 (in-order t)
s2 (reverse s1)]
(= s1 s2)))
in-order 로컬함수를 만들어서 구현해봤다.
;; 97
(fn [r]
(let [i (fn f[t] (if (nil? t) [] (concat (f (second t)) [(first t)] (f (nth t 2)))))
s (i r)
t (reverse s)]
(= s t)))
혹은 전체를 mirror해서 같은지 비교할 수도 있지 않을까?
;; 59
#(= % ((fn m[t]
(if (nil? t) nil
[(nth t 0) (m (nth t 2)) (m (nth t 1))])) %))
nil? 체크를 C처럼 쓸수 있는 건 다행인지 불행인지 -.-;
;; 50
#(= % ((fn m[t]
(if t
[(nth t 0) (m (nth t 2)) (m (nth t 1))])) %))
nth를 desctructuring으로 바꿀 수 있다. (if-let/when-let)
;; 43
#(= % ((fn m[t]
(if-let [[t l r] t]
[t (m r) (m l)])) %))
댓글 없음:
댓글 쓰기