我是Palantir技术公司在接受采访时在互联网上提出的挑战。
一群农民有一些海拔数据,我们将帮助他们了解降雨如何流过农田。我们将土地表示为一个二维的高度阵列,并使用以下模型,基于水下坡的想法:如果一个细胞的四个相邻细胞都有较高的高度,我们称这个细胞为水槽;水聚集在水槽中。否则,水会流向海拔最低的邻近细胞。如果一个单元不是接收器,您可以假设它有一个唯一的最低邻居,并且这个邻居将低于单元格。直接或间接流入同一水槽的细胞据说是同一盆地的一部分。你的挑战是把地图划分成盆地。特别是,给定一个海拔图,您的代码应该将地图划分为盆地,并按降序输出盆地的大小。假设高程图是正方形的。输入将以一个整数开始,S,地图的高度(和宽度)。下一条S线将分别包含一排地图,每一行都带有S整数--这一行中的加高单元格。有些农民有小块地,如下面的例子,而有些人则有较大的地块。然而,在任何情况下,农民都不会拥有超过S= 5000的一块土地。您的代码应该输出一个按降序排列的盆地大小的空格分隔列表。(忽略尾随空格。)下面是几个例子。输入:
3
1 5 2
2 4 7
3 6 9 输出:
7 2用A和B标记的盆地是:
A A B
A A B
A A A 输入:
1
10输出:
1这里只有一个盆地。输入:
5
1 0 2 5 8
2 3 4 7 9
3 5 7 8 9
1 2 5 4 2
3 3 5 2 1 输出:
11 7 7标有A、B和C‘s的盆地是:
A A A A A
A A A A A
B B A C C
B B B C C
B B C C C 输入:
4
0 2 1 3
2 1 0 4
3 3 3 3
5 5 2 1 输出:
7 5 4标有A、B和C‘s的盆地是:
A A B B
A B B B
A B B C
A C C C发布于 2014-05-07 03:18:13
r=[]
M=gets('').split.map &:to_i
N=M.shift
g=M.map{1}
M.sort.reverse.map{|w|t=[c=M.index(w),c%N<0?c:c-1,c%N<N-1?c+1:c,c+N,c-N].min_by{|y|M[y]&&y>=0?M[y]:M.max}
M[c]+=1
t!=c ?g[t]+=g[c]:r<<g[c]}
A2gt;<<r.sort.reverse*' '这是一种稍微不同的方法,只在每个平方上调用"flow“一次(性能取决于Array::index的性能)。它从最高的海拔到最低的高度,一次把一个细胞排空到它的最低邻居,并在它完成时标记完成的单元格(增加1到海拔)。
评论和间隔:
results=[]
ELEVATIONS = gets('').split.map &:to_i # ELEVATIONS is the input map
MAP_SIZE = ELEVATIONS.shift # MAP_SIZE is the first line of input
watershed_size = ELEVATIONS.map{1} # watershed_size is the size of the watershed of each cell
ELEVATIONS.sort.reverse.map { |water_level|
# target_index is where the water flows to. It's the minimum elevation of the (up to) 5 cells:
target_index = [
current_index = ELEVATIONS.index(water_level), # this cell
(current_index % MAP_SIZE) < 0 ? current_index : current_index-1, # left if possible
(current_index % MAP_SIZE) >= MAP_SIZE-1 ? current_index : current_index+1, # right if possible
current_index + MAP_SIZE, # below
current_index - MAP_SIZE # above
].min_by{ |y|
# if y is out of range, use max. Else, use ELEVATIONS[y]
(ELEVATIONS[y] && y>=0) ? ELEVATIONS[y] : ELEVATIONS.max
}
# done with this cell.
# increment the elevation to mark done since it no longer matters
ELEVATIONS[current_index] += 1
# if this is not a sink
(target_index != current_index) ?
# add my watershed size to the target's
watershed_size[target_index] += watershed_size[current_index]
# else, push my watershed size onto results
: results << watershed_size[current_index]}216 -取消选择场外指数的更好方法
221 -原来"11“在”2“之前.恢复到to_i,但在getses上节省一些空间。
224号-为什么要声明s?和each => map
229-大型高尔夫--首先将高地排序为s (从而删除while子句),使用min_by而不是sort_by{...}[0],不要在海拔上费心to_i,使用flat_map和收缩select{}块。
271 -将分水岭大小移动到新的数组中并使用sort_by。
315 -将结果移动到数组中,这提供了各种好处,并缩短了相邻索引列表。在指数lambda中也增加了一个煤焦。
355 -第一次承诺
发布于 2014-05-08 23:42:16
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(' ')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.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]})假设输入在变量S中;
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.
})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]})产出:[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]})产出:[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]})产出:[5, 7, 4]
发布于 2014-05-14 00:17:46
function f(a,i,j)
z=size(a,1)
n=filter((x)->0<x[1]<=z&&0<x[2]<=z,[(i+1,j),(i-1,j),(i,j-1),(i,j+1)])
v=[a[b...] for b in n]
all(v.>a[i,j]) && (return i,j)
f(a,n[indmin(v)]...)
end
p(a)=prod(["$n " for n=(b=[f(a,i,j) for i=1:size(a,1),j=1:size(a,2)];sort([sum(b.==s) for s=unique(b)],rev=true))])只是一个递归函数,它要么确定当前单元格是接收器,要么找到漏池,然后在每组索引上调用它。我不想做输入部分,因为无论如何我都不会赢,而且那部分也不好玩。
https://codegolf.stackexchange.com/questions/19188
复制相似问题