Skip to content

Instantly share code, notes, and snippets.

@jameswalton
Created May 15, 2020 12:19
Show Gist options
  • Select an option

  • Save jameswalton/df6a07c144fc1d837822c961a0b006ce to your computer and use it in GitHub Desktop.

Select an option

Save jameswalton/df6a07c144fc1d837822c961a0b006ce to your computer and use it in GitHub Desktop.
Week 2 "Pulling it all together"
-module(ex).
-export([area/1, perimeter/1, enclose/1, bits_tr/1, bits_dr/1]).
-export([test_perimeter/0, test_area/0, test_enclose/0, test_binary/0, test_all/0]).
% Ths shapes have the following patterns:
% {circle, {X, Y}, R}
% {rectangle, {X, Y}, H, W}
% {triangle, {X, Y}, A, B, C}
perimeter({circle, _, R}) -> 2 * math:pi() * R;
perimeter({rectangle, _, H, W}) -> 2 * (H + W);
perimeter({triangle, _, A, B, C}) -> A + B + C.
area({circle, _, R}) -> math:pi() * R * R;
area({rectangle, _, H, W}) -> H * W;
area({triangle, _, A, B, C}) ->
S = (A + B + C) / 2,
math:sqrt(S * (S - A) * (S - B) * (S - C)).
enclose({circle, XY, R}) ->
D = 2 * R,
{rectangle, XY, D, D};
enclose(Rectangle = {rectangle, _XY, _H, _W}) ->
Rectangle;
enclose(Triangle = {triangle, XY, A, B, C}) ->
MaxSide = max(max(A, B), C),
TriangleHeight = 2 * area(Triangle) / MaxSide,
{rectangle, XY, MaxSide, TriangleHeight}.
%% Direct recursive implementation of `bits`.
%% The accumulation happens in the second clause of the function.
bits_dr(0) -> 0;
bits_dr(N) ->
(N rem 2) + bits_dr(N div 2).
%% Tail recursive implementation of `bits`.
%% All of the arguments are passed to the next iteration of the function.
bits_tr(N) -> bits_tr(N, 0).
bits_tr(0, Sum) -> Sum;
bits_tr(N, Sum) ->
bits_tr(N div 2, Sum + N rem 2).
%% Tests for the exported functions
test_perimeter() ->
18.84955592153876 = perimeter({circle, {0, 0}, 3}),
14 = perimeter({rectangle, {0, 0}, 4, 3}),
18 = perimeter({triangle, {0, 0}, 3, 6, 9}),
ok.
test_area() ->
28.274333882308138 = area({circle, {0, 0}, 3}),
12 = area({rectangle, {0, 0}, 4, 3}),
3.897114317029974 = area({triangle, {0, 0}, 3, 3, 3}),
ok.
test_enclose() ->
{rectangle, {0,0}, 6, 6} = enclose({circle, {0, 0}, 3}),
{rectangle, {0, 0}, 4, 3} = enclose({rectangle, {0, 0}, 4, 3}),
{rectangle, {0, 0}, 3, 2.598076211353316} = enclose({triangle, {0, 0}, 3, 3, 3}),
ok.
test_binary() ->
0 = bits_dr(0),
0 = bits_tr(0),
1 = bits_dr(1),
1 = bits_tr(1),
1 = bits_dr(2),
1 = bits_tr(2),
2 = bits_dr(3),
2 = bits_tr(3),
1 = bits_dr(4),
1 = bits_tr(4),
3 = bits_dr(7),
3 = bits_tr(7),
1 = bits_dr(8),
1 = bits_tr(8),
ok.
test_all() ->
test_perimeter(),
test_area(),
test_enclose(),
test_binary().
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment