Two Dimensional Waterflow problem

2

1

The one dimensional twitter waterflow problem is this:

You are given an array that represents a hill in the sense that the ith entry is the height of the ith location of the hill. When it rains, water logs in the hills, and you need to figure out how much water would log.

For example, after raining, the array 2 5 3 4 3 2 5 5 3 4 2 2 2 looks like this,

and 9 units of water have accumulated.


The challenge is to solve the 2D version of this. To clarify, you will be given a 2D matrix of land heights, and you will have to output the total amount of rainwater it can collect. Water cannot flow out through diagonals, but only the four cardinal directions.

Agnishom Chattopadhyay

Posted 2018-07-01T04:57:06.017

Reputation: 365

Question was closed 2018-07-01T13:25:18.787

1duplicate? – ngn – 2018-07-01T06:15:06.327

@ngn it is pretty close, but not an exact duplicate – Agnishom Chattopadhyay – 2018-07-01T07:09:08.023

3@AgnishomChattopadhyay Fair enough. I think you should mention big-O of what we should optimise for - the size of the matrix, or the volume of the water held, or the max height? – ngn – 2018-07-01T07:12:56.257

2@AgnishomChattopadhyay also, it would be nice to have some tests – ngn – 2018-07-01T07:21:13.733

4I think you should make it more obvious that the actual challenge is the second part of the post and give at least one 2D example. – Arnauld – 2018-07-01T07:47:23.593

1Also: (1) if there is a winning criteria tag, don't need [code-challenge]. (2) best case, worst case or average case? – user202729 – 2018-07-01T09:33:18.923

I voted to close because ngn 's question is not clarified. – user202729 – 2018-07-01T10:02:40.343

The picture is really misleading... – Jo King – 2018-07-01T10:24:44.787

Possible duplicate of Fill in the lakes

– Jonathan Frech – 2018-07-01T11:23:24.010

@JonathanFrech Different winning criteria. – user202729 – 2018-07-01T15:00:01.143

Answers

0

Python 3, O(h × w × d) 296 bytes, O(h × w × d')

def f(a):
 w=0;b=[len(a[0])*[0]];a=b+a+b;a=[[0]+x+[0]for x in a];b=sorted(set(sum(a,[])))
 for[i,j]in zip(b,b[1:]+[1+max(b)]):
  c=[[0,0]]
  while c:
   [x,y]=c.pop()
   if x<len(a)and x>=0and y<len(a[0])and y>=0and a[x][y]<=i:w+=i-a[x][y];a[x][y]=j;c+=[[x+1,y],[x,y+1],[x-1,y],[x,y-1]]
 return w

Try it online! Where d' represents the number of distinct values in the input. Edit: Saved 3 bytes thanks to @Mr.Xcoder.

Neil

Posted 2018-07-01T04:57:06.017

Reputation: 95 035

(what is h, w and d?) – user202729 – 2018-07-01T10:01:10.683

@user202729 d is the highest land height in the w × h grid, but I like to think of it as the depth. – Neil – 2018-07-01T10:16:28.433

b=[len(a[0])*[0]] should work for 276. – Mr. Xcoder – 2018-07-01T12:31:37.127

Thanks for the answer. I'd like to think that there is some algorithm that is independent of d. Otherwise, scaling all the numbers by some arbitrary amount would randomly require more time. – Agnishom Chattopadhyay – 2018-07-01T15:28:41.510

@AgnishomChattopadhyay Better now? – Neil – 2018-07-01T16:03:19.537

This is much cooler. Where is the d factor coming from? – Agnishom Chattopadhyay – 2018-07-01T16:21:36.093

@AgnishomChattopadhyay ... if you mean the d' factor, it's documented in the answer. – Neil – 2018-07-01T16:39:00.130

@Neil Yes, I see that. What I meant was, I had been wondering if there is a reason why the d' factor cannot be avoided. – Agnishom Chattopadhyay – 2018-07-01T16:45:48.040

@AgnishomChattopadhyay Well, I can think of an O(w² × h²) algorithm, but I hardly think that's an improvement. – Neil – 2018-07-01T18:10:54.113

Scan every row from left and right, every column from top and bottom, thereby determining the maximum limiting height for every square in each direction. Then sum up the difference of each squares height and the minimum of its borders. Should be O (n^2), which is asymptotically optimal. – politza – 2018-07-11T07:35:37.410

@politza As far as I can tell, given the first test case I use in my demo, your algorithm would think that the 0 is covered by 6 units of water but in fact it's only 5. – Neil – 2018-07-11T07:52:59.263

Yes, you're correct. – politza – 2018-07-11T09:29:14.250