Home Posts Tags Post Search Tag Search

Post 42

Hacker Rank 16 - Minimum Set to Sum to N

Published on: 2025-06-21 Tags: elixir, Side Project, Hacker Rank
You are given a list of N positive integers, A = {a[1], a[2], ..., a[N]} and another integer S. You have to find whether there exists a non-empty subset of A whose sum is greater than or equal to S.

You have to print the size of minimal subset whose sum is greater than or equal to S. If there exists no such subset then print -1 instead.

input:
4
4 8 10 12
4
4
13
30
100

output:
1
2
3
-1

Okay so for this one I wanted to do a few things. First I wanted to sort the input integers to combine, and then sort the value to test against. 

I did this as the easiest way to check if there is a subset of the integers is greater than a value is to try the highest numbers and go down from there. 

Ill  go over the code now and explain the reason for the sort of the values.

    # Helper function to start the loop
    defp process_queries(targets, list, total) do
      do_process_queries(targets, list, 0, 0, total, %{})
    end
  
    # If the list is empty return the map as you have added all possible numbers
    defp do_process_queries([], _list, _sum, _count, _total, acc), do: acc
  
    # Test for when we haven't reached the target value yet.
    defp do_process_queries([target | rest], [head | tail], sum, count, total, acc) when sum < target do
      do_process_queries([target | rest], tail, sum + head, count + 1, total, acc)
    end
  
    # We know that the current number to check is okay so now we add it to the acc 
    # and we move on with the rest, the next number is set below. We will still have to check 
   # against the next value in the list but that is done in the case above
    defp do_process_queries([target | rest], list, sum, count, total, acc) when sum >= target do
      do_process_queries(rest, list, sum, count, total, Map.put(acc, target, count))
    end
  
    # This is the loop for when we get to the end of the values to check against this is done to make
    # sure that the ones that fail are set to -1
    defp do_process_queries([target | rest], [], sum, count, total, acc) do
      updated_map =
        if sum >= target do
          Map.put(acc, target, count)
        else
          Map.put(acc, target, -1)
        end
      # This is the set to be sure that we have the right order for the print
      Enum.reduce(rest, updated_map, fn t, m ->
        if t > total, do: Map.put(m, t, -1), else: m
      end)
    end

As you can see there is a lot that goes into the params for this but with this we can avoid having to do the same computations over and over again. It took making sure that both sets of lists are sorted :desc and :asc.