Jadu
Jadu

Reputation: 709

No Output for the Elixir Program

I am trying to solve a dynamic problem finding the subsets i have written the code but i didn't know why i am not getting anything it just blinks after running Todos.sum_of_one(arr_of_digits, sum_val), I think the problem is in the terminating case when n==0, can anyone please tell me where is the mistake

def Todos do
    #find all the subsets whose sum is equal to sum_val 
    def sumofone(arr_of_digits,n,v,sum)do
      if(sum==0) do
          for i <- v do
            i 
          end
      end
      #return if n becomes 0
      if(n==0) do
        v
      end
      sumofone(arr_of_digits,n-1,v,sum)
      k = Enum.at(arr_of_digits,n-1)
      #inserting the element in the list
      [k | v] 
      sumofone(arr_of_digits,n-1,v,sum - arr_of_digits[n-1]);
    end 

    def sum_of_one(arr_of_digits, sum_val) do
      v = []
      sumofone(arr_of_digits,l,v,sum_val)
    end
  end

Upvotes: 1

Views: 120

Answers (1)

legoscia
legoscia

Reputation: 41527

It looks like you're trying to return from the function in the two if expressions. Elixir doesn't work that way - it always* runs through the entire function and returns the value of the last expression in the function.

One way to get around this is to break up the code into different function clauses, where each clause matches one of the conditions you're testing for:

    # This clause executes when the fourth argument is 0
    def sumofone(_arr_of_digits,_n,v,0) do
      for i <- v do
        i 
      end
    end

    # This clause executes when the second argument is 0
    def sumofone(_arr_of_digits,0,v,_sum) do
      v
    end

    # This clause executes in all other cases, as long as n is greater than 0
    def sumofone(arr_of_digits,n,v,sum) when n > 0 do
      sumofone(arr_of_digits,n-1,v,sum)
      k = Enum.at(arr_of_digits,n-1)
      #inserting the element in the list
      [k | v] 
      sumofone(arr_of_digits,n-1,v,sum - arr_of_digits[n-1]);
    end 

With this change, it's guaranteed that the function will actually terminate. It still won't do what you expect it to do, since there are two lines that calculate a value but throw it away. In Elixir, if you want to update the value of a variable, you need to do so explicitly. Did you mean something like this?

      sum = sumofone(arr_of_digits,n-1,v,sum)

and

      #inserting the element in the list
      v = [k | v] 

But I'll leave that for you to debug.

Note that I prefixed some of the argument names with an underscore. Without that, the compiler would give a warning about the variable being unused. With the underscore, it's clear that this is in fact intended.


* Except if you're using errors, throws and exits. But try not to use them - it's often clearer not to.

Upvotes: 1

Related Questions