R, 83 76 67 byte
Ho appena realizzato che posso salvare diversi byte evitando di controllare se gli orinatoi candidati sono vuoti. Gli orinatoi non vuoti restituiranno sempre un Infvalore di disagio, quindi vengono esclusi nel corso del calcolo. Inoltre, usando solo l'indicizzazione diretta anziché replace, quindi è più breve ma meno elegante.
x=scan()
x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1
x
Spiegazione
x=scan()
Leggiamo lo stato corrente da stdin e lo chiamiamo x. Assumiamo che l'ingresso è una sequenza di 1s e 0s separati da spazi o nuove righe. Ai fini della spiegazione, supponiamo di inserire 1 0 0 0 0 0 1.
x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1
Sostituiamo un valore di xun determinato indice con 1. Tutto ciò che sta tra i due [ ]è capire quale sia l'indice migliore.
Poiché gli orinatoi esistenti sono immutabili, non è necessario considerare le distanze tra loro. Dobbiamo solo considerare le distanze tra gli orinatoi occupati e l'eventuale nuovo. Quindi determiniamo gli indici degli orinatoi occupati. Usiamo which, una funzione per restituire gli indici di un vettore logico che sono TRUE. Tutti i numeri in R, se costretti a digitare logical, sono TRUEse diversi da zero e FALSEse zero. Fare semplicemente which(x)comporterà un errore di tipo argument to 'which' is not logical, così come xun vettore numerico. Dobbiamo quindi costringerlo a logico. !è la funzione di negazione logica di R, che passa automaticamente a logica. Applicandolo due volte, si !!xottiene un vettore di TRUEeFALSEindicando quali orinatoi sono occupati. (Alternativi coercizioni byte-equivalenti a logica coinvolgono gli operatori logici &e |ed i comandi incorporati Te F, ad esempio, F|xo di T&xe così via. !!xSembra più exclamatory quindi useremo questo.)
which(!!x)
Questo è accoppiato seq(x), che restituisce la sequenza intera dalla 1lunghezza di x, cioè tutte le posizioni degli orinatoi (e quindi tutte le possibili posizioni da considerare).
seq(x)
Ora abbiamo gli indici dei nostri orinatoi occupati: 1 7e dei nostri orinatoi vuoti 1 2 3 4 5 6 7. Passiamo `-`alla funzione di sottrazione alla outerfunzione per ottenere la "sottrazione esterna", che è la seguente matrice di distanze tra tutti gli orinatoi e gli orinatoi occupati:
[, 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),`-`)
Portiamo questo al -2potere. (Per coloro che si sono un po 'persi, nel PO, si definisce "disagio" 1 / (distance(x, y) * distance(x, y)), che semplifica 1/d(x,y)^2, ad es d(x,y)^-2.)
outer(seq(x),which(!!x),`-`)^-2
Prendi la somma di ogni riga nella matrice.
rowSums(outer(seq(x),which(!!x),`-`)^-2)
Ottieni l'indice del valore più piccolo, ovvero l'orinatoio ottimale. Nel caso di più valori più piccoli, viene restituito il primo (ovvero quello più a sinistra).
which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))
E voilà, abbiamo l'indice dell'orinale ottimale. Sostituiamo il valore di questo indice xcon 1. Nel caso di 1111input, non importa quale sostituiamo, avremo comunque un output valido.
x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1
Restituisce l'ingresso modificato.
x