R, 83 76 67 octets
Je viens de réaliser que je peux économiser plusieurs octets en ne prenant pas la peine de vérifier si les urinoirs candidats sont vides. Les urinoirs non vides renverront toujours une Infvaleur d'inconfort, ils sont donc exclus au cours du calcul. En outre, il suffit d'utiliser l'indexation directe plutôt que replace, donc c'est plus court mais moins élégant.
x=scan()
x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1
x
Explication
x=scan()
Nous lisons l'état actuel de stdin et l'appelons x. Nous supposons que l'entrée est une séquence de 1s et 0s séparés par des espaces ou des retours à la ligne. Aux fins de l'explication, disons que nous saisissons 1 0 0 0 0 0 1.
x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1
Nous remplaçons une valeur de xà un indice particulier par 1. Tout entre le[ ] détermine quel est le meilleur index.
Étant donné que les urinoirs existants sont immuables, nous n'avons pas besoin de considérer les distances entre eux. Il suffit de considérer les distances entre les urinoirs occupés et le nouveau éventuel. Nous déterminons donc les indices des urinoirs occupés. Nous utilisons whichune fonction pour renvoyer les indices d'un vecteur logique qui le sont TRUE. Tous les nombres de R, lorsqu'ils sont contraints de taper logical, sont TRUEsi différents de zéro et FALSEs'ils sont nuls. Faire simplement which(x)entraînera une erreur de type argument to 'which' is not logical, tout comme xun vecteur numérique. Nous devons donc le contraindre à la logique. !est la fonction de négation logique de R, qui contraint automatiquement à logique. En l'appliquant deux fois !!x,, donne un vecteur de TRUEetFALSE indiquant quels urinoirs sont occupés. (Les coercitions équivalentes en octets alternatives à la logique impliquent les opérateurs logiques& et |et les commandes internes Tet F, par exemple F|xou T&xet ainsi de suite. !!xSemble plus exclamatif, nous allons donc l'utiliser.)
which(!!x)
Ceci est associé à seq(x), qui renvoie la séquence entière de 1à la longueur de x, c'est-à-dire tous les emplacements d'urinoirs (et donc tous les emplacements possibles à considérer).
seq(x)
Nous avons maintenant les indices de nos urinoirs occupés: 1 7et de nos urinoirs vides 1 2 3 4 5 6 7. On passe `-`, la fonction de soustraction, à la outerfonction pour obtenir la "soustraction externe", qui est la matrice de distances suivante entre tous les urinoirs et les urinoirs occupés:
[, 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),`-`)
Nous élevons cela à la -2puissance e. (Pour ceux qui sont un peu perdus, au PO, le "malaise" est défini comme 1 / (distance(x, y) * distance(x, y)), ce qui simplifie 1/d(x,y)^2, c'est- à -dire d(x,y)^-2.)
outer(seq(x),which(!!x),`-`)^-2
Prenez la somme de chaque ligne de la matrice.
rowSums(outer(seq(x),which(!!x),`-`)^-2)
Obtenez l'indice de la plus petite valeur, c'est-à-dire l'urinoir optimal. Dans le cas de plusieurs plus petites valeurs, la première (c'est-à-dire la plus à gauche) est renvoyée.
which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))
Et voilà, nous avons l'indice de l'urinoir optimal. Nous remplaçons la valeur de cet indice xpar 1. Dans le cas d'une 1111entrée, peu importe celle que nous remplaçons, nous aurons toujours une sortie valide.
x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1
Renvoie l'entrée modifiée.
x