생성일: 2019년 10월 29일
수정일: 2023년 10월 04일

4clojure - Fibonacci Sequence (26)

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

문제

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

(= (__ 6) '(1 1 2 3 5 8))

(= (__ 8) '(1 1 2 3 5 8 13 21))

풀이

(fn [x]
  (loop [li [1 1] cnt 2]
    (if (= cnt x) li
      (recur (conj li (+ (last li) (last (take (- (count li) 1) li)))) (+ cnt 1)))))

풀이 과정

피보나치 수열을 구하는 문제이다. 어떻게든 문제를 풀어보겠다고 길게 써놓은 프로그램을 보고 있자니 많은 생각이 든다. 좀 더 clojure 다운 프로그램을 만들고 싶다는 것과 좀 더 공부를 더 해야겠다는 느낌에 대해 만감이 교차 한다. 결과적으로는 문제는 해결을 했지만 여기에 만족하고 싶지는 않다.

iterate를 가지고 문제를 해결하는 방법이 있었는데 iterate라는 함수의 특성을 이용한 방식으로 해결을 하였다 그리고 단순한 값에 대한 결과값이 당연히 그렇게 되는 것이라고 생각을 했었는데 다른 차원의 해결 방식을 보고 iterate에 대한 사용법을 다시 한번 알게 되었다.

단순한 값에 대한 예제이다.

(iterate inc 5)
;; (5 6 7 8 9 10 11 12 13 14 15 ... n)

위 예제만 봤을 때는 5부터 시작해서 하나씩 증가되는 것이구나 라고 생각을 했었고 별 의심을 하지 않았다 하지만 피보나치 수열에서의 사용법을 보고 경악을 하고 말았다.

(take 3 (iterate (fn [[f s]] [s (+ f s)]) [1 1]))
;; ([1 1] [1 2] [2 3])

피보나치 수열의 결과가 나오는 과정의 일부분을 가져 왔는데 여기서 왜 s의 값이 변하는가? 에 대해서 의문을 가지고 생각을 해봤고 동작에 대해서 생각지도 못한 방식에 경악을 하고 말았고 나의 얕은 지식에 한탄 하고 말았다. 왜냐하면 처음 시작 할때 [1 1]로 시작을 하고 다음 순서에서는 [1 1]을 사용을 하는 것이 아니라 [s (+ f s)]의 값을 사용을 하는 것이 iterate의 동작이라는 것을 깨달았다. 즉 두번째 반복시 [f s]의 값은 [1 2]가 되는 것이다.

단순한 숫자 결과의 값에 대해서도 5부터 1개씩 증가하는구나라고 생각할 수도 있겠지만 항상 다음 값을 출력하기 위해서 바로 이전에 값을 사용한다는 것이 iterate의 핵심이라고 느꼈다.

보고 있자니 왠지 reduce와 동작이 비슷한 것 같다.

그걸 증명해 볼수 있는 예제를 만들어 봤다.

(take 5 (iterate identity 5))
;; (5 5 5 5 5)

identity는 어떠한 계산을 하지 않고 값 그대로를 반환하는 것인데 역시나 repeat 함수와 동작이 같았다.

문제를 푸는 것에 의의를 두지 말고 좀 더 함수의 사용법을 알 수 있도록 나의 생각과 예제를 통해서 공부하는 것이 더 잘 할 수 있는 방법이라는 것을 깨닫게 된 계기가 되었다.

Tags: 4clojure Today I Learn