Skip to content

Instantly share code, notes, and snippets.

@acangiano
Last active May 16, 2020 02:24
Show Gist options
  • Save acangiano/ab0a61501e11cc7503e24d9c882ebf1d to your computer and use it in GitHub Desktop.
Save acangiano/ab0a61501e11cc7503e24d9c882ebf1d to your computer and use it in GitHub Desktop.
Functional Programming in Erlang - Week 2 Assignment
-module(ex1).
-author("Antonio Cangiano").
-export([area/1, bits/1, bits_tr/1, enclose/1, perimeter/1]).
perimeter({circle, {_X, _Y}, R}) -> 2 * math:pi() * R;
perimeter({rectangle, {_X, _Y}, H, W}) -> 2 * (H + W);
perimeter({triangle, {_X1, _Y1} = A, {_X2, _Y2} = B, {_X3, _Y3} = C}) ->
AB = segment(A, B),
BC = segment(B, C),
CA = segment(C, A),
AB + BC + CA.
% Length of a segment given its two endpoints
segment({Xa, Ya}, {Xb, Yb}) ->
math:sqrt(math:pow(Xb - Xa, 2) + math:pow(Yb - Ya, 2)).
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}}) ->
% Use determinant of 3x3 matrix
abs(X1 * (Y2 - Y3) + X2 * (Y3 - Y1) + X3 * (Y1 - Y2)) / 2.
% Takes a shape and returns the smallest enclosing rectangle of the shape
enclose({circle, {X, Y}, R}) ->
{rectangle, {X - R, Y - R}, 2 * R, 2 * R};
enclose({rectangle, {_X, _Y}, _H, _W} = Rect) -> Rect;
enclose({triangle, {X1, Y1}, {X2, Y2}, {X3, Y3}}) ->
Xmin = lists:min([X1, X2, X3]),
Ymin = lists:min([Y1, Y2, Y3]),
Xmax = lists:max([X1, X2, X3]),
Ymax = lists:max([Y1, Y2, Y3]),
{rectangle, {Xmin, Ymin}, Ymax - Ymin, Xmax - Xmin}.
% Sum of the bits in the binary representation
bits(0) -> 0;
% More readable alternative: bits(N) when N > 0 -> N rem 2 + bits(N div 2).
bits(N) when N > 0 -> N band 1 + bits(N bsr 1).
% Tail recursive version
bits_tr(N) -> bits_tr(N, 0).
bits_tr(0, Acc) -> Acc;
bits_tr(N, Acc) when N > 0 ->
bits_tr(N bsr 1, Acc + N band 1).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment