생성일: 2019년 11월 29일
수정일: 2023년 07월 28일

4clojure - Find Distinct Items (56)

  1. 문제
  2. 풀이
  3. 풀이2
    1. 풀이 분석

문제

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

(= (__ [:a :a :b :b :c :c]) [:a :b :c])

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

(= (__ (range 50)) (range 50))

풀이

(fn [coll]
  (reduce (fn [acc num] 
            (if (some true? (map #(= % num) acc)) acc
              (conj acc num))) [] coll))

순회하는 방식으로 [] 안에 값이 있으면 누적된 []를, 없으면 []안에 값을 추가하는 방식으로 문제를 해결 했다.

풀이2

다른 사람이 푼 해결책을 보면

reduce #({%2 %} ((set %) %2) (conj % %2)) []

풀이 분석

reduce 연산을 풀이하면 아래와 같다

({1 []} ((set []) 1) (conj [] 1))
;; [1]

({2 [1]} ((set [1]) 2) (conj [1] 2))
;; [1 2]

({1 [1 2]} ((set [1 2]) 1) (conj [1 2] 1))
;; [1 2]

({3 [1 2]} ((set [1 2]) 3) (conj [1 2] 3))
;; [1 2 3]

중복 되는 값은 원래의 acc로 계산된 vector를 리턴하고 없으면 (conj)로 acc에 값을 추가하는 방식으로 계산을 한다. set에 값이 있을때와 없을 때의 연산을 비교해서 본다면 아래와 같다.

;; set 안에 값이 있을 때
({1 [1 2]} ((set [1 2]) 1) (conj [1 2] 1))
;; ({1 [1 2]} 1 (conj [1 2] 1))
;; [1 2]

;; set 안에 값이 없을 때
({3 [1 2]} ((set [1 2]) 3) (conj [1 2] 3))
;; ({3 [1 2]} nil (conj [1 2] 3)) 
;; (conj [1 2] 3)
;; [1 2 3]

nil 값은 hash-map 안에 없으므로 conj 연산으로 값을 추가해 준다.

이런 방식이 실제 프로그래밍 하면서 쓰이지 않을 것 같다는 생각이 들긴 하지만 알아두면 그리고 분석을 할 줄 안다면 많은 도움이 될 것 같다.

Tags: 4clojure Today I Learn