JavaScript (ECMAScript 6) - 226 Characters
s=S.split(/\s/);n=s.shift(k=[]);u=k.a;t=s.map((v,i)=>[v,i,1]);t.slice().sort(X=(a,b)=>a[0]-b[0]).reverse().map(v=>{i=v[1];p=[v,i%n?t[i-1]:u,t[i-n],(i+1)%n?t[i+1]:u,t[+n+i]].sort(X)[0];p==v?k.push(v[2]):p[2]+=v[2]});k.join(' ')
Explanation
s=S.split(/\s/); // split S into an array using whitespace as the boundary.
n=s.shift(); // remove the grid size from s and put it into n.
k=[]; // an empty array to hold the position of the sinks.
u=k.a; // An undefined variable
t=s.map((v,i)=>[v,i,1]); // map s to an array of:
// - the elevation
// - the position of this grid square
// - the number of grid squares which have flowed into
// this grid square (initially 1).
X=(a,b)=>a[0]-b[0]; // A comparator function for sorting.
t.slice() // Take a copy of t
.sort(X) // Then sort it by ascending elevation
.reverse() // Reverse it to be sorted in descending order
.map(v=>{ // For each grid square (starting with highest elevation)
i=v[1]; // Get the position within the grid
p=[v,i%n?t[i-1]:u,t[i-n],(i+1)%n?t[i+1]:u,t[+n+i]]
// Create an array of the grid square and 4 adjacent
// squares (or undefined if off the edge of the grid)
.sort(X) // Then sort by ascending elevation
[0]; // Then get the square with the lowest elevation.
p==v // If the current grid square has the lowest elevation
?k.push(v[2]) // Then add the number of grid square which have
// flowed into it to k
:p[2]+=v[2]}); // Else flow the current grid square into its lowest
// neighbour.
k.join(' ') // Output the sizes of the block with space separation.
Previous Version - 286 Characters
s=S.split(/\s/);n=s.shift()*1;k=[];u=k[1];t=s.map((v,i)=>({v:v,p:i,o:[]}));for(i in t){t[p=[t[i],i%n?t[i-1]:u,t[i-n],(+i+1)%n?t[+i+1]:u,t[+i+n]].sort((a,b)=>(a.v-b.v))[0].p].o.push([i]);p==i&&k.push([i])}k.map(x=>{while(x[L="length"]<(x=[].concat(...x.map(y=>t[y].o)))[L]);return x[L]})
Assumes that the input is in a variable S
;
Explanation
s=S.split(/\s/); // split S into an array using whitespace as the boundary.
n=s.shift()*1; // remove the grid size from s and put it into n.
k=[]; // an empty array to hold the position of the sinks.
u=k[1]; // Undefined
t=s.map((v,i)=>({v:v,p:i,o:[]})); // map s to an Object with attributes:
// - v: the elevation
// - p: the position of this grid square
// - o: an array of positions of neighbours which
// flow into this grid square.
for(i in t){ // for each grid square
p=[t[i],i%n?t[i-1]:u,t[i-n],(+i+1)%n?t[+i+1]:u,t[+i+n]]
// start with an array containing the objects
// representing that grid square and its 4 neighbours
// (or undefined for those neighbours which are
// outside the grid)
.sort((a,b)=>(a.v-b.v)) // then sort that array in ascending order of elevation
[0].p // then get the first array element (with lowest
// elevation) and get the position of that grid square.
t[p].o.push([i]); // Add the position of the current grid square to the
// array of neighbours which flow into the grid square
// we've just found.
p==i&&k.push([i]) // Finally, if the two positions are identical then
// we've found a sink so add it to the array of sinks (k)
}
k.map(x=>{ // For each sink start with an array, x, containing the
// position of the sink.
while(x.length<(x=[].concat(...x.map(y=>t[y].o))).length);
// Compare x to the concatenation of x with all the
// positions of grid squares which flow into squares
// in x and loop until it stops growing.
return x.length // Then return the number of grid squares.
})
Test
S="3\n1 5 2\n2 4 7\n3 6 9";
s=S.split(/\s/);n=s.shift()*1;k=[];u=k[1];t=s.map((v,i)=>({v:v,p:i,o:[]}));for(i in t){t[p=[t[i],i%n?t[i-1]:u,t[i-n],(+i+1)%n?t[+i+1]:u,t[+i+n]].sort((a,b)=>(a.v-b.v))[0].p].o.push([i]);p==i&&k.push([i])}k.map(x=>{while(x[L="length"]<(x=[].concat(...x.map(y=>t[y].o)))[L]);return x[L]})
Outputs: [7, 2]
S="5\n1 0 2 5 8\n2 3 4 7 9\n3 5 7 8 9\n1 2 5 4 2\n3 3 5 2 1"
s=S.split(/\s/);n=s.shift()*1;k=[];u=k[1];t=s.map((v,i)=>({v:v,p:i,o:[]}));for(i in t){t[p=[t[i],i%n?t[i-1]:u,t[i-n],(+i+1)%n?t[+i+1]:u,t[+i+n]].sort((a,b)=>(a.v-b.v))[0].p].o.push([i]);p==i&&k.push([i])}k.map(x=>{while(x[L="length"]<(x=[].concat(...x.map(y=>t[y].o)))[L]);return x[L]})
Outputs: [11, 7, 7]
S="4\n0 2 1 3\n2 1 0 4\n3 3 3 3\n5 5 2 1"
s=S.split(/\s/);n=s.shift()*1;k=[];u=k[1];t=s.map((v,i)=>({v:v,p:i,o:[]}));for(i in t){t[p=[t[i],i%n?t[i-1]:u,t[i-n],(+i+1)%n?t[+i+1]:u,t[+i+n]].sort((a,b)=>(a.v-b.v))[0].p].o.push([i]);p==i&&k.push([i])}k.map(x=>{while(x[L="length"]<(x=[].concat(...x.map(y=>t[y].o)))[L]);return x[L]})
Outputs: [5, 7, 4]
1I edited your question to make it more appropriate for this site. Earlier, it was a programming question / code review. Now it is in the form of the challenge. This site is for releasing code challenges / problems to the community for them to attempt. Note: you still require a winning criteria: shortest code ([tag:code-golf]) is recommended. – Justin – 2014-01-23T07:15:17.457
I am going to take the liberty of marking your question code-golf. – Justin – 2014-01-23T08:10:44.673
2@OP If you want an answer for your original question instead of a number of alternative golfed solutions, I suggest asking it again on Stack Overflow (or maybe Code Review?) – Gareth – 2014-01-23T08:24:25.053
@Gareth codereview doesn't like golfing and SO doesn't like reviewing, so... – John Dvorak – 2014-01-23T08:25:52.140
1@JanDvorak I think the original question before editing might be okay on Code Review (there wasn't any golfing involved to start with)? You're probably right about SO though. – Gareth – 2014-01-23T08:29:35.343
@Quincunx The part please make an effort to submit clean, readable code rules out any code-golf. – Howard – 2014-01-23T08:32:06.590
CR is it, then. But, what should be done about this question? The quoted goals don't match code-golf, otherwite it seems fine to me. Just edit them out? – John Dvorak – 2014-01-23T08:32:59.337
1@JanDvorak I think just edit it out and make it a valid code-golf – Justin – 2014-01-23T09:53:29.170
1
I have posted the problem on code review - http://codereview.stackexchange.com/questions/39895/how-to-partition-a-2d-map-consisting-of-elevation-data-into-individual-basins
– AnkitSablok – 2014-01-23T18:17:46.183