Last active
May 13, 2020 08:46
-
-
Save theaspect/bacf67baca9c38de6ec481b025dbc5e1 to your computer and use it in GitHub Desktop.
Functional Erlang Assignment 1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(assignment1). | |
-include_lib("eunit/include/eunit.hrl"). | |
-export([hypotenuse/2, area/1, perimeter/1, enclose/1, bits/1, bits_tail/1]). | |
% You can run test with: | |
% c(assignment1). | |
% assignment1:test(). | |
% Available shapes: | |
% {circle, {X,Y}, R} | |
% {rectangle, {X,Y}, H, W} | |
% {triangle, {X1,Y1}, {X2,Y2}, {X3,Y3}} | |
% Define a function perimeter/1 which takes a shape | |
% and returns the perimeter of the shape. | |
% Choose a suitable representation of triangles, | |
% and augment area/1 and perimeter/1 to handle this case too. | |
% Define a function enclose/1 that takes a shape | |
% and returns the smallest enclosing rectangle of the shape. | |
% Find line length by two coords | |
hypotenuse({X1,Y1}, {X2,Y2}) -> | |
math:sqrt((X2-X1)*(X2-X1) + (Y2-Y1)*(Y2-Y1)). | |
% Assignment | |
% Area of a shape | |
area({circle, {_X,_Y}, R}) -> | |
math:pi() * R*R; | |
area({rectangle, {_X,_Y}, H, W}) -> | |
H * W; | |
area({triangle, {X1,Y1}, {X2,Y2}, {X3,Y3}}) -> | |
% 2D vector cross-product, is area of parallelogram | |
abs(((X2-X1)*(Y3-Y1) - (X3-X1)*(Y2-Y1)) / 2). | |
% Perimeter of a shape | |
perimeter({circle, {_X,_Y}, R}) -> | |
2*math:pi()*R; | |
perimeter({rectangle, {_X,_Y}, H, W}) -> | |
2*H + 2*W; | |
perimeter({triangle, {X1,Y1}, {X2,Y2}, {X3,Y3}}) -> | |
hypotenuse({X1,Y1}, {X2,Y2}) + | |
hypotenuse({X1,Y1}, {X3,Y3}) + | |
hypotenuse({X2,Y2}, {X3,Y3}). | |
% Enclose rectangle of a shape | |
enclose({circle, {X,Y}, R}) -> | |
{rectangle, {X-R, Y-R}, 2*R, 2*R}; | |
enclose({rectangle, {X,Y}, H, W}) -> | |
{rectangle, {X,Y}, H, W}; | |
enclose({triangle, {X1,Y1}, {X2,Y2}, {X3,Y3}}) -> | |
X_MIN=lists:min([X1, X2, X3]), | |
X_MAX=lists:max([X1, X2, X3]), | |
Y_MIN=lists:min([Y1, Y2, Y3]), | |
Y_MAX=lists:max([Y1, Y2, Y3]), | |
% Find dimensions of enclosing rectangle and put in a left bottom coord of the triangle | |
{rectangle, {X_MIN,Y_MIN}, Y_MAX-Y_MIN, X_MAX-X_MIN}. | |
% Find sum of bits, direct recursive | |
bits(0) -> 0; | |
bits(X) -> (X band 1) + bits(X bsr 1). | |
% Find sum of bits, tail recursive | |
bits_tail(X) -> bits_tail(X, 0). | |
bits_tail(0, ACC) -> ACC; | |
bits_tail(X, ACC) -> bits_tail(X bsr 1, ACC + (X band 1)). | |
% All tests | |
hypotenuse_test() -> ?assert(hypotenuse({4,1},{1,5}) == 5). | |
area_test() -> [ | |
?assert(area({circle, {0,0}, 1}) == math:pi()), | |
?assert(area({rectangle, {0,0}, 2, 3}) == 6), | |
?assert(area({triangle, {1,5}, {4,5}, {4,1}}) == 6) | |
]. | |
perimeter_test() -> [ | |
?assert(perimeter({circle, {0,0}, 1}) == 2 * math:pi()), | |
?assert(perimeter({rectangle, {0,0}, 2, 3}) == 10), | |
?assert(perimeter({triangle, {1,5}, {4,5}, {4,1}}) == 12) | |
]. | |
enclose_test() -> [ | |
?assert(enclose({circle, {1,1}, 1}) == {rectangle, {0,0}, 2, 2}), | |
?assert(enclose({rectangle, {0,0}, 2, 3}) == {rectangle, {0,0}, 2, 3}), | |
?assert(enclose({triangle, {1,5}, {4,5}, {4,1}}) == {rectangle, {1,1}, 4, 3}) | |
]. | |
bits_test() -> [ | |
?assert(bits(7) == 3), | |
?assert(bits(8) == 1) | |
]. | |
bits_tail_test() -> [ | |
?assert(bits_tail(7) == 3), | |
?assert(bits_tail(8) == 1) | |
]. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment