R 83 76 67 байт
Просто понял, что я могу сэкономить несколько байтов, не потрудившись проверить, пустые ли писсуары кандидата. Непустые писсуары всегда возвращают Infзначение дискомфорта, поэтому они исключаются в ходе расчета. Кроме того, просто используется прямое индексирование, а не replace, так что это короче, но не так элегантно.
x=scan()
x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1
x
объяснение
x=scan()
Мы читаем текущее состояние из стандартного ввода и называем его x . Мы предполагаем, что входные данные представляют собой последовательность 1s и 0s, разделенных пробелами или символами новой строки. Для целей объяснения, скажем, мы вводим 1 0 0 0 0 0 1.
x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1
Мы заменяем значение xв определенном индексе на 1. Все, что [ ]находится между, определяет , какой индекс лучше.
Поскольку существующие писсуары неизменны, нам не нужно учитывать расстояния между ними. Нам нужно только рассмотреть расстояния между занятыми писсуарами и возможным новым. Таким образом, мы определяем показатели занятых писсуаров. Мы используем whichфункцию для возврата индексов логического вектора, которые есть TRUE. При приведении к типу все числа в R logicalравны TRUEнулю и FALSEнулю. Простое выполнение which(x)приведет к ошибке типа argument to 'which' is not logical, как xи числовой вектор. Поэтому мы должны привести его к логическому. !является функцией логического отрицания R, которая автоматически приводит к логическому. Применяя его дважды, !!xполучаем вектор TRUEиFALSEуказывая, какие писсуары заняты. (Альтернативные побайтно-эквивалентные приведения к логическому включают в себя логические операторы &и |и встроенные функции Tи F, например, F|xили T&xи т. Д. !!xВыглядит более восклицательным, поэтому мы будем использовать это.)
which(!!x)
Это в паре с seq(x), который возвращает целочисленную последовательность от 1длины x, то есть все места писсуара (и, следовательно, все возможные места для рассмотрения).
seq(x)
Теперь у нас есть индексы наших занятых писсуаров: 1 7и наших пустых писсуаров 1 2 3 4 5 6 7. Мы передаем `-`функцию вычитания в outerфункцию для получения «внешнего вычитания», которое представляет собой следующую матрицу расстояний между всеми писсуарами и занятыми писсуарами:
[, 1] [, 2]
[1,] 0 -6
[2,] 1 -5
[3,] 2 -4
[4,] 3 -3
[5,] 4 -2
[6,] 5 -1
[7,] 6 0
outer(seq(x),which(!!x),`-`)
Мы возносим это к -2власти. (Для тех, кто немного потерян, в ОП «дискомфорт» определяется как 1 / (distance(x, y) * distance(x, y)), что упрощает 1/d(x,y)^2, т d(x,y)^-2. Е. )
outer(seq(x),which(!!x),`-`)^-2
Возьмите сумму каждой строки в матрице.
rowSums(outer(seq(x),which(!!x),`-`)^-2)
Получите индекс наименьшего значения, то есть оптимальный писсуар. В случае нескольких наименьших значений возвращается первое (т.е. самое левое) значение.
which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))
И вуаля, у нас есть индекс оптимального писсуара. Мы заменяем значение в этом индексе в xс 1. В случае 1111ввода, не имеет значения, какой из них мы заменим, у нас все равно будет действительный вывод.
x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1
Вернуть измененный ввод.
x