생성일: 2019년 12월 27일
수정일: 2023년 08월 20일

4clojure - Reimplement Trampoline (78)

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

문제

(= (letfn [(triple [x] #(sub-two (* 3 x)))
          (sub-two [x] #(stop?(- x 2)))
          (stop? [x] (if (> x 50) x #(triple x)))]
    (__ triple 2))
  82)

(= (letfn [(my-even? [x] (if (zero? x) true #(my-odd? (dec x))))
          (my-odd? [x] (if (zero? x) false #(my-even? (dec x))))]
    (map (partial __ my-even?) (range 6)))
  [true false true false true false])

제한 : trampoline

풀이

(fn [f & args] (loop [f (apply f args)] (if (fn? f) (recur (f)) f)))

풀이과정

그냥 함수 호출 하는 방법으로 해봤다

(letfn [(triple [x] #(sub-two (* 3 x)))
          (sub-two [x] #(stop?(- x 2)))
          (stop? [x] (if (> x 50) x #(triple x)))]
    ((fn [f x] (f x)) triple 2))
;; #object[user$eval136$triple__137$fn__138 0x2f05be7f "user$eval136$triple__137$fn__138@2f05be7f"]

실행할 준비가 되는 상태로만 되는 것 같다.

함수의 실행에 대한 문제가 아니라 뭔가 다른 방식에 대한 문제 인 것 같다. 간단하게 함수를 호출을 해도 그냥 정의만 되어 버린다.

(letfn [(triple [x] #(sub-two (* 3 x)))
          (sub-two [x] #(stop?(- x 2)))
          (stop? [x] (if (> x 50) x #(triple x)))]
    (triple 2))
;; #object[user$eval152$triple__153$fn__154 0x68ad99fe "user$eval152$triple__153$fn__154@68ad99fe"]

뭔가 내가 모르는 다른 방식이 더 있는 것 같다. 그걸 어떻게 찾아야 할지 고민이 된다. 왜 실행이 되지 않는지 라는 생각이 자꾸 들긴 한다.

생각하다가 도저히 답이 안나와서 다른 사람들은 어떻게 풀었는지 참고를 하기로 했다. 왜 위에 함수가 실행이 되지 않는지도 이해가 가지 않아서 정말 모르는 방법인거 같아 참고한다.

(fn [f & args] (loop [f (apply f args)] (if (fn? f) (recur (f)) f)))

문제를 잘못 이해하고 있었다 함수 내부에서 익명 함수를 사용한 것이 아니라 함수를 반환하고 있었다 그래서 위 해결 방법에서 fn?으로 반환된 결과가 함수인지를 판단하고 그 함수를 실행 시켜서 하고 있었던 것이다 결과적으로 (fn)과 같은 동작의 샆 태그인데 왜 저렇게 동작이 되는 것인지 계속 고민을 하고 있었던 것이다 위 1번테스트를 풀이 한다면 다음과 같은 흐름으로 실행이 된다

(triple 2)
;; (apply triple '(2))
;; (#(sub-two 6))
;; (apply #(stop? 4) '())
;; (#(triple 4)) 
;; (apply #(sub-two 12) '())
;; (#(stop? 10))
;; (apply #(triple 10) '())
;; (#(sub-two 30))
;; (apply #(stop? 28) '())
;; (#(triple 28)) 
;; (apply #(sub-two 84) '())
;; (#(stop? 82))
;; 82
Tags: 4clojure Today I Learn