Positionelle Badezimmer Etikette

24

Hintergrund

Wenn es um die verfügbaren Urinale geht, besagt die Badezimmeretikette, dass das nächste zu füllende Urinal das sein sollte, das die totalen Beschwerden minimiert. Die totale Unbehaglichkeitsgleichung wird durch den folgenden Satz von Gleichungen gegeben:

dist (x, y) = linearer Abstand zwischen der Person x und der Person y in Urinaleinheiten.
 Unbehagen (x) = Summe (1 / (dist (x, y) * dist (x, y))) für alle Personen y ohne Person x
 total_Discomfort = Summe (Unbehagen (x)) für alle x

Ein ausführlicheres Dokument, das sich mit einem ähnlichen (nicht exakt gleichen) Problem befasst, finden Sie hier: (Vielen Dank an @Lembik, der mich auf dieses erstaunliche Whitepaper aufmerksam gemacht hat!)


Input-Output

Bei Eingabe eines leeren und eines vollen Urinals geben Sie den resultierenden Satz Urinale mit der Hinzufügung einer Person aus. Wenn für eine Position ein Gleichstand besteht, sollten die Urinale von links nach rechts gefüllt werden. Die Ausgabe sollte dasselbe Format haben wie die Eingabe.

  • Wenn ein Fall mit vollem Urinal vorliegt, geben Sie die Eingabe zurück.
  • In der Eingabe ist immer mindestens ein Urinal definiert.


Testfälle

EINGANG -> AUSGANG
1000001 -> 1001001
101010101 -> 111010101
100 -> 101
00000 -> 10000
1111111 -> 1111111
0100 -> 0101
101000 -> 101001


Regeln

Das ist , also gewinnt der kürzeste Code in Bytes. Standard-Schlupflöcher sind verboten.

Nick Frev
quelle
1
Es wird empfohlen, ungefähr eine Woche zu warten, bevor Sie eine Antwort annehmen. Das Akzeptieren in weniger als einem Tag kann die Anzahl der Antworten verringern, die Ihre Herausforderung erhält.
Emigna
1
Ich würde vorschlagen, 0100und 101000in den Testfällen (einige Regex-basierte Ansätze arbeiten an den tatsächlichen Testfällen, aber nicht an denen, die noch behandelt werden sollten)
Dada
@TheBitByte Wie ist es anstößig? Es ist eine ziemlich genaue Beschreibung, wie Männer in einem Badezimmer Urinale wählen.
mbomb007

Antworten:

3

Jelly , 13-12 Bytes

J_þTݲSiṂ$Ṭo

Probieren Sie es online! oder Überprüfen Sie alle Testfälle.

Erläuterung

J_þTݲSiṂ$Ṭo  Input: boolean array A
J             Indices, returns [1, 2, ..., len(A)]
   T          Truthy indices, returns the indices which have a truthy value
 _þ           Form the subtraction (_) table (þ) between them
    İ         Inverse, find the reciprocal of each
     ²        Square each
      S       Sum the sublists column-wise
         $    Monadic chain
        Ṃ       Minimum
       i        Find the first index of that
          Ṭ   Untruth indices, returns a boolean array with 1's at those indices
           o  Logical OR between that and A, and return
Meilen
quelle
10

MATL , 19 18 17 Bytes

lyf!Gn:-H_^Xs&X<(

Probieren Sie es online! Oder überprüfen Sie alle Testfälle (leicht modifizierter Code).

Erläuterung

Es reicht aus, die Entfernung von jeder potenziellen neuen Position zu den bereits besetzten zu berechnen. Die verbleibenden Entfernungen hängen nicht von der möglichen neuen Position ab und bilden so einen konstanten Term, der ignoriert werden kann.

Nehmen wir [1 0 0 0 0 0 1]als Beispiel die Eingabe .

l      % Push 1
       % STACK: 1
y      % Take input implicitly. Duplicate from below
       % STACK: [1 0 0 0 0 0 1], 1, [1 0 0 0 0 0 1]
f!     % Indices of nonzero elements, as a column array
       % STACK: [1 0 0 0 0 0 1], 1, [1 7]
Gn:    % Push [1 2 ... n], where n is input size (array of possible positions)
       % STACK: [1 0 0 0 0 0 1], 1, [1; 7], [1 2 3 4 5 6 7]
-      % Matrix with all pairs of differences 
       % STACK: [1 0 0 0 0 0 1], 1, [1; 7], [0 -1 -2 -3 -4 -5 -6;
                                             6  5  4  3  2  1  0]
H_^    % Raise each entry to -2
       % STACK: [1 0 0 0 0 0 1], 1, [   Inf 1.0000 0.2500 0.1111 0.0625 0.0400 0.0278;
                                     0.0278 0.0400 0.0625 0.1111 0.2500 1.0000    Inf]
Xs     % Sum of each column
       % STACK: [1 0 0 0 0 0 1], 1, [Inf 1.04 0.3125 0.2222 0.3125 1.04 Inf]
&X<    % Index of minimum. Takes the first if there is a tie
       % STACK: [1 0 0 0 0 0 1], 1, 4
(      % Assign: write 1 at the position of the minimizer
       % STACK: [1 0 0 1 0 0 1]
       % Implicitly display
Luis Mendo
quelle
4

JavaScript (ES6), 89 Byte

a=>a[a.map((e,i)=>!e&&(t=0,a.map((e,j)=>t+=(j-=i)&&e/j/j),t<m&&(m=t,k=i)),k=0,m=1/0),k]=1

Ausgabe durch Ändern des Eingabearrays.

Neil
quelle
4

R 83 76 67 Bytes

Ich habe gerade festgestellt, dass ich mehrere Bytes einsparen kann, indem ich nicht nachprüfe, ob die Kandidatenurinale leer sind. Nicht leere Urinale liefern immer einen Infunangenehmen Wert, sodass sie bei der Berechnung ausgeschlossen werden. Außerdem wird nur die direkte Indizierung verwendet replace, sodass sie kürzer, aber weniger elegant ist.

x=scan()
x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1
x

Erläuterung

x=scan()

Wir lesen den aktuellen Stand von stdin und nennen ihn x. Wir gehen davon aus, dass die Eingabe eine durch Leerzeichen oder Zeilenumbrüche getrennte Folge von 1s und 0s ist. Nehmen wir zum Zwecke der Erklärung an, wir geben ein 1 0 0 0 0 0 1.

x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1

Wir ersetzen einen Wert für xeinen bestimmten Index durch 1. Alles, was dazwischen [ ]liegt, ermittelt den besten Index.

Da die vorhandenen Urinale unveränderlich sind, müssen wir die Abstände zwischen ihnen nicht berücksichtigen. Wir müssen nur die Abstände zwischen den besetzten und den möglichen neuen Urinalen berücksichtigen. Also bestimmen wir die Indizes der besetzten Urinale. Wir verwenden whicheine Funktion, um die Indizes eines logischen Vektors zurückzugeben, die sind TRUE. Alle Zahlen in R sind, wenn sie zur Eingabe gezwungen logicalwerden, TRUEungleich Null und FALSEnull. Wenn Sie dies einfach tun, which(x)wird ein Typfehler ausgegeben argument to 'which' is not logical, ebenso xwie ein numerischer Vektor. Wir müssen es daher auf logisch zwingen. !ist die logische Negationsfunktion von R, die automatisch zu logisch zwingt. Wenn Sie es zweimal anwenden, erhalten Sie !!xeinen Vektor von TRUEundFALSEAnzeige, welche Urinale belegt sind. (Alternative Byte-äquivalent Nötigungen zu logisch beinhalten die logischen Operatoren &und |und die builtins Tund F, zum Beispiel F|xoder T&xund so weiter. !!xBlicke mehr exclamatory so wir verwenden werden.)

                                 which(!!x)

Dies ist gepaart mit seq(x), wodurch die ganzzahlige Folge von 1zu der Länge von x, dh allen Urinalstellen (und damit allen möglichen Stellen, die zu berücksichtigen sind) zurückgegeben wird.

                          seq(x)

Jetzt haben wir die Indizes unserer belegten Urinale: 1 7und unserer leeren Urinale 1 2 3 4 5 6 7. Wir übergeben `-`die Subtraktionsfunktion an die outerFunktion, um die "äußere Subtraktion" zu erhalten, bei der es sich um die folgende Matrix von Abständen zwischen allen Urinalen und den belegten Urinalen handelt:

[, 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),`-`)

Wir erheben dies zur -2Macht. (Für diejenigen, die ein wenig verloren sind, wird im OP "Unbehagen" definiert als 1 / (distance(x, y) * distance(x, y)), was vereinfacht 1/d(x,y)^2, dh d(x,y)^-2.)

                    outer(seq(x),which(!!x),`-`)^-2

Nimm die Summe jeder Zeile in der Matrix.

            rowSums(outer(seq(x),which(!!x),`-`)^-2)

Ermitteln Sie den Index des kleinsten Werts, dh des optimalen Urinals. Bei mehreren kleinsten Werten wird der erste (dh der ganz linke) zurückgegeben.

  which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))

Und voilà, wir haben den Index des optimalen Urinals. Wir ersetzen den Wert bei diesem Index in xdurch 1. Bei 1111as-Eingaben spielt es keine Rolle, welche wir ersetzen, wir haben immer noch eine gültige Ausgabe.

x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1

Gibt die geänderte Eingabe zurück.

x
rturnbull
quelle
2

PHP, 135 Bytes

$a=explode(1,$argv[1]);$b=0;foreach($a as$c=>$d){$l=strlen($d);if($l>$b){$b=$l;$e=$c;}}if($b)$a[$e][intval($b/2)]=1;echo implode(1,$a);

Ich bin mir sicher, dass es einen wesentlich schnelleren Weg gibt, aber ich habe einen verschwommenen Kopf und kann mir keinen vorstellen!

Alter Code

Der Code ohne Verkleinerung:

$a=explode(1,$argv[1]);
$b=0;
foreach($a as $c=>$d){
    $l=strlen($d);
    if($l>$b){
        $b=$l;
        $e=$c;
    }
}
if($b){
    $a[$e][intval($b/2)]=1;
}
echo implode(1,$a);
CT14.IT
quelle
2

Python 3 223 222 165 Bytes

Okay, ich weiß, das ist nicht die schönste Antwort da draußen, und ich bin sicher, es kann einiges runtergespielt werden, aber ich habe nur rumgespielt und gesehen, was ich tun kann

Die Tipps zu Whitespace und Komparatoren finden Sie unter mbomb007. Außerdem habe ich festgestellt, dass mein Online-Zeichenzähler alle Tabs in Leerzeichen umgewandelt hat, sodass die Anzahl viel geringer ist als ursprünglich

def u(a):
 m,r,x=9,0,len(a)
 for i in range(x): 
    d=0
    if a[i]<'1':
     for j in range(x):
        if a[j]>'0':d+=float((j-i)**-2)
     if d<m:r=i;m=d
 return a[:r]+'1'+a[r+1:]

Überarbeitete Leerzeichen anzeigen:

def u(a):
<sp> m,r,x=9,0,len(a)
<sp> for i in range(x): 
<tab> d=0
<tab> if a[i]<'1':
<tab><sp> for j in range(x):
<tab><tab> if a[j]>'0':d+=float((j-i)**-2)
<tab><sp> if d<m:r=i;m=d
<sp> return a[:r]+'1'+a[r+1:]

Original:

def u(a):
    m,r,x=9,0,len(a)
    for i in range(x): 
        d=0
        if a[i]!='1':
            for j in range(x):
                if a[j]=='1':d+=float(1/(j-i)**2)
            if d<m:r=i;m=d
    return a[:r]+'1'+a[r+1:]

Dies setzt voraus, dass eine Zeichenfolge von 1 und 0 übergeben wird, "10001"und gibt eine Zeichenfolge zurück"10101"

Bearbeiten: Geändert 1/float((j-i)**2)zufloat((j-i)**-2)

Biowiesel
quelle
!='1'kann sein <'1'und =='1'kann sein >'0'. Bedenken Sie auch diesen Tipp
mbomb007
Danke für diesen Whitespace-Tipp. Das wusste ich definitiv nicht. Das ist großartig!
Bioweasel
Dieser Whitespace-Tipp funktioniert meiner Meinung nach nur in Python 2. Vielleicht frühe Version von Python 3, aber idk. Sie müssen Ihre Antwort auf Python 2 oder eine bestimmte Version von 3 beschränken, damit es funktioniert.
mbomb007
Ich habe es in einer 3.5.2-Shell in IDLE laufen lassen und es läuft ohne ein Problem, also denke ich, dass es noch in Ordnung ist
Bioweasel
2

Python 3, 574 471 347 Bytes

Daran werde ich wahrscheinlich noch weiter arbeiten, wenn man bedenkt, dass die andere Python-Lösung wie ein Fünftel von dieser ist: [.

def a(I):
 D,l,r={},len(I),range
 for i in r(l):
  if I[i]<1:
   n,t,n[i]=I[:],[],1
   for j in r(l):
    if n[j]>0:
     q,Q=[],0
     for k in r(l):
      if k!=j and n[k]>0:q.append((k-j,j-k)[k<j])
     for i in q:Q+=1/(i**2)
    t.append(Q)
   T=sum(t)
   if T not in D.keys():D[T]=i
 if len(D)>0:I[D[min(D.keys())]]=1
 print(I)

Nun, das ist jetzt viel besser, da ich gelernt habe, dass Sie einzelne Leerzeichen verwenden können.

Jodler
quelle
1

Python, 165 163 158 147 141 140 139 Bytes

def u(p):e=enumerate;a=[(sum((i-j)**-2for j,y in e(p)if"0"<y),i)for i,x in e(p)if"1">x];return a and p[:min(a)[1]]+"1"+p[min(a)[1]+1:] or p
Francisco Couzo
quelle
zweite Zeile umschreiben als if"1"*len(p)==p:return p , um ein Byte zu speichern
FlipTack