|
| 1 | +defmodule HackerRank.W1.DivisibleSumPairs do |
| 2 | + @moduledoc """ |
| 3 | + Divisible Sum Pairs - Challenge 6, Week 1. |
| 4 | + <https://www.hackerrank.com/challenges/three-month-preparation-kit-divisible-sum-pairs/problem> |
| 5 | + """ |
| 6 | + |
| 7 | + @doc """ |
| 8 | + Count the number of (i, j) index pairs such that i < j and the sum of arr[i] + arr[j] is divisible by a given integer k. |
| 9 | +
|
| 10 | + ## Parameters |
| 11 | +
|
| 12 | + - _n (integer): The count of items in the supplied array (unused) |
| 13 | + - k (integer): the integer to be used as the divisor |
| 14 | + - ar (list[integers]): the array of integers to work on |
| 15 | +
|
| 16 | + Returns: |
| 17 | + - integer: the number of pairs that are divisible by k |
| 18 | +
|
| 19 | + Example: |
| 20 | + iex> DivisibleSumPairs.challenge(6, 5, [1, 3, 2, 6, 1, 2]) |
| 21 | + 2 |
| 22 | + """ |
| 23 | + |
| 24 | + @spec challenge(integer(), integer(), list(integer())) :: integer() |
| 25 | + def challenge(_n, k, arr) do |
| 26 | + # This is a recursy' thing |
| 27 | + count_pairs(k, arr, %{}, 0) |
| 28 | + end |
| 29 | + |
| 30 | + # Tail recursive |
| 31 | + defp count_pairs(_k, [],_fmap, count), do: count |
| 32 | + defp count_pairs(k, arr, fmap, count) do |
| 33 | + # get the value |
| 34 | + [value | rest] = arr |
| 35 | + |
| 36 | + # get the mod |
| 37 | + mod = rem(value, k) |
| 38 | + |
| 39 | + # get the complement or zero if mod is zero |
| 40 | + comp = if mod == 0, do: 0, else: k - mod |
| 41 | + |
| 42 | + # increment count by the frequency of the complement |
| 43 | + count = |
| 44 | + case Map.get(fmap, comp) do |
| 45 | + nil -> count |
| 46 | + hit -> count + hit |
| 47 | + end |
| 48 | + |
| 49 | + # update the frequency map |
| 50 | + fmap = Map.update(fmap, mod, 1, &(&1 + 1)) |
| 51 | + |
| 52 | + # now go again |
| 53 | + count_pairs(k, rest, fmap, count) |
| 54 | + |
| 55 | + end |
| 56 | +end |
0 commit comments