Created
May 16, 2020 18:53
-
-
Save pppillai/cb4b0c0cc09c14f652d768721f705574 to your computer and use it in GitHub Desktop.
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([perimeter/1, area/1, enclose/1, bits/1, bits/2, test/0]). | |
%% compile:file(assignment1, [debug_info, export_all, {outdir, beam}]). | |
%% assignment1.erl is module and beam is dir. | |
%% Shapes | |
%% Define a function perimeter/1 which takes a shape and returns the perimeter of the shape. | |
perimeter({triangle, {A, B, C}}) -> | |
A + B + C; | |
perimeter({square, {A}}) -> | |
4 * A; | |
perimeter({rectangle, {H, W}}) -> | |
2 * (H + W); | |
perimeter({circle, R}) -> | |
2 * math:pi() * R; | |
%% Choose a suitable representation of triangles, and augment area/1 and perimeter/1 to handle this case too. | |
%% triangle = {triangle, T, {A, B, C}} | |
perimeter({triangle, T, Side}) -> | |
case T of | |
equilateral -> | |
{L} = Side, | |
3 * L; | |
isosceles -> | |
{L, B} = Side, | |
2 * L + B; | |
scalene -> | |
{L, B, W} = Side, | |
L + B + W | |
end. | |
area({triangle, T, Side}) -> | |
case T of | |
equilateral -> | |
{L} = Side, | |
S = (3 * L)/2, | |
math:sqrt(S * (S - L) * (S - L) * (S - L)); | |
isosceles -> | |
{L, B} = Side, | |
S = (L + L + B)/2, | |
math:sqrt(S * (S - L) * (S - L) * (S - B)); | |
scalene -> | |
{L, B, W} = Side, | |
S = (L + B + W)/2, | |
math:sqrt(S * (S - L) * (S - B) * (S - W)) | |
end. | |
%% Define a function enclose/1 that takes a shape and returns the smallest enclosing rectangle of the shape. | |
%% To enclose we need the point in X and Y dimension of corners or center. | |
%% | |
enclose({circle, {X, Y}, R}) -> | |
{rectangle, {X - R, Y - R}, 2 * R, 2 * R}; | |
%% Do nothing for rectangle. | |
enclose({rectangle, {X, Y}, H, W}) -> | |
{rectangle, {X, Y}, H, W}; | |
%% Find min and max of both planes | |
%% Start at min of both planes and draw height and width of diff of each plane (min, max). | |
enclose({triangle, {X, Y}, {X1, Y1}, {X2, Y2}}) -> | |
X_MIN = lists:min([X, X1, X2]), | |
X_MAX = lists:max([X, X1, X2]), | |
Y_MIN = lists:min([Y, Y1, Y2]), | |
Y_MAX = lists:max([Y, Y1, Y2]), | |
{rectangle, {X_MIN, Y_MIN}, Y_MAX - Y_MIN, X_MAX - X_MIN}. | |
%% Summing the bits | |
%% Define a function bits/1 that takes a positive integer N and returns the sum of the bits in the binary representation. For example bits(7) is 3 and bits(8) is 1. | |
% 7 = 111 | |
% bits(7) -> | |
% 00000111 band 1 + bits(00000111 bsr 1). | |
% = 1 + bits(00000011 band 1 + bits(00000011 bsr 1)) | |
% = 1 + 1 + bits(00000001 band 1 + bits(00000001 bsr 1)) | |
% = 1 + 1 + 1 + bits(0) | |
% = 3. | |
bits(0) -> | |
0; | |
bits(N) -> | |
(N band 1) + bits(N bsr 1). | |
bits(0, Result) -> | |
Result; | |
bits(N, Result) -> | |
bits(N bsr 1, N band 1 + Result). | |
%%TESTS | |
test() -> | |
?assert(perimeter({triangle, {1, 1, 1}}) == 3), | |
?assert(perimeter({square, {1}}) == 4), | |
?assert(perimeter({rectangle, {1, 2}}) == 6), | |
?assert(math:floor(perimeter({circle, 9})) == 56.0), | |
?assert(perimeter({triangle, equilateral, {1}}) == 3), | |
?assert(perimeter({triangle, isosceles, {1, 2}}) == 4), | |
?assert(perimeter({triangle, scalene, {1, 2, 3}}) == 6), | |
?assert(math:floor(area({triangle, equilateral, {3}})) == 3.0), | |
?assert(math:floor(area({triangle, isosceles, {3, 2}})) == 2.0), | |
?assert(math:floor(area({triangle, scalene, {4, 2, 3}})) == 2.0), | |
?assert(enclose({circle, {5, 5}, 5}) == {rectangle,{0,0},10,10}), | |
?assert(enclose({rectangle, {5, 5}, 5, 6}) == {rectangle,{5,5},5,6}), | |
?assert(enclose({triangle, {1, 1}, {3, 3}, {6, 6}}) == {rectangle,{1,1},5,5}), | |
?assert(bits(7) == 3), | |
?assert(bits(8, 0) == 1), | |
ok. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment