R, 83 76 67 bajtów
Właśnie zdałem sobie sprawę, że mogę zaoszczędzić kilka bajtów, nie zawracając sobie głowy sprawdzaniem, czy pisuary kandydatów są puste. Niepuste pisuary zawsze zwracają Infwartość dyskomfortu, dlatego są one wykluczane w trakcie obliczeń. Ponadto, zamiast bezpośredniego indeksowania replace, jest krótszy, ale mniej elegancki.
x=scan()
x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1
x
Wyjaśnienie
x=scan()
Odczytujemy bieżący stan ze standardowego wejścia i nazywamy go x. Zakładamy, że wkład jest sekwencją 1si 0y znak spacji lub znakami nowej linii. Dla celów wyjaśnienia załóżmy, że wprowadzamy 1 0 0 0 0 0 1.
x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1
Zastępujemy wartość xokreślonego indeksu wartością 1. Wszystko pomiędzy [ ]zastanawia się, jaki jest najlepszy indeks.
Ponieważ istniejące pisuary są niezmienne, nie musimy brać pod uwagę odległości między nimi. Musimy tylko wziąć pod uwagę odległości między zajętymi pisuarami i możliwym nowym. Tak więc określamy wskaźniki zajmowanych pisuarów. Używamy whichfunkcji do zwracania indeksów wektora logicznego TRUE. Wszystkie liczby w R po wymuszeniu wpisania logicalsą TRUEniezerowe i FALSEzerowe. Po prostu zrobienie which(x)spowoduje błąd typu argument to 'which' is not logical, podobnie jak xwektor numeryczny. Musimy zatem zmusić to do logiki. !to funkcja logicznej negacji R, która automatycznie zmienia się w logiczną. Zastosowanie go dwukrotnie !!xdaje wektor TRUEiFALSEwskazując, które pisuary są zajęte. (Alternatywne bajt równoważne coercions logicznemu obejmować operatorów logicznych &i |i przy pomocy poleceń wbudowanych Ti Fnp F|xalbo T&xi tak dalej. !!xWygląda bardziej wykrzyknikowy więc użyjemy tego.)
which(!!x)
Jest to sparowane z seq(x), co zwraca sekwencję całkowitą od 1długości x, tj. Wszystkich lokalizacji pisuaru (a więc wszystkich możliwych lokalizacji do rozważenia).
seq(x)
Teraz mamy wskaźniki naszych zajętych pisuarów 1 7i naszych pustych pisuarów 1 2 3 4 5 6 7. Przekazujemy `-`funkcję odejmowania do outerfunkcji, aby uzyskać „odejmowanie zewnętrzne”, która jest następującą macierzą odległości między wszystkimi pisuarami a zajętymi pisuarami:
[, 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),`-`)
Podnosimy to do -2potęgi. (Dla tych, którzy są trochę zagubieni, w OP „dyskomfort” definiuje się jako 1 / (distance(x, y) * distance(x, y)), co upraszcza 1/d(x,y)^2, tj d(x,y)^-2.)
outer(seq(x),which(!!x),`-`)^-2
Weź sumę każdego wiersza w macierzy.
rowSums(outer(seq(x),which(!!x),`-`)^-2)
Uzyskaj indeks najmniejszej wartości, czyli optymalnego pisuaru. W przypadku wielu najmniejszych wartości zwracana jest pierwsza (tj. Najbardziej lewa).
which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))
I voilà, mamy indeks optymalnego pisuaru. Zamieniamy na wartość tego wskaźnika w xz 1. W przypadku danych 1111wejściowych nie ma znaczenia, który z nich zastąpimy, nadal będziemy mieć prawidłowe dane wyjściowe.
x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1
Zwraca zmodyfikowane dane wejściowe.
x