Skip to content

Instantly share code, notes, and snippets.

@tnoda
Created December 20, 2012 04:04
Show Gist options
  • Save tnoda/4342901 to your computer and use it in GitHub Desktop.
Save tnoda/4342901 to your computer and use it in GitHub Desktop.
#mitori_clj Project Euler Problem 12
(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)))
@plaster
Copy link

plaster commented Jan 3, 2013

私も解いてみて、約数の個数を求めるのを (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