Reputation: 26034
Given Alice's triplet and Bob's triplet (lists), I need to compare each element so if alice_triplet[i]
> bob_triplet[i]
, Alice's score is incremented by one, and vice versa.
I have this code:
def main do
alice_triplet = [5, 6, 7]
bob_triplet = [3, 6, 10]
alice_score = 0
bob_score = 0
Enum.zip(alice_triplet, bob_triplet)
|> Enum.each(fn
tuple when elem(tuple, 0) > elem(tuple, 1) -> alice_score = alice_score + 1
tuple when elem(tuple, 1) > elem(tuple, 0) -> bob_score = bob_score + 1
_ -> nil end)
IO.puts alice_score
IO.puts bob_score
end
But, the output is:
0
0
Why? I think it is about the variable scope because I'm getting this warning:
warning: variable "alice_score" is unused solution.ex:12
warning: variable "bob_score" is unused solution.ex:13
Is there a "more functional" way to do this? I'm learning Elixir (and FP in general, actually), so any advice will be appreciated.
Upvotes: 1
Views: 352
Reputation: 222090
The statement alice_score = alice_score + 1
does not modify the outer alice_score
, it creates a new local alice_score
with the value set to the outer value + 1. This has been covered in many answers. The solution almost always is to use Enum.reduce/3
with the state you need to change used as the accumulator.
Here's how that can be applied to your code:
alice_triplet = [5, 6, 7]
bob_triplet = [3, 6, 10]
{alice_score, bob_score} = Enum.zip(alice_triplet, bob_triplet) |>
Enum.reduce({0, 0}, fn
tuple, {as, bs} when elem(tuple, 0) > elem(tuple, 1) -> {as + 1, bs}
tuple, {as, bs} when elem(tuple, 1) > elem(tuple, 0) -> {as, bs + 1}
_, {as, bs} -> {as, bs}
end)
IO.puts alice_score
IO.puts bob_score
You can also simplify the code using pattern matching instead of elem/2
(elem/2
is rarely used in idiomatic Elixir code):
alice_triplet = [5, 6, 7]
bob_triplet = [3, 6, 10]
{alice_score, bob_score} = Enum.zip(alice_triplet, bob_triplet) |>
Enum.reduce({0, 0}, fn
{a, b}, {as, bs} when a > b -> {as + 1, bs}
{a, b}, {as, bs} when b > a -> {as, bs + 1}
_, {as, bs} -> {as, bs}
end)
IO.puts alice_score
IO.puts bob_score
The output in both cases is
1
1
Upvotes: 3