R, 83 76 67 바이트
후보 소변기가 비어 있는지 확인하지 않고 몇 바이트를 절약 할 수 있다는 것을 깨달았습니다. 비어 있지 않은 소변기는 항상 Inf불편 값을 반환 하므로 계산 과정에서 제외됩니다. 또한 대신 직접 색인 생성을 사용 replace하기 때문에 짧지 만 우아하지는 않습니다.
x=scan()
x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1
x
설명
x=scan()
stdin에서 현재 상태를 읽고 호출합니다 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