Elixir Fib Frog
defmodule FibFrog do
  def fib_frog(a) do
    size = length(a)
    jumps = size |> build_fib([1, 0]) |> Enum.reverse()
    a_map = a |> Enum.with_index() |> Map.new(fn {v, i} -> {i, v} end)

    bfs([{-1, 0}], MapSet.new(), jumps, a_map, size)
  end

  defp build_fib(size, [last | _] = acc) when last > size do
    acc |> Enum.reverse() |> Enum.drop(2)
  end

  defp build_fib(size, [a, b | _] = acc), do: build_fib(size, [a + b | acc])

  defp bfs([], _visited, _jumps, _a_map, _size), do: -1

  defp bfs([{idx, jmp} | rest], visited, jumps, a_map, size) do
    case try_jumps(jumps, idx, jmp, size, a_map, visited) do
      {:found, result} -> result
      {:continue, new_paths, visited} -> bfs(rest ++ new_paths, visited, jumps, a_map, size)
    end
  end

  defp try_jumps(jumps, idx, jmp, size, a_map, visited) do
    Enum.reduce_while(jumps, {:continue, [], visited}, fn f, {:continue, paths, visited} ->
      next_idx = idx + f

      cond do
        next_idx == size ->
          {:halt, {:found, jmp + 1}}

        next_idx > size or MapSet.member?(visited, next_idx) or Map.get(a_map, next_idx) == 0 ->
          {:cont, {:continue, paths, visited}}

        true ->
          {:cont, {:continue, paths ++ [{next_idx, jmp + 1}], MapSet.put(visited, next_idx)}}
      end
    end)
  end
end

This precomputes Fibonacci jumps, then uses a breadth-first search to find the shortest valid path across the river.