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