Skip to content

Instantly share code, notes, and snippets.

@kylethebaker
Last active June 27, 2017 09:13
Show Gist options
  • Save kylethebaker/14a7761e32265b0537dd74a6a969fd73 to your computer and use it in GitHub Desktop.
Save kylethebaker/14a7761e32265b0537dd74a6a969fd73 to your computer and use it in GitHub Desktop.
Function Erlang Week 1 Assignment
-module(assignment1).
-export([area/1]).
-export([perimeter/1]).
-export([enclose/1]).
-export([tail_bits/1]).
-export([direct_bits/1]).
% Define shape types
% coordinate pair
-type coords() :: {integer(), integer()}.
% origin, radius
-type circle() :: {circle, coords(), integer()}.
% top-left coordinate, width, height
-type rectangle() :: {rectangle, coords(), integer(), integer()}.
% coordinate for each of the three points
-type triangle() :: {triangle, coords(), coords(), coords()}.
% a circle, rectangle, or triangle
-type shape() :: circle() | rectangle() | triangle().
% Calculates the area of a shape
% rectangle = w * h
% circle = pi * r^2
% triangle = (Ax(By-Cy) + Bx(Cy-Ay) + Cx(Ay-By)) / 2
-spec area(shape()) -> number().
area({rectangle, _, Width, Height}) -> Width * Height;
area({circle, _, Radius}) -> math:pow(Radius, 2) * math:pi();
area({triangle, {Ax, Ay}, {Bx, By}, {Cx, Cy}}) ->
A = (Ax * (By - Cy)),
B = (Bx * (Cy - Ay)),
C = (Cx * (Ay - By)),
abs((A + B + C) / 2).
% Calculates the perimeter of a shape
% rectangle = 2 * (w + h)
% circle = 2 * pi * r
% triangle = a + b + c
-spec perimeter(shape()) -> number().
perimeter({rectangle, _, Width, Height}) -> 2 * (Width + Height);
perimeter({circle, _, Radius}) -> 2 * math:pi() * Radius;
perimeter({triangle, A, B, C}) ->
AB = line_length(A, B),
BC = line_length(B, C),
CA = line_length(C, A),
AB + BC + CA.
% Given two coordinates, finds the length of the line between them
-spec line_length(coords(), coords()) -> number().
line_length({Ax, Ay}, {Bx, By}) ->
ABx = math:pow(Bx - Ax, 2),
ABy = math:pow(By - Ay, 2),
math:sqrt(ABx + ABy).
% Give a shape, find the smallest enclosing rectangle
% circle = a square wrapped around
% rectangle = simply itself
% triangle = A and B connect to form W, height of triangle is height of rect
-spec enclose(shape()) -> rectangle().
enclose({circle, {X, Y}, R}) ->
{rectangle, {X - R, Y - R}, R * 2, R * 2};
enclose(Rect = {rectangle, _, _, _}) -> Rect;
enclose(Triangle = {triangle, A, B, C}) ->
Width = line_length(A, B),
Area = area(Triangle),
Height = 2 * (Area / Width),
% top left will be A's x coord and C's y coord
{Ax, _} = A,
{_, Cy} = C,
{rectangle, {Ax, Cy}, Width, Height}.
% Sums the bits of a positive integer using tailcall recursion
-spec tail_bits(integer()) -> integer().
tail_bits(0) -> 0;
tail_bits(N) when N > 0 -> tail_bits(N, 0).
tail_bits(N, Sum) when N == 1 -> Sum + (N rem 2);
tail_bits(N, Sum) -> tail_bits(N div 2, Sum + (N rem 2)).
% Sums the bits of a positive integer using direct recursion
-spec direct_bits(integer()) -> integer().
direct_bits(0) -> 0;
direct_bits(1) -> 1;
direct_bits(N) -> direct_bits(N div 2) + N rem 2.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment