# String contains non-overlapping letter pairs

I was trying my hand at learning Elixir via ancient adventofcode puzzles and was trying to write a function to satisfy this requirement:

It contains a pair of any two letters that appears at least twice in the string without overlapping, like xyxy (xy) or aabcdefgaa (aa), but not like aaa (aa, but it overlaps).

Here is what I came up with, but it feels like it might be unwieldy. Is there a way to make it more elegant?

  def has_non_overlapping_pair(string) do
0..String.length(string)-2
|> Enum.map(fn n ->
String.slice(string, n, 2)
end)
|> Enum.reduce(["_"], fn pair, acc ->
if pair == hd(acc) do ["_"|acc]
else [pair|acc] end
end)
|> count_occurrences
|> Map.delete("_")
|> Map.values
|> Enum.any?(fn val -> val > 1 end)
end


You could use a map to store the pairs with their first occurrence while iterating over the pairs. Break if the current pair was already found at a position less than the current position minus 1.

def has_non_overlapping_pair(string) do
0..String.length(string) - 2
|> Enum.reduce_while(%{}, fn n, m ->
pair = String.slice(string, n, 2)
pos  = Map.get(m, pair, n)
cond do
pos == n     -> {:cont, Map.put(m, pair, n)}
pos == n - 1 -> {:cont, m}
true         -> {:halt, true}
end
end) == true
end