80は、数の開平の問題です。
初めは、数値解析のやりかたでやろうと思って、やってはみたものの、時間が掛りすぎてだめ。
で、結局、一番最初に思った、筆算の開平の方法を実装して解決。
方法は、ウィキの開平法あたりを見てください。このとおりです。
・square-num?
平方数かどうか。
・num-cat
数字の連結。右側1桁前提。
12,3 -> 123
・biggest-x
開平で使う、yyyとXがあるとき、yyy? × ? が X を超えない最大の?を求める。
・extract-sqrt
numをp桁まで開平する。
・pe80
2からlimitまでの数の内、平方数以外のものを開平して、各桁の数を全部足す。
初めは、数値解析のやりかたでやろうと思って、やってはみたものの、時間が掛りすぎてだめ。
で、結局、一番最初に思った、筆算の開平の方法を実装して解決。
方法は、ウィキの開平法あたりを見てください。このとおりです。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;; Problem 80 : 2012/4/26 | |
;;"Elapsed time: 324.264961 msecs" | |
(require '[clojure.math.numeric-tower :as math]) | |
(defn square-num? [n] | |
(= (math/expt (int (Math/sqrt n)) 2) n)) | |
(defn num-cat [[u l]] | |
(+ (* u 10) l)) | |
(defn biggest-x [bring-down tgt] | |
(last (take-while #(< (second %) tgt) | |
(map #(vector % (* % (num-cat [bring-down %]))) | |
(range 0 10))))) | |
(defn extract-sqrt [num & {:keys [p] :or {p 100}}] | |
(loop [root [], | |
tgt-digit num, | |
bring-down-s 0N] | |
(let [[x n-mul] (biggest-x bring-down-s tgt-digit) | |
new-root (conj root x)] | |
(if (>= (count new-root) p) | |
new-root | |
(recur new-root | |
(* (- tgt-digit n-mul) 100) | |
(+ (num-cat [bring-down-s x]) x)))))) | |
(defn pe80 [limit] | |
(reduce + | |
(map #(reduce + (extract-sqrt %)) | |
(filter (complement square-num?) | |
(range 2 (inc limit)))))) |
・square-num?
平方数かどうか。
・num-cat
数字の連結。右側1桁前提。
12,3 -> 123
・biggest-x
開平で使う、yyyとXがあるとき、yyy? × ? が X を超えない最大の?を求める。
・extract-sqrt
numをp桁まで開平する。
・pe80
2からlimitまでの数の内、平方数以外のものを開平して、各桁の数を全部足す。
0 コメント:
コメントを投稿