Skip to content

Instantly share code, notes, and snippets.

@pppillai
Created May 16, 2020 18:53
Show Gist options
  • Save pppillai/cb4b0c0cc09c14f652d768721f705574 to your computer and use it in GitHub Desktop.
Save pppillai/cb4b0c0cc09c14f652d768721f705574 to your computer and use it in GitHub Desktop.
-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