Problem 163
http://projecteuler.net/index.php?section=problems&id=163
三角形の数を数える簡単なお仕事。
そんなに簡単ではないが。
m = 36 layer n = tail.concat $ [map (<+>(6*n-k,k)) grid| k<-[0,6..6*n]]++[[(6*(n+1),0)]] where grid = [(4,-2),(0,3),(0,6),(2,2),(3,0),(3,3)] onLine x y = any (prallel (x <-> y)).map head.line $ x <%> 6 where prallel (a,b) (c,d) = a*d==b*c gridOnLine x = filter (not.null).map (lg x).line $ x <%> 6 where lg x = tail.takeWhile inner.scanl (<+>) x.cycle inner (x,y) = y>=0 && x+y<=6*m triangle a = [(b,c)| [l,k]<- comb 2 $ gridOnLine a,b<-l, c<-k,onLine b c] main = print.sum.map (length.triangle).((0,0):).concatMap layer $ [0..m-1] comb 0 _ = [[]] comb _ [] = [] comb (n+1) (x:xs) = map (x:) (comb n xs) ++ comb (n+1) xs (<+>) (a,b) (c,d) = (a+c,b+d) (<->) (a,b) (c,d) = (a-c,b-d) (<%>) (a,b) c = (mod a c,mod b c) line (0,0) = [[(0,3)], [(2,2),(1,1),(1,1),(2,2)], [(3,0)], [(4,-2),(2,-1),(2,-1),(4,-2)], [(3,-3)], [(2,-4),(1,-2),(1,-2),(2,-4)]] line (0,3) = [[(0,3)], [(2,-1),(4,-2),(4,-2),(2,-1)]] line (2,2) = [[(1,1),(1,1),(2,2),(2,2)], [(4,-2),(4,-2),(2,-1),(2,-1)], [(1,-2),(1,-2),(2,-4),(2,-4)]] line (3,0) = [[(3,0)], [(1,-2),(2,-4),(2,-4),(1,-2)]] line (4,4) = [[(2,2),(2,2),(1,1),(1,1)], [(2,-1),(2,-1),(4,-2),(4,-2)], [(2,-4),(2,-4),(1,-2),(1,-2)]] line (3,3) = [[(1,1),(2,2),(2,2),(1,1)], [(3,-3)]]
座標変換(正三角形を直角二等辺三角形に)して格子点の座標が整数になるようにした。
格子点の種類が割り算のあまりでわかる。
まあ、全探索ですが、計算量が良く分からないなぁ。
問題の状況では格子点は約4000個(プログラムによると)
三角形かどうかチェックした格子点の組の数は約10^7個(プログラムによると)
だから、格子点の数に関して2乗ぐらい?(根拠がないなー)