Elixir Equi Leader
defmodule EquiLeader do
def equi_leader(a) do
{leader_size, value} =
Enum.reduce(a, {0, nil}, fn v, {size, value} ->
cond do
size == 0 -> {1, v}
value != v -> {size - 1, value}
true -> {size + 1, value}
end
end)
count = length(a)
candidate = if leader_size > 0, do: value, else: -1
leader_count = Enum.count(a, &(&1 == candidate))
leader = if leader_count > div(count, 2), do: candidate, else: -1
{equi_leaders, _l_leader_count} =
a
|> Enum.with_index()
|> Enum.reduce({0, 0}, fn {v, k}, {equi_leaders, l_leader_count} ->
left_half = div(k + 1, 2)
right_half = div(count - k - 1, 2)
l_leader_count = if v == leader, do: l_leader_count + 1, else: l_leader_count
r_leader_count = leader_count - l_leader_count
equi_leaders =
if l_leader_count > left_half and r_leader_count > right_half do
equi_leaders + 1
else
equi_leaders
end
{equi_leaders, l_leader_count}
end)
equi_leaders
end
end
This keeps leader counts on both sides of the split and counts positions where the same leader survives in each half.