Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The Optimal Urinal Strategy

Here is an interactive page describing the problem and an academic paper going over the mathematics.

The problem can be roughly described as follows.

Given an arbitrary-length array of boolean values representing n adjacent urinals, with values of true indicating occupied and values of false indicating vacant, how would you construct an algorithm to populate this array, given any configuration, while:

  • Maximizing the 'privacy' of each occupant by keeping one as far as possible from other urinators on either side.

  • Maintaining this privacy for as long as possible by ensuring the configuration becomes saturated at the last possible time.

  • Faced with multiple suboptimal choices, prioritizing urinals without an adjacent urinal on either side over a merely unoccupied adjacent urinal.

I marked this javascript for simplicity, but any code or pseudo-code would be fine.

var urinals = Array
    .apply(null, new Array(n))
    .map(Boolean.prototype.valueOf,false);

edit - found a related problem here:

Optimal Seating Arrangement Algorithm

like image 286
Greg Avatar asked Jan 18 '14 23:01

Greg


People also ask

What is proper urinal etiquette?

Always leave a gap. If there are three urinals and only one – the end one - is being used, use the one at the other end. Leave the middle one empty. This is referred to as the “urinal gap” and should always be adhered to unless the bathroom is busy.

Where should men aim when peeing?

"Often, aiming for the sidewalls is the best approach. If you can reduce angle and stand closer, that is ideal. If you can only do one, stand closer. If standing closer isn't an option, reduce the impact angle."

Where do you pee in a urinal to avoid splash?

Splash-back is at its worst when the urine stream is angled perpendicular to the urinal wall. According to one of the researchers, Randy Hurd, the best option to prevent splash-back is to "aim at the sidewalls of the urinal." He also suggests that gentlemen stand closer to the urinal.

Why are there ladybug stickers in urinals?

Ladybug WC stickers in the toilet improves the aim of all boys, big and small. We have them in rolls of 10, 30, 100 and 500 pieces. Known from a study done by a Dutch airport where the "marksmanship" was significantly improved by the sticker in the toilet bowl.


1 Answers

As close as I have to a solution:

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;
};

For example, applied to filling an array of 9 vacant spaces will fill them like this:

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]

Does not always produce optimal results (sometimes a different placement could allow saturation a few moves later) and does not favor end urinals, but does a pretty good job fanning values around and keeping a minimum buffer for just about as long as possible.

like image 139
Greg Avatar answered Oct 17 '22 16:10

Greg