seqwithsum(Goal) ->
seqwithsum(1, 2, 3, Goal, []).
seqwithsum(Tail, Head, Sum, Goal, L) ->
if
Tail + Head > Goal ->
L;
Sum < Goal ->
% advance head
seqwithsum(Tail, Head+1, Sum+Head+1, Goal, L);
Sum > Goal ->
% advance tail
seqwithsum(Tail+1, Head, Sum-Tail, Goal, L);
true ->
% Prepend matching sequence to list and advance tail
seqwithsum(Tail+1,Head,Sum-Tail,Goal,[{Tail, Head}] ++ L)
end.
I now dislike the code I wrote because of the ugly if-construct. Now that I've read some more and experimented a little I come to the conclusion that this construct, while efficient, is not Erlangy. "If" looks like a language design after-thought. Guards simply have a better feel to them. So here we go:
seqwithsum(Goal) ->
seqwithsum(1, 2, 3, Goal, []).
seqwithsum(Tail, Head, Sum, Goal, Results) when Sum < Goal ->
% advance Head
seqwithsum(Tail, Head+1, Sum+Head+1, Goal, Results);
seqwithsum(Tail, Head, _Sum, Goal, Results) when Tail + Head > Goal ->
Results;
seqwithsum(Tail, Head, Sum, Goal, Results) when Sum > Goal ->
%advance Tail
seqwithsum(Tail+1, Head, Sum-Tail, Goal, Results);
seqwithsum(Tail, Head, Sum, Goal, Results)
seqwithsum(Tail+1, Head, Sum- Tail, Goal, [{Tail, Head} | Results]).
That's more the way things are supposed to be in Erlang. At least that's my point of view. To me, this looks more elegant than the code using the if-construct.
Be aware that the guards are evaluated in the order in which they occur in the source. Moving the code guarded by Tail + Head > Goal further down will cause an infinite loop.
No comments:
Post a Comment