数の各桁の数を二乗した和を並べた数が89でループする場合を数える問題です。
操作からすると、345と435と543などの同じ構成の数は同じ結果になるので、それをうまく使えばメモ化で速くなりそうなので、やってみた。
数を数列にしてソートする。0はなくても同じなので除外する。そうしてできた数列で判定する関数を作ってメモ化する。
解けたんだけど、遅い。
ふと、元の数をつくるのにどれくらいかかるか計算してみたら、それだけで2分近くかかってる。こりゃだめだ。 どうしよう。
操作からすると、345と435と543などの同じ構成の数は同じ結果になるので、それをうまく使えばメモ化で速くなりそうなので、やってみた。
数を数列にしてソートする。0はなくても同じなので除外する。そうしてできた数列で判定する関数を作ってメモ化する。
解けたんだけど、遅い。
ふと、元の数をつくるのにどれくらいかかるか計算してみたら、それだけで2分近くかかってる。こりゃだめだ。 どうしよう。
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 92 | |
;; "Elapsed time: 160349.067511 msecs" | |
(defn num-to-list [n] | |
(if (zero? n) | |
[] | |
(conj (num-to-list (quot n 10)) (rem n 10)))) | |
(defn get-digits [n] | |
(sort (filter #(not= 0 %) (num-to-list n)))) | |
(defn add-square [s] | |
(reduce + (map #(* % %) s))) | |
(defn-memo end-with-89? [digit-list] | |
(cond (= digit-list [8 9]) true | |
(= digit-list [1]) false | |
:t (end-with-89? (get-digits (add-square digit-list))))) | |
(count (filter true? (map end-with-89? (map get-digits (range 1 10000000))))) | |
;;user> (time (count (map get-digits (range 1 10000000)))) | |
;;"Elapsed time: 118325.744157 msecs" |
0 コメント:
コメントを投稿