기약 진분수를 커지는 순으로 늘어놓기
분모가 보다 작거나 같은 0과 1 사이의 기약 진분수의 수열을 Farey sequence라 한다. 이 수열에서 와 가 이웃이고 면, 두 수의 차는 가 되어야 한다.
의 이웃 중 가장 큰 값을 찾아야 하므로 이라 하면 다음과 같은 식을 얻을 수 있다.
따라서 의 범위에서 를 계산한 다음 의 최대값을 구하면 문제의 답을 찾을 수 있다. 모두 정수여야 하므로, 위 공식으로 구한 가 정수인 경우만 filter
로 걸러내 계산하면 된다.
(ns p071
(:require [util :refer [infix]]))
(def limit 1000000)
(defn solve []
(->> (range 2 limit) ; b
(map (fn [b] [(infix (((3 * b) - 1) / 7)) b])) ; [a b]
(filter (fn [[a b]] (integer? a))) ; a should be an int
(map (fn [[a b]] (/ a b))) ; a/b
(apply max)
numerator))
실행 결과는 다음과 같다.
p071=> (time (solve)) "Elapsed time: 155.691129 msecs" 42??70