以下是描述问题的interactive page和数学上的academic paper。
问题大致可以描述如下。
给定一个任意长度的布尔值数组,表示n
个邻近的小便池,值true
表示占用,值false
表示空置,在给定任何配置的情况下,如何构建一个算法来填充此数组,同时:
通过尽可能远离任何一侧的其他排水器,最大限度地提高每位乘客的“隐私”。
通过确保配置在最后可能的时间变得饱和,尽可能长时间保持此隐私。
面对多个次优的选择,优先排尿小便器,两侧没有相邻的小便池,而不是仅仅是一个未占用的相邻小便池。
我为了简单起见标记了这个javascript,但任何代码或伪代码都没问题。
var urinals = Array
.apply(null, new Array(n))
.map(Boolean.prototype.valueOf,false);
编辑 - 在这里找到了一个相关的问题:
答案 0 :(得分:1)
尽可能接近解决方案:
var urinalFinder = function(urinals){
var gaps = new Array(), last = null;
for(var i = 0; i < urinals.length; i++){
last = gaps.length ? gaps[gaps.length - 1] : 0;
if(last < 0 && !urinals[i] || last > 0 && !!urinals[i] || last == 0)
gaps.push(0); // push if new sequence of vacant or occupied
// negatives are occupied count & positives vacant count
gaps[gaps.length - 1] += !!urinals[i] ? -1 : 1;
}
// find the first index of the largest gap
var maxGapSize = Math.max.apply(Math, gaps),
maxGapGapsIdx = gaps.indexOf(maxGapSize),
isFirst = maxGapGapsIdx === 0,
isLast = maxGapGapsIdx === gaps.length - 1,
maxGapIdx = 0;
if(maxGapSize < 1) return false; // no gaps available
var gapPoint = maxGapSize > 3
? Math.ceil(maxGapSize / 3) // per xkcd suggestion
: isFirst && maxGapSize === 2
? 1
: isLast && maxGapSize === 2 ? 2 : Math.ceil(maxGapSize / 2);
// find where our chosen gap begins in input array
for(var i = 0; i < maxGapGapsIdx; i++)
maxGapIdx += Math.abs(gaps[i]);
var result = maxGapIdx + gapPoint - 1; // arrays are zero-indexed
return result;
};
例如,应用于填充9个空格的数组将填充它们:
var foo = [0,0,0,0,0,0,0,0,0]; // nine values
for(var i = 0; i < foo.length; i++)
foo[urinalFinder(foo)] = i+1;
[4, 6, 1, 7, 2, 8, 3, 9, 5]
并不总能产生最佳效果(有时候不同的位置可能会让以后几次移动饱和度)并且不支持末端小便池,但是它可以很好地控制值并保持最小缓冲区尽可能长的时间