[erlang-questions] Trying to learn the Erlang Way
Anthony Ramine
<>
Fri Feb 7 17:59:18 CET 2014
Hello,
Good luck with your learning.
Replied inline.
Regards,
--
Anthony Ramine
Le 7 févr. 2014 à 17:45, kraythe . <> a écrit :
> So now the fixed code is:
>
> %% Subtract the second vector from the first
> subtract({X1, Y1, Z1}, {X2, Y2, Z2}) -> {(X1 - X2), (Y1 - Y2), (Z1 - Z2)}.
The parentheses are not required here but you seem to like to use them with arithmetic, won't argue against that.
> %% Compute the magnitude of the vector
> magnitude({X, Y, Z}) -> math:sqrt((X * X) + (Y * Y) + (Z * Z)).
>
> %% Compute whether the vector with components X, Y and Z has greater magnitude then the passed scalar M.
> %% Note that this method avoids the expensive sqrt operation.
> is_magnitude_greater(M, {X, Y, Z}) when is_number(M), is_number(X), is_number(Y), is_number(Z) ->
> Msq = M * M,
> Magsq = (X * X) + (Y * Y) + (Z * Z),
> Msq > Magsq.
All the guards here are useless as M * M will crash with badarith if M isn’t a number.
> %% Determines if any coordinate in the given vector is bigger than the passed in value M
> has_coordinate_greater_than(V, {X, Y, Z}) when X > V; Y > V; Z > V -> true;
> has_coordinate_greater_than(V, Coordinate) when is_number(V), is_tuple(Coordinate) -> false.
You can make that function in one clause:
has_coordinate_greater_than(V, {X, Y, Z}) ->
X > V orelse Y > V orelse Z > V.
As an aside, your second clause would traditionally be written as:
has_coordinate_greater_than(_, {_, _, _}) -> false
or, to document better the code sometimes:
has_coordinate_greater_than(_V, {_X, _Y, _Z}) -> false
> %% Culls the list of vectors X to only those that are in the sphere devined by vector C as a center and R as a radius.
> cull(C, R, Vectors) when is_number(R), is_tuple(C), is_list(Vectors) -> cull(C, R, Vectors, []).
> cull(C, R, [], Culled) -> Culled;
> cull(C, R, [Head|Tail], Culled) ->
> D = subtract(C, Head),
> case has_coordinate_greater_than(R, Head) of
> true -> cull(C, R, Tail, Culled);
> false -> cull(C, R, D, Head, Tail, Culled)
> end.
> cull(C, R, D, Head, Tail, Culled) when is_tuple(D), is_number(R) ->
> case is_magnitude_greater(R, D) of
> true -> cull(C, R, Tail, [Head | Culled]);
> false -> cull(C, R, Tail, Culled)
> end.
Newlines are usually inserted between different functions.
In cull/6, I would pass Head last, generally new arguments are always inserted last in recursive functions to make the code more efficient and avoid moving around register values in the VM.
> Now the question is the resolution of the followup question of how to integrate this in a solution. Do we return a list of trues and falses and zip that with the objects to form a candidate list? How would you do it?
Given that your function returns a boolean per value in the given list, why does it work on a list to begin with? Why doesn’t it take just one vector?
More information about the erlang-questions
mailing list