생성일: 2019년 11월 02일
수정일: 2023년 10월 15일

4clojure - Compress a Sequence (30)

  1. 문제
  2. 풀이
    1. 풀이과정

문제

(= (apply str (__ "Leeeeeerrroyyy")) "Leroy")

(= (__ [1 1 2 3 3 2 2 3]) '(1 2 3 2 3))

(= (__ [[1 2] [1 2] [3 4] [1 2]]) '([1 2] [3 4] [1 2]))

풀이


(fn [l]
  (loop [li [] li2 l]
    (cond (empty? li2) li
          (not= (last li) (first li2)) (recur (conj li (first li2)) (rest li2))
          :else (recur li (rest li2)))))

recur을 이용하여 li에 있는 마지막 값과 li2의 처음 값을 비교 하여 다르면 li에 추가하고 같으면 건너뛰는 방식으로 문제를 해결 하였다.

partition-by를 이용하는 방법도 있었는데 함수의 용도가 string 또는 collection을 순회 하면서 순서대로 같은 값 또는 같은 구조를 묶는 함수이다.

풀이과정

(partition-by identity [1 1 2])
;; ((1 1) (2))

(partition-by identity [1 2 1])
;; ((1) (2) (1))

공식 document의 예제를 변형해서 좀 더 partition-by의 용도를 확인 해봤다.

(partition-by #(> 3 %) [1 2 3 4 5])
;; ((1 2) (3 4 5))

(partition-by #(< 3 %) [1 2 3 4 5])
;; ((1 2 3) (4 5))

(partition-by #(> 3 %) [1 2 3 4 5 6 7 8 9])
;; ((1 2) (3 4 5 6 7 8 9))

(partition-by #(= 3 %) [1 2 3 4 5 6 7 8 9])
;; ((1 2) (3) (4 5 6 7 8 9))

collection 값의 갯수에 따라서 묶이는 갯수가 다르다는 것을 확인 할 수 있어서 partition-all과는 동작이 다르다는 것을 알 수 있다.

partition-by의 원형이 되는 partition에 대해서도 테스트를 해봤다.

(partition 4 (range 17))
;; ((0 1 2 3) (4 5 6 7) (8 9 10 11) (12 13 14 15))

언뜻 보기에는 partition-all과 다를바가 없어 보이는데 같은 방식으로 결과를 확인 해봤다.

(partition-all 4 (range 17))
;; ((0 1 2 3) (4 5 6 7) (8 9 10 11) (12 13 14 15) (16))

마지막 값에 대해서 차이점이 있는 것을 확인 할 수 있었다. partion는 묶는 갯수에 따라서 마지막에 그 조건을 충족하지 않으면 버리지만, partition-all은 유지를 한다는 것이 차이점이다.

Tags: 4clojure Today I Learn