Skip to content

Instantly share code, notes, and snippets.

@DeepSpawn
Last active February 26, 2017 07:49
Show Gist options
  • Save DeepSpawn/c8f1de5de4cd7b3b22ebefc00b4c7cca to your computer and use it in GitHub Desktop.
Save DeepSpawn/c8f1de5de4cd7b3b22ebefc00b4c7cca to your computer and use it in GitHub Desktop.
-module(assignment1).
-author("gtaylor").
%% API
-export([perimeter/1, area/1, distance/2, sides/1, toRectange/2, enclose/1, bits/1, bitsRec/1]).
% triangle tuple representation
% {triangle, {Ax,Ay}, {Bx,By}, {Cx,Cy}}
sides({triangle, A, B, C}) ->
{distance(A, B), distance(A, C), distance(B, C)}.
%%2> assignment1:sides({triangle,{0,0},{3,0},{0,5}}).
%%{3.0,5.0,4.0}
distance({X1, Y1}, {X2, Y2}) ->
math:sqrt(abs( (X2 - X1) * (X2 - X1) - (Y2 - Y1) * (Y2 - Y1))).
perimeter({circle, {_X, _Y}, R}) ->
math:pi() * 2 * R;
%%2> assignment1:perimeter({circle, {0, 0}, 0.5}).
%%3.141592653589793
perimeter({rectangle, {_X, _Y}, H, W}) ->
2 * (H + W);
%%2> assignment1:perimeter({rectangle, {0, 0}, 2, 3}).
%%10
perimeter(Tri = {triangle, {_, _}, {_, _}, {_, _}}) ->
{A, B, C} = sides(Tri),
A + B + C.
%%2> assignment1:perimeter({triangle,{0,0},{3,0},{0,5}}).
%%12.0
%from lecture
area({circle, {_X, _Y}, R}) ->
math:pi() * R * R;
%from lecture
area({rectangle, {_X, _Y}, H, W}) ->
H * W;
area(Tri = {triangle, {_, _}, {_, _}, {_, _}}) ->
%% Herons formula to calculate area
{A, B, C} = sides(Tri),
S = (A + B + C) / 2,
math:sqrt(S * (S - A) * (S - B) * (S - C)).
%%2> assignment1:area({triangle,{0,0},{3,0},{0,5}}).
%%6.0
enclose({circle, {X, Y}, R}) ->
{rectangle, {X, Y}, R, R};
%%I am assuming solutions have to be rectangles that have side that are axis aligned
%%this simplifies the problem significantly
enclose({triangle, {Ax,Ay}, {Bx,By}, {Cx,Cy}}) ->
MinCorner = {(minThree(Ax,Bx,Cx)),(minThree(Ay,By,Cy))},
MaxCorner = {maxThree(Ax,Bx,Cx), maxThree(Ay,By,Cy)},
toRectangle(MaxCorner,MinCorner);
%%2> assignment1:enclose({triangle,{0,0},{3,0},{0,5}}).
%%{rectangle,{1.5,2.5},5.0,3.0
enclose({rectangle, {X, Y}, R, R}) ->
{rectangle, {X, Y}, R, R}.
%%creates a rectangle tuple from the two diagonal points
toRectangle({Ax, Ay}, {Bx, By}) ->
Center = {(Ax + Bx) / 2, (Ay + By) / 2},
W = distance({Ax, 0}, {Bx, 0}),
H = distance({0, Ay}, {0, By}),
{rectangle, Center, H, W}.
maxThree(X,Y,Z) ->
max(max(X,Y),Z).
minThree(X,Y,Z) ->
min(min(X,Y),Z).
%%direct recursion
bitsRec(0) -> 0;
bitsRec(N) when N > 0 ->
1 + bitsRec(N band (N-1)).
%% band (binary and) returns all of the 1s shared between N and N-1 ie
%% 4 band 3
%% 100 band 010
%% = 000
%%
%% 3 band 2
%% 011 band 010
%% = 010
%%
%%tail recursive, much better as compiler can do tail call elimination - even if this come at a cost of code clarity
bits(N) ->
bits(N, 0).
bits(N, Acc) when N > 0 ->
bits(N band (N-1), Acc +1);
bits(_, Acc) ->
Acc.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment