-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprob-066.clj
59 lines (47 loc) · 1.42 KB
/
prob-066.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
;;;;;;;;;; problem 066 ;;;;;;;;;;
; uses pell's equation
(use '[clojure.contrib.math :only (sqrt)]
'[clojure.contrib.def :only (defvar)]
'[clojure.contrib.seq-utils :only (flatten)])
(defn sqr [n] (* n n))
(defn conv [coll]
(loop [n (last coll), c (butlast coll)]
(if (empty? c)
n
(recur (+ (last c) (/ 1 n)) (butlast c)))))
(defn cf-notation
([x] (cf-notation x 0 1 []))
([x n d coll]
(let [m (.intValue (/ (+ (sqrt x) n) d))
a (- n (* d m))]
(cond
(and (= d 1) (not= n 0)) (conj coll m)
:else (recur x (* a -1) (quot (- x (sqr a)) d) (conj coll m))))))
(defn lazy-cf [n]
(let [cf (cf-notation n)]
(flatten (cons (first cf) (repeat (rest cf))))))
(defn numerator [r]
(bigint (first (.split (str r) "/"))))
(defn denominator [r]
(let [d (second (.split (str r) "/"))]
(if (nil? d) 1 (bigint d))))
(defn find-min [n]
(first
(for [i (iterate inc 1)
:let [cv (conv (take i (lazy-cf n)))
x (numerator cv)
y (denominator cv)]
:when (= 1 (- (sqr x) (* n (sqr y))))]
[n x y])))
(defn sqr? [n]
(let [x (sqrt n)]
(= x (.intValue x))))
(defn not-sqr? [n] (not (sqr? n)))
(defvar non-sqrs
(filter not-sqr? (iterate inc 2)))
(defn biggest-val [a b]
(if (> (second a) (second b)) a b))
(defn prob-066 []
(first
(reduce biggest-val
(map find-min (take-while #(<= % 1000) non-sqrs)))))