제곱근을 연분수로 나타낼 때 반복 주기가 홀수인 경우 세기
위키피디아에 연분수로 제곱근을 구하는 방법이 자세히 설명되어 있다.
제곱근을 위와 같이 연분수로 나타냈을 때 다음 알고리즘으로 을 구할 수 있다. 은 자연수이고 완전제곱수가 아니어야 한다.
가 되면 반복이 끝난다. 이 알고리즘을 다음과 같이 Clojure 함수로 옮길 수 있다.
(defn expand-continued-fraction [n]
(let [a0 (int (Math/sqrt n))]
(loop [m 0, d 1, a a0, acc [a0]]
(if (= a (* 2 a0))
acc
(let [m (- (* d a) m), d (/ (- n (* m m)) d), a (int (/ (+ a0 m) d))]
(recur m d a (conj acc a)))))))
이제 일 때 반복주기가 홀수인 경우를 세기만 하면 된다. 은 완전제곱수이면 계산할 때 분모가 이 되는 경우가 생겨 ArithmeticException
이 발생하므로 완전제곱수는 제외하고 계산해야 한다.
(defn square [x] (* x x))
(defn solve []
(->> (range 2 (inc 10000))
(filter #(not= % (square (int (Math/sqrt %)))))
(map expand-continued-fraction)
(filter #(even? (count %)))
count))
실행 결과는 다음과 같다.
p064> (time (solve)) "Elapsed time: 135.54102 msecs" 1?22