0

I'm attempting an algorithm problem in hackerrank, Roads and Libraries. The idea behind the problem is to use DFS to find connected components (CC) using an array.

Here is the test case:

queries = [
  {
    n_cities_roads: [9,2],
    c_lib_road: [91, 84],
    matrix: [
      [8, 2], [2, 9]
    ]
  },
  {
    n_cities_roads: [5,9],
    c_lib_road: [92, 23],
    matrix: [
      [2,1], [5, 3], [5,1], 
      [3,4], [3,1],  [5, 4], 
      [4,1], [5,2],  [4,2]
    ]
  },
  {
    n_cities_roads: [8,3],
    c_lib_road: [10, 55],
    matrix: [
      [6,4], [3,2], [7,1]
    ]
  },
  {
    n_cities_roads: [1, 0],
    c_lib_road: [5, 3],
    matrix: []
  },

  {
    n_cities_roads: [2, 0],
    c_lib_road: [102, 1],
    matrix: []
  }
]

queries.each do |query|
  (n_city, n_road), (c_lib, c_road) = [*query[:n_cities_roads]], [*query[:c_lib_road]]
  roads_and_libraries n_city, c_lib, c_road, query[:matrix]
end

The output should be:

805
184
80
5
204

My current solution below can get CC for some cases, but not for all.

def dfs(i, visited, matrix)
  visited[i] = true
  unless matrix[i].nil?
    matrix[i].each do |j|
      unless visited[j]
        dfs j, visited, matrix
      end
    end
  end
end

def roads_and_libraries(no_cities, c_lib, c_road, cities)
  return c_lib * no_cities if c_lib <= c_road
  visited, count = Array.new(no_cities, false), 0

  (0..no_cities).each do |i|
    unless visited[i]
      count += 1
      dfs i, visited, cities
    end
  end
  p (c_road * (no_cities - count)) + (c_lib * count)
end

The output of the test with my code above is:

805
184
7
305

I'm struggling to understand how to use DFS correctly to find connected components. Not sure where I'm going wrong.

sawa
  • 165,429
  • 45
  • 277
  • 381
Jamy
  • 115
  • 1
  • 9

1 Answers1

1

Just print this line:

p roads_and_libraries n_city, c_lib, c_road, query[:matrix]

Not this

p (c_road * (no_cities - count)) + (c_lib * count)

Because there is a return in the method:

return c_lib * no_cities if c_lib <= c_road

I don't know the algorithm, but it seems that the matrix can not be empty [], at least it has to be [[1,1]] to get the required output:

roads_and_libraries 1, 5, 3, [[1,1]] #=> 5
roads_and_libraries 2, 102, 1, [[1,1]] #=> 204

So, to deal with empty matrix, one way is to just add this as first line in dfs method:

matrix = [[1,1]] if matrix.empty?
iGian
  • 11,023
  • 3
  • 21
  • 36
  • Oh! Yh your right! Thanks for noticing that. I did the change, but now the output is this: `805 184 80 7 305` – Jamy Nov 04 '18 at 14:34
  • I don't know your algorithm, but perhaps matrix can not be empty, at least it should be [[1,1]]. See the edit. – iGian Nov 04 '18 at 14:49
  • Well, technically my algorithm should also deal with the empty matrix though. As per hackerrank test cases – Jamy Nov 04 '18 at 14:53
  • Se last edit, to deal with empty matrix adding a line to dfs method. – iGian Nov 04 '18 at 15:03