Etichetta del bagno di posizione


24

sfondo

L'etichetta del bagno, quando si tratta degli orinatoi disponibili, afferma che il prossimo orinatoio da riempire dovrebbe essere quello che minimizza il disagio totale. L'equazione del disagio totale è data dalla seguente serie di equazioni:

dist (x, y) = distanza lineare tra la persona xe la persona y nel disagio delle Unità orinatoi
 (x) = somma (1 / (dist (x, y) * dist (x, y))) per tutte le persone y esclusa la persona x
 total_Discomfort = sum (discomfort (x)) per tutti x

Un documento più approfondito che affronta un problema simile (non esattamente lo stesso) può essere trovato qui: (Grazie a @Lembik per avermi avvisato di questo fantastico white paper!)


Input Output

Dato un input di orinatoi vuoti e pieni, produce l'insieme di orinatoi risultante con l'aggiunta di una persona. Se esiste un pareggio per una posizione, gli orinatoi devono riempire da sinistra a destra. L'output deve essere nello stesso formato dell'input.

  • Se viene fornito un caso con orinatoi completi, restituire l'input.
  • L'ingresso avrà sempre almeno un orinatoio definito.


Casi test

INGRESSO -> USCITA
1000001 -> 1001001
101010101 -> 111010101
100 -> 101
00000 -> 10000
1111111 -> 1111111
0100 -> 0101
101000 -> 101001


Regole

Questo è , quindi vince il codice più breve in byte. Sono vietati i fori standard.



1
Si consiglia di attendere circa una settimana prima di accettare una risposta. Accettare in meno di un giorno potrebbe ridurre la quantità di risposte ricevute dalla tua sfida.
Emigna,

1
Suggerirei di aggiungere 0100e 101000nei casi di test (alcuni approcci basati su regex funzionano sugli effettivi casi di test ma non funzioneranno su quelli che dovrebbero ancora essere gestiti)
Dada


@TheBitByte Com'è offensivo? È una descrizione abbastanza accurata di come gli uomini scelgono gli orinatoi in un bagno.
mbomb007,

Risposte:


3

Gelatina , 13 12 byte

J_þTݲSiṂ$Ṭo

Provalo online! oppure Verifica tutti i casi di test.

Spiegazione

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

10

MATL , 19 18 17 byte

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

Provalo online! Oppure verifica tutti i casi di test (codice leggermente modificato).

Spiegazione

È sufficiente calcolare la distanza da ogni potenziale nuova posizione a quelle già occupate. Le distanze rimanenti non dipendono dalla nuova potenziale posizione e quindi costituiscono un termine costante, che può essere ignorato.

Prendiamo l'input [1 0 0 0 0 0 1]come esempio.

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

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

Emette modificando l'array di input.


4

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

2

PHP, 135 byte

$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);

Sono sicuro che c'è un modo considerevolmente più veloce di farlo, ma ho una testa confusa e non riesco a pensarne uno!

Vecchio codice

Il codice senza minificazione:

$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);

2

Python 3 223 222 165 byte

Okay, so che questa non è la risposta più bella là fuori, e sono sicuro che può essere giocato un bel po ', ma stavo solo scherzando e vedendo cosa potevo fare

Grida a mbomb007 per i suggerimenti su spazi bianchi e comparatori Inoltre, ho visto che il mio contatore di personaggi online stava prendendo tutte le schede e le trasformava in spazi, quindi il conteggio è molto inferiore a quello che avevo originariamente

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:]

Visualizzazione degli spazi bianchi modificati:

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:]

Originale:

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:]

Questo si aspetta una stringa passata come 1 e 0 "10001"e restituisce una stringa"10101"

Modifica: modificato 1/float((j-i)**2)infloat((j-i)**-2)


!='1'può essere <'1'e =='1'può essere >'0'. Inoltre, considera questo suggerimento
mbomb007,

Grazie per quel suggerimento sugli spazi bianchi. Di certo non lo sapevo. È fantastico!
bioweasel

Quel suggerimento per gli spazi bianchi funziona solo in Python 2, credo. Forse la prima versione di Python 3, ma idk. Dovrai limitare la tua risposta a Python 2 o ad una versione specifica di 3 affinché funzioni.
mbomb007,

L'ho fatto funzionare in una shell 3.5.2 in IDLE e funziona senza problemi, quindi penso che
vada

2

Python 3, 574 471 347 byte

Probabilmente ci lavorerò ancora un po ', considerando che l'altra soluzione Python è come un quinto di questo: [.

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)

Bene, è molto meglio ora che ho imparato che puoi usare singoli spazi.


1

Python, 165 163 158 147 141 140 139 byte

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

riscrivi la seconda riga if"1"*len(p)==p:return pper salvare un byte
FlipTack
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.