Project Euler 091
http://projecteuler.net/problem=91
http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2091
O(0,0), P(x1,y1), Q(x2,y2) 0<=x1,y1,x2,y2<=50
三角形OPQで異なる直角三角形は何個作れるか?
次のコードは自分で書いたもの。原点Oが直角になる場合とそうでない場合に分けて数え上げた。角Qが直角となるときの点Qの座標のリストで(0,0)を落としているのがあまりきれいじゃないと思う。
-- 点Qの座標のリスト qs = drop 1 [(x,y)|x<- [0..50], y<- [0..50]] -- 点Q(x,y) /= (0,0) とが直角となるような点Pで範囲内のもの ps (x,y) = takeWhile p [(x-k*dx, y+k*dy)| k<- [1..]] ++ takeWhile p [(x+k*dx, y-k*dy)| k<- [1..]] where dx = y `quot` (gcd x y) dy = x `quot` (gcd x y) -- 点(a,b)が範囲内にあるか? p (a,b) = 0 <= a && a <= 50 && 0 <= b && b <= 50 -- 原点Oが直角になる場合とそうでない場合に分けて和をとる p091 = (+) (50*50) $ sum $ map (length.ps) qs main = print p091
次のコードはHaskellWikiのもの。直角となる点が軸上にある場合とそうでない場合に分けて数え上げている。数え上げればいい問題だからいちいち座標を計算する必要はないことがわかる。
http://www.haskell.org/haskellwiki/Euler_problems/91_to_100
reduce x y = (quot x d, quot y d) where d = gcd x y problem_91 n = 3*n*n + 2* sum others where others =[min xc yc| x1 <- [1..n], y1 <- [1..n], let (yi,xi) = reduce x1 y1, let yc = quot (n-y1) yi, let xc = quot x1 xi ]