Skip to content

Instantly share code, notes, and snippets.

@michaeldperez
Created February 26, 2017 20:10
Show Gist options
  • Save michaeldperez/4269669d1ca9dbcd25584630b27b03a2 to your computer and use it in GitHub Desktop.
Save michaeldperez/4269669d1ca9dbcd25584630b27b03a2 to your computer and use it in GitHub Desktop.
shapes.erl file for Functional Programming in Erlang
-module(bits).
-export([bits/1]).
% Bits with an arity of 1 calls bits/2 with arguments Number and a preset Sum of 0.
bits(Number) ->
bits(Number, 0).
% When Number is 0, all bits have been calculated so return the sum.
% Actually, I'm taking for granted the fact that 0 rem 2 == 0 so really I'm returning Sum + 0.
bits(0, Sum) ->
Sum;
% When Number is 1, all bits have been caluclated so return the Sum
% taking into account that 1 rem 2 == 1, which requires 1 to be added to the Sum.
bits(1, Sum) ->
Sum + 1;
% When Number rem 2 == 0, Number is a multiple of 2, so divide Number by 2 and make a
% tail-recursive call to the function. Here the Sum is in reality Sum + 0.
bits(Number, Sum) when (Number rem 2) == 0 ->
bits(Number div 2, Sum);
% In this case, Number rem 2 == 1, so we add 1 to the Sum and make a tail-recursive call to
% the function with Number divided by 2 and the new Sum as arguments.
bits(Number, Sum) ->
bits(Number div 2, Sum + 1).
-module(bits_tests).
-include_lib("eunit/include/eunit.hrl").
bits_test_() ->
[?_assertEqual(0, bits:bits(0)),
?_assertEqual(1, bits:bits(1)),
?_assertEqual(1, bits:bits(2)),
?_assertEqual(2, bits:bits(3)),
?_assertEqual(1, bits:bits(4)),
?_assertEqual(2, bits:bits(5)),
?_assertEqual(2, bits:bits(6)),
?_assertEqual(3, bits:bits(7)),
?_assertEqual(1, bits:bits(8)),
?_assertEqual(2, bits:bits(9)),
?_assertEqual(2, bits:bits(10)),
?_assertEqual(3, bits:bits(11)),
?_assertEqual(2, bits:bits(12)),
?_assertEqual(3, bits:bits(13)),
?_assertEqual(3, bits:bits(14)),
?_assertEqual(4, bits:bits(15)),
?_assertEqual(1, bits:bits(16))].
-module (shapes).
-export ([area/1, perimeter/1, enclose/1]).
% Area formula for circle given in video.
area({circle, {_X, _Y}, R}) ->
math:pi() * R * R;
% Area formula for rectangle given in video.
area({rectangle, {_X, _Y}, H, W}) ->
H * W;
% Representing a triangle by it's three sides and it's height.
% Using integer division for simplicity.
area({triangle, {_X, _Y}, _Side1, _Side2, Base, Height}) ->
(Base * Height) div 2.
% Perimeter formula for circle: 2 * Pi * Radius.
perimeter({circle, {_X, _Y}, R}) ->
math:pi() * 2 * R;
% Perimeter formula for rectangle: twice the sum of it's height and width.
perimeter({rectangle, {_X, _Y}, H, W}) ->
2*(H + W);
% Perimeter formula for triangle: Sum of all sides.
perimeter({triangle, {_X, _Y}, Side1, Side2, Base, _Height}) ->
Side1 + Side2 + Base.
% Not sure but I think the smallest enclosing rectangle of a circle is a square whose sides are
% equal to the square's diameter (or 2*R).
enclose({circle, {X, Y}, R}) ->
{rectangle, {X, Y}, 2*R, 2*R};
% Not sure but I think the smallest enclosing rectangle of a rectangle is the rectangle itself.
enclose(Rect = {rectangle, {_X, _Y}, _H, _W}) ->
Rect;
% Not sure but I think the smallest enclosing rectangle of a triangle is one whose height is equal
% to the height of the triangle and whose width is equal to the base of the triangle.
enclose({triangle, {X, Y}, _Side1, _Side2, Base, Height}) ->
{rectangle, {X, Y}, Height, Base}.
-module(shapes_tests).
-include_lib("eunit/include/eunit.hrl").
% not sure of formula for enclosing rectangles
% Holding off testing.
% Also, testing float values is unclear. I had 50.27 and 25.13 as values and
% the tests failed. Had to use exact precision.
shapes_test_() ->
[area_tests(),
perimeter_tests()].
area_tests() ->
[?_assertEqual(50.26548245743669, shapes:area({circle, {0, 0}, 4})),
?_assertEqual(16, shapes:area({rectangle, {0, 0}, 4, 4})),
?_assertEqual(24, shapes:area({triangle, {0, 0}, 3, 3, 12, 4}))].
perimeter_tests() ->
[?_assertEqual(25.132741228718345, shapes:perimeter({circle, {0, 0}, 4})),
?_assertEqual(16, shapes:perimeter({rectangle, {0, 0}, 4, 4})),
?_assertEqual(25, shapes:perimeter({triangle, {0, 0}, 5, 8, 12, 10}))].
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment