R, 83 76 67 byte
Baru menyadari bahwa saya dapat menyimpan beberapa byte dengan tidak repot memeriksa apakah kandidat urinal kosong. Ural yang tidak kosong akan selalu mengembalikan Infnilai ketidaknyamanan, sehingga tidak dimasukkan dalam perhitungan. Juga, hanya menggunakan pengindeksan langsung daripada replace, jadi lebih pendek tapi kurang elegan.
x=scan()
x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1
x
Penjelasan
x=scan()
Kami membaca status saat ini dari stdin dan menyebutnya x. Kami berasumsi bahwa input adalah urutan 1s dan 0s dipisahkan oleh spasi atau baris baru. Untuk keperluan penjelasan, misalkan kita masukan 1 0 0 0 0 0 1.
x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1
Kami mengganti nilai xpada indeks tertentu dengan 1. Segala sesuatu di antara [ ]ini mencari tahu apa indeks terbaik.
Karena urinal yang ada tidak berubah, kita tidak perlu mempertimbangkan jarak di antara mereka. Kita hanya perlu mempertimbangkan jarak antara urinal yang ditempati dan kemungkinan yang baru. Jadi kami menentukan indeks urinal yang diduduki. Kami menggunakan which, fungsi untuk mengembalikan indeks vektor logis TRUE. Semua angka dalam R, ketika dipaksa untuk mengetik logical, adalah TRUEjika bukan nol dan FALSEjika nol. Cukup melakukan which(x)akan menghasilkan kesalahan ketik argument to 'which' is not logical,, seperti xvektor numerik. Karena itu kami harus memaksanya masuk akal. !adalah fungsi negasi logis R, yang secara otomatis memaksa ke logis. Menerapkannya dua kali !!x,, menghasilkan vektor TRUEdanFALSEmenunjukkan urinal mana yang ditempati. (Alternatif paksaan setara byte untuk logika melibatkan operator logika &dan |dan builtin Tdan F, misalnya F|xatau T&xseterusnya. !!xTerlihat lebih seram sehingga kita akan menggunakannya.)
which(!!x)
Ini dipasangkan dengan seq(x), yang mengembalikan urutan bilangan bulat dari 1panjang x, yaitu semua lokasi urinoir (dan dengan demikian semua lokasi yang memungkinkan untuk dipertimbangkan).
seq(x)
Sekarang kita memiliki indeks urinal kita yang diduduki: 1 7dan urinal kita yang kosong 1 2 3 4 5 6 7. Kami lulus `-`, fungsi pengurangan, ke outerfungsi untuk mendapatkan "pengurangan luar", yang merupakan matriks jarak berikut antara semua urinal dan urinal yang ditempati:
[, 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),`-`)
Kami mengangkat ini ke -2kekuatan th. (Bagi mereka yang sedikit tersesat, dalam OP, "ketidaknyamanan" didefinisikan sebagai 1 / (distance(x, y) * distance(x, y)), yang menyederhanakan 1/d(x,y)^2, yaitu d(x,y)^-2.)
outer(seq(x),which(!!x),`-`)^-2
Ambil jumlah setiap baris dalam matriks.
rowSums(outer(seq(x),which(!!x),`-`)^-2)
Dapatkan indeks nilai terkecil, yaitu urinal optimal. Dalam kasus beberapa nilai terkecil, yang pertama (yaitu paling kiri) dikembalikan.
which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))
Dan voila, kami memiliki indeks urinal optimal. Kami mengganti nilai pada indeks ini xdengan 1. Dalam hal 1111sebagai input, tidak masalah yang mana yang kami ganti, kami masih akan memiliki output yang valid.
x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1
Kembalikan input yang dimodifikasi.
x