생성일: 2019년 12월 24일
수정일: 2023년 08월 17일
수정일: 2023년 08월 17일
4clojure - Euler's Totient Function (75)
문제
(= (__ 1) 1)
(= (__ 10) (count '(1 3 7 9)) 4)
(= (__ 40) 16)
(= (__ 99) 60)
풀이
(fn [n]
(if (= n 1) 1
(let [gcd (fn [a b] (if (zero? b) a (recur b (mod a b))))]
(count
(conj
(filter #(= 1 %)
(map #(gcd n %)
(filter #(not= (rem n %) 0)
(range 1 n)))) 1)))))
풀이과정
일단 10에 대한 범위가 필요하므로 range 함수를 사용 하였다.
(range 10)
;; (0 1 2 3 4 5 6 7 8 9)
0은 빼도 되므로 1부터 시작하도록 했다.
(range 1 10)
;; (1 2 3 4 5 6 7 8 9)
간단하게 나머지 연산을 하여 0이 아닌 값에 대해서 필터링 하면 될것 같다.
(filter #(not= (rem 10 %) 0) (range 1 10))
;; (3 4 6 7 8 9)
근데 하고나서 생각해보니 10과 다른 수에 대한 최대 공약수가 아닌 수를 구해야한다. 최대 공약수를 어떻게 식과 조합하여 만들 수 있을지 고민을 해봐야 한다.
(fn [n]
(if (= n 1) 1
(let [gcd (fn [a b] (if (zero? b) a (recur b (mod a b))))]
(count
(conj
(filter #(= 1 %)
(map #(gcd n %)
(filter #(not= (rem n %) 0)
(range 1 n)))) 1)))))
let에 함수를 만들 수 있는 방법을 알게 되어 gcd를 만들었다. filter가 된 값들을 map으로 gcd를 하였다.,
(defn x[n]
(if (= n 1) 1
(let [gcd (fn [a b] (if (zero? b) a (recur b (mod a b))))]
(map #(gcd n %) (filter #(not= (rem n %) 0) (range 1 n))))))
user=> (x 10)
;; (1 2 2 1 2 1)
1이 되는 값들만 filter를 한다.
(defn x[n]
(if (= n 1) 1
(let [gcd (fn [a b] (if (zero? b) a (recur b (mod a b))))]
(filter #(= 1 %) (map #(gcd n %) (filter #(not= (rem n %) 0) (range 1 n)))))))
user=> (x 10)
;; (1 1 1)
갯수가 다르게 표시가 되는데..생각해보니 1이 있어야 해서 conj로 1을 추가 하였다.
(defn x[n]
(if (= n 1) 1
(let [gcd (fn [a b] (if (zero? b) a (recur b (mod a b))))]
(conj (filter #(= 1 %) (map #(gcd n %) (filter #(not= (rem n %) 0) (range 1 n)))) 1))))
user=> (x 10)
;; (1 1 1 1)
그 후 count로 값을 구했다.
(fn [n]
(if (= n 1) 1
(let [gcd (fn [a b] (if (zero? b) a (recur b (mod a b))))]
(count
(conj
(filter #(= 1 %)
(map #(gcd n %)
(filter #(not= (rem n %) 0)
(range 1 n)))) 1)))))
user=> (x 10)
;; 4
근데 생각해보니 내가 왜 나머지를 구해서 했는지 잘 모르겠다..뭔가 최대 공약수가 구해지지 않는 값들을 걸러내기 위함인데 저렇게 추가를 하다보니 1값을 넣는 코드가 추가가 되어 하지 않아도 될 계산을 하게 된 것 같다.