Learning idiomatic Elixir - Q1

Of course, the proper solution would be a sliding window within the original structure
The problem with Elixir is that it lacks an internal O(1) access data structure outside of tuples and to solve this one, one needs O(1) access. There are two ways I’ve found so far to solve it. Either use :queue or convert the List to tuple (given that it is fixed size and we won’t be changing the size, it should work).
I don’t know much yet of Elixir and BEAM internals, this may not be super optimal but..

defmodule CodingChallange do
  def solve_problem(arr,target_sum) do
    tarr = List.to_tuple(arr)
    size = Kernel.length(arr);
    current_sum = elem(tarr,0)
    left = 0
    right = 0
    solve(tarr,size,left,right,current_sum, target_sum)
  end


  defp solve(_,_,left,right, target_sum,target_sum) when left <= right, do: :ok
  defp solve(tarr,size,left,right, _current_sum,target_sum) when left > right do
    right = left
    current_sum = elem(tarr, left)
    solve(tarr,size,left,right, current_sum,target_sum)
  end
  defp solve(tarr,size,left,right,current_sum, target_sum) when current_sum < target_sum and right < size-1 do
    if Mix.env() != :test, do: Slog.log(["LESS CASE", tarr,size," left:",left, " right:", right, "curretn_sum:" ,current_sum, "target_sum", target_sum])
    right = right + 1
    current_sum = current_sum + elem(tarr,right)
    solve(tarr,size,left,right,current_sum, target_sum)
  end

  defp solve(tarr,size,left,right,current_sum, target_sum) when current_sum > target_sum and left <= right and left < size-1 do
    if Mix.env() != :test, do: Slog.log(["GREATER CASE", tarr,size," left:",left, " right:", right, "curretn_sum:" ,current_sum, "target_sum", target_sum])
    current_sum = current_sum - elem(tarr,left)
    left = left + 1
    solve(tarr,size,left,right,current_sum, target_sum)
  end
  defp solve(_,_,_,_, current_sum,target_sum) when current_sum != target_sum, do: nil

end

Tests:

defmodule CodingChallangeTest do
  use ExUnit.Case
  doctest CodingChallange

  test "check solution" do
    assert CodingChallange.solve_problem([1,2,3,4],6) == :ok
    assert CodingChallange.solve_problem([1,7,1,1,1,5,6,1],3) == :ok
    assert CodingChallange.solve_problem([0,4,5,1,8,9,12,3,1],7) == nil
    assert CodingChallange.solve_problem([5,3,3,3,4,100],13) == :ok
    assert CodingChallange.solve_problem([5,4,3,2,1,0,1,2,3,4,5],0) == :ok
    assert CodingChallange.solve_problem([5,4,3,2,1,1,1,2,3,4,5],0) == nil
  end
end

TBH I find the lack of proper arrays a bit frustrating. The Arrays module doesn’t explicitly state that the access time is O(1). Outside of that so far Elixir is a delight
In my line of work (and probably everybody else’s) there are like 15% of code that executes 90% of the time and performance needs to be optimal. I am at the phase where I research Elixir for the appropriate data structures to ditch Java and Akka in Elixir’s favor. Over the years I developed the habit of reading the internal implementation to make sure I won’t get tricked by assuming a one line of code would execute in linear time, but I don’t read Elixir’s code that easily yet