patternMinor
Filtering triangles
Viewed 0 times
trianglesfilteringstackoverflow
Problem
I'm playing with Haskell's list comprehensions, tuples, and
The exercise I've given myself is to find all triangles with a perimeter of length 26 in the set of triangles whose edges range from 1 to 10 in length.
Is there a nicer way to convert a homogenous tuple to a list?
Generally, are there ways to simplify this code?
foldr.The exercise I've given myself is to find all triangles with a perimeter of length 26 in the set of triangles whose edges range from 1 to 10 in length.
main = do
print triangles
triangles = [(a,b,c) | a <- [1..10], b <- [1..10], c <- [1..10], hasPerimeterOf 26 (a,b,c)]
-- Determines whether a triangle has a perimeter of targetPerimeter
hasPerimeterOf targetPerimeter triangle = targetPerimeter == perimeter triangle
-- Calculates the perimeter of a triangle
perimeter triangle = foldr (+) 0 (toList(triangle))
-- Converts a tuple of three to a list
toList (a,b,c) = a : b : c : []Is there a nicer way to convert a homogenous tuple to a list?
Generally, are there ways to simplify this code?
Solution
The sum of length of any two sides of a triangle must be bigger then the length of the third side. Therefore there is no need to calculate
Generally, are there ways to simplify this code?
I would simply use pattern matching on the tuple in
Note that I replaced the comment with a more meaningful function name.
EDIT:
As 200_success rightfully pointed out in the comment, the
hasPerimeterOf for all combinations of a, b and c. You can simplify it by adding another filter:triangles = [(a,b,c) | a <- [1..10], b <- [1..10], c <- [1..10], c < a + b, hasPerimeterOf 26 (a,b,c)]Generally, are there ways to simplify this code?
I would simply use pattern matching on the tuple in
perimeter like this:perimeter (a,b,c) = a + b + chasPerimeterOf seems redundant here, anyway. Why not simply compare the perimeter with the desired value? It will be very readable and concise that way. The final code:main = do
print triangles
triangles = [(a,b,c) | a <- [1..10], b <- [1..10], c <- [1..10], trianglePerimeter (a,b,c) == 26]
trianglePerimeter (a,b,c) = a + b + cNote that I replaced the comment with a more meaningful function name.
EDIT:
As 200_success rightfully pointed out in the comment, the
c < a + b filter leads to awkward results, because it removes some duplicate triangles, leaving other duplicates untouched. In my opinion, if triangles (1,2,4) and (2,4,1) are the same, then the final result should contain only one triangle for each unique set of sides. Otherwise, the mentioned filter has to be removed.Code Snippets
triangles = [(a,b,c) | a <- [1..10], b <- [1..10], c <- [1..10], c < a + b, hasPerimeterOf 26 (a,b,c)]perimeter (a,b,c) = a + b + cmain = do
print triangles
triangles = [(a,b,c) | a <- [1..10], b <- [1..10], c <- [1..10], trianglePerimeter (a,b,c) == 26]
trianglePerimeter (a,b,c) = a + b + cContext
StackExchange Code Review Q#123375, answer score: 4
Revisions (0)
No revisions yet.