diff --git a/haskell/Util/Triangle.hs b/haskell/Util/Triangle.hs new file mode 100644 index 0000000..17ce90c --- /dev/null +++ b/haskell/Util/Triangle.hs @@ -0,0 +1,18 @@ +module Util.Triangle where + +-- |A triangle consisting of three integral sides +data Triangle = Triangle Int Int Int + deriving(Show, Eq) + +-- |Find all right triangles having sum of sides 'sum' and side c length of 'c' +right_triangles :: Int -> Int -> [Triangle] +right_triangles sum c = do + let diff = sum - c + let range = [1..(floor ((fromIntegral diff) / 2)) + 1] + let triangles = filter is_right_triangle (map (\x -> Triangle x (diff - x) c) range) + triangles + +-- |Return whether the provided triangle is a right triangle using the pythagorean theorem +is_right_triangle :: Triangle -> Bool +is_right_triangle (Triangle a b c) = + a^2 + b^2 == c^2 diff --git a/haskell/e009.hs b/haskell/e009.hs index 7d8af99..3f01e60 100644 --- a/haskell/e009.hs +++ b/haskell/e009.hs @@ -9,9 +9,7 @@ Find the product abc. -} import Text.Printf - --- |A triangle consisting of three integral sides -data Triangle = Triangle Int Int Int +import Util.Triangle -- |Return the product of the sides of the first triangle having the sum of the sides 'sum' triplet :: Int -> Int @@ -21,18 +19,6 @@ triplet sum = do let (Triangle a b c) = tri a * b * c --- |Find all right triangles having sum of sides 'sum' and side c length of 'c' -right_triangles :: Int -> Int -> [Triangle] -right_triangles sum c = do - let diff = sum - c - let range = [1..(floor ((fromIntegral diff) / 2)) + 1] - let triangles = filter is_right_triangle (map (\x -> Triangle x (diff - x) c) range) - triangles - --- |Return whether the provided triangle is a right triangle using the pythagorean theorem -is_right_triangle :: Triangle -> Bool -is_right_triangle (Triangle a b c) = - a^2 + b^2 == c^2 main = do printf "Pythagorean triplet product having a + b + c = 1000: %d\n" (triplet 1000 :: Int) diff --git a/haskell/e039.hs b/haskell/e039.hs new file mode 100644 index 0000000..4be094a --- /dev/null +++ b/haskell/e039.hs @@ -0,0 +1,24 @@ +{- + +If p is the perimeter of a right angle triangle with integral length sides, {a,b,c}, there are exactly three solutions for p = 120. + +{20,48,52}, {24,45,51}, {30,40,50} + +For which value of p 1000, is the number of solutions maximised? +-} + +import Data.List +import Data.Ord +import Text.Printf +import Util.Triangle + +trimap = do + let totals = map (\x -> (x, (length . triangles) x)) [1..999] + last (sortBy (comparing snd) totals) + +triangles sum = do + let cs = reverse (takeWhile (<= sum - 3) [3..]) + concat (map (\x -> right_triangles sum x) cs) + +main = do + printf "Maximum triangles found with sum = %d\n" (fst trimap)