Be respectful in the restroom
Jelly, 10 9 bytes
JạþTS׬MḢ
Uses 1-based indexing. Try it online! or verify all test cases.
How it works
JạþTS׬MḢ Main link. Argument: A (array of Booleans)
J Yield all indices of A.
T Yield all truthy indices of A.
ạþ Compute the table of absolute differences.
S Compute the sums of all columns.
For each index, this yields the sum of all distances to occupied stalls.
׬ Multiply each sum by the logical NOT of the corresponding Boolean in A.
This zeroes sums that correspond to occupied stalls.
M Maximal; yield an array of all indices of maximal sums.
Ḣ Head; extract the first index.
Swift, 158, 157, 128, 100 Bytes
Takes input from the Array<Bool>
variable i
, returns answer from the last expression.
let e=i.characters.map{$0>"0"}.enumerate()
e.flatMap{$1 ?nil:$0}.map{a in(a,e.flatMap{$1 ?$0:nil}.map{abs(a-$0)}.reduce(0){$0+$1})}.maxElement{$0.1 < $1.1}!.0
Edit 1:
Saved a byte by converting to bools via string comparison
let e=i.characters.map{$0=="1"}.enumerate()
e.flatMap{$1 ?nil:$0}.map{a in(a,e.flatMap{$1 ?$0:nil}.map{abs(a-$0)}.reduce(0){$0+$1})}.maxElement{$0.1 < $1.1}!.0
Edit 2:
Reworked my algorithm:
let e=i.characters.map{$0=="1"}.enumerate()
e.map{x in(x.0,x.1 ?0:e.reduce(0){$1.1 ?$0+abs(x.0-$1.0):$0})}.max{$0.1<$1.1}!.0
Edit 3:
Took advantage of new rule that allows taking input directly from a boolean array.
let e=i.enumerated()
e.map{x in(x.0,x.1 ?0:e.reduce(0){$1.1 ?$0+abs(x.0-$1.0):$0})}.max{$0.1<$1.1}!.0
Ungolfed:
// for the sake of easier copy/pasting of input, take it as string
let s = "100000110000"
// convert input to true for taken, false for free
// this is the input the golfed version actually uses
let input = s.characters.map{$0>"0"}
// Returns an array of tuples storing the array values (vacancy of the stall) and their index (their location)
let valueIndexPairs = bools.enumerated()
// Returns an array of pairs of locations and their avg distance to others
let locationDistancePairs = valueIndexPairs.map{(valueIndexPair: (Int, Bool)) -> (Int, Int) in
let averageDistance = valueIndexPairs.reduce(0) {partialSum, otherStall in
let otherStallIsTaken = otherStall.1
if otherStallIsTaken {
//don't let other stalls effect average if they're taken
return partialSum
}
else {
let thisStallLocation = valueIndexPair.0
let otherStallLocation = otherStall.0
let distanceToOtherStall = abs(thisStallLocation - otherStallLocation)
return partialSum + distanceToOtherStall
}
}
//if this stall is taken, treat its average distance to others as 0
let thisStallsLocation = valueIndexPair.0
let isThisStallTaken = valueIndexPair.1
return (thisStallsLocation, isThisStallTaken ? 0 : averageDistance)
}
//find location where average distance is maxiumum
let bestLocationIndexPair = locationDistancePairs.max{$0.1 < $1.1}!
let bestLocation = bestLocationIndexPair.0
print(bestLocation)
Jelly, 13 bytes
1-indexed.
³Tạ⁸S
JUÇÞḟTṪ
Try it online!
Algorithm
Naive implementation of the question.