Created
December 20, 2012 04:04
-
-
Save tnoda/4342901 to your computer and use it in GitHub Desktop.
#mitori_clj Project Euler Problem 12
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
(ns tnoda.projecteuler.problem-12 | |
(:use [org.clojars.tnoda.math.prime :only [sieve* prime-factors *prime-array*]] | |
clojure.test)) | |
(defn- solver* | |
"Returns the value of the first triangle number to have over x divisors." | |
[x] | |
(binding [*prime-array* (sieve*)] | |
(let [triangle-numbers (reductions + (range)) | |
nd (fn number-of-divisors | |
[x] | |
(->> (prime-factors x) | |
vals | |
(map inc) | |
(apply *)))] | |
(->> triangle-numbers | |
(drop-while #(>= x (nd %))) | |
first)))) | |
(def solver (partial solver* 500)) | |
(is (= 28 (solver* 5))) |
私も解いてみて、約数の個数を求めるのを (count (filter #(zero? (mod n %)) (range 1 (inc n))))
のnaive実装でいつまでたっても実行が終わらずに、@kohyama さんの指摘どおりしばらくハマっていました。
少しかんがえて素因数分解に落ち着いて、最終的には @tnoda さんのコードとほぼ同じになりました。
tnoda/math/prime.clj 書き方や語彙が参考になります。
別の問題で作っていた素因数分解結果をシーケンスにする関数を、この問題向けにmapにするように書きなおしていたのですが、実はfrequencies
でいいのですね。覚えます。
reductions
、こういう関数ないかなあと少し探してはみたのですが、見つけられませんでした。
語彙がもっとほしいです。もしくはもっと上手く探せるようになりたいです。でも、こうやってちょっとずつ覚えていくの楽しいですね。
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
同じ意見です.理想的には言語組込みの素数列シーケンスがあってもいいかもしれないのですが,それをどのようにして提供するのかというのが,使われかたにもよるので,一つに決めきれないのが難しいところです.
with-primes
というマクロを作って,その中では,最初の一回だけsieve
して,その素数列を使い回すようにするというのを考えているのですが,どうでしょうか.(with-primes
マクロの実体は(binding [*prime-array* (sieve*)] ...)
なんですけどね.)