Etiqueta posicional do banheiro


24

fundo

A etiqueta do banheiro, ao pertencer aos mictórios disponíveis, afirma que o próximo mictório a ser preenchido deve ser o que minimiza o desconforto total. A equação de desconforto total é dada pelo seguinte conjunto de equações:

dist (x, y) = distância linear entre a pessoa x e a pessoa y em unidades de mictório
 desconforto (x) = soma (1 / (dist (x, y) * dist (x, y))) para todas as pessoas y excluindo a pessoa x
 total_Desconforto = soma (desconforto (x)) para todos os x

Um artigo mais aprofundado que lida com um problema semelhante (não exatamente o mesmo) pode ser encontrado aqui: (Obrigado ao @Lembik por me alertar sobre este incrível whitepaper!)


Entrada / Saída

Dada a entrada de um mictório vazio e cheio, produza o conjunto resultante de mictórios com a adição de uma pessoa. Se houver um empate em uma posição, os mictórios devem ser preenchidos da esquerda para a direita. A saída deve estar no mesmo formato que a entrada.

  • Se houver um caso com mictórios cheios, retorne a entrada.
  • A entrada sempre terá pelo menos um urinol definido.


Casos de teste

ENTRADA -> SAÍDA
1000001 -> 1001001
101010101 -> 111010101
100 -> 101
00000 -> 10000
1111111 -> 1111111
0100 -> 0101
101000 -> 101001


Regras

Isso é , então o código mais curto em bytes vence. São proibidos os orifícios padrão.



11
Recomenda-se esperar cerca de uma semana antes de aceitar uma resposta. Aceitar em menos de um dia pode diminuir a quantidade de respostas que seu desafio recebe.
Emigna

11
Eu sugiro adicionando 0100e 101000nos casos de teste (alguns baseados em regex trabalho abordagem sobre os casos de teste reais, mas não funcionará em aqueles que ainda deve ser manuseado)
Dada


@TheBitByte Como é ofensivo? É uma descrição bastante precisa de como os homens escolhem mictórios no banheiro.
mbomb007

Respostas:


3

Geléia , 13 12 bytes

J_þTݲSiṂ$Ṭo

Experimente online! ou Verifique todos os casos de teste.

Explicação

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 bytes

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

Experimente online!Ou verifique todos os casos de teste (código ligeiramente modificado).

Explicação

Basta calcular a distância de cada nova posição potencial até as já ocupadas. As distâncias restantes não dependem da nova posição potencial e, portanto, constituem um termo constante, que pode ser ignorado.

Vamos dar [1 0 0 0 0 0 1]um exemplo como exemplo.

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 bytes

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

Saídas modificando a matriz de entrada.


4

R, 83 76 67 bytes

Acabei de perceber que posso salvar vários bytes, sem me preocupar em verificar se os mictórios candidatos estão vazios. Mictórios não vazios sempre retornam um Infvalor de desconforto, portanto são excluídos no decorrer do cálculo. Além disso, basta usar a indexação direta em vez de replace, portanto, é mais curto, mas menos elegante.

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

Explicação

x=scan()

Lemos o estado atual de stdin e o chamamos x. Nós assumimos que a entrada é uma sequência de 1s e 0s separados por espaços ou novas linhas. Para os fins da explicação, digamos que inserimos 1 0 0 0 0 0 1.

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

Substituímos um valor de xum índice específico por 1. Tudo entre o [ ]é descobrir qual é o melhor índice.

Como os mictórios existentes são imutáveis, não precisamos considerar as distâncias entre eles. Só precisamos considerar as distâncias entre os mictórios ocupados e o possível novo. Então, determinamos os índices dos mictórios ocupados. Usamos whichuma função para retornar os índices de um vetor lógico que são TRUE. Todos os números em R, quando forçados a digitar logical, são TRUEdiferentes de zero e FALSEzero. Simplesmente which(x)resultará em um erro de tipo argument to 'which' is not logical, como xé um vetor numérico. Portanto, temos que coagi-lo à lógica. !é a função de negação lógica de R, que obriga automaticamente a lógica. A aplicação duas vezes, !!xproduz um vetor de TRUEeFALSE indicando quais mictórios estão ocupados. (Coerções alternativas equivalentes a bytes para lógicas envolvem os operadores lógicos& e |e os builtins Te F, por exemplo, F|xou T&xe assim por diante. !!xAparência mais exclamatory por isso vamos usar isso.)

                                 which(!!x)

Isso é emparelhado com seq(x), que retorna a sequência inteira 1do comprimento de x, ou seja, todos os locais do mictório (e, portanto, todos os locais possíveis a serem considerados).

                          seq(x)

Agora temos os índices de nossos mictórios ocupados: 1 7e nossos mictórios vazios 1 2 3 4 5 6 7. Passamos `-`, a função de subtração, para a outerfunção de obter a "subtração externa", que é a seguinte matriz de distâncias entre todos os urinóis e os urinóis ocupados:

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

Nós elevamos isso ao -2poder th. (Para aqueles que estão um pouco perdidos, no OP, "desconforto" é definido como 1 / (distance(x, y) * distance(x, y)), o que simplifica para 1/d(x,y)^2, ie d(x,y)^-2.)

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

Pegue a soma de cada linha na matriz.

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

Obtenha o índice do menor valor, ou seja, o urinol ideal. No caso de vários valores menores, o primeiro (ou seja, mais à esquerda) é retornado.

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

E, voilà, temos o índice do mictório ideal. Substituímos o valor nesse índice xpor 1. No caso de 1111como entrada, não importa qual substituímos, ainda teremos uma saída válida.

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

Retorne a entrada modificada.

x

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

Tenho certeza de que há uma maneira consideravelmente mais rápida de fazê-lo, mas tenho uma cabeça confusa e não consigo pensar em uma!

Código antigo

O código sem minificação:

$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 bytes

Ok, eu sei que essa não é a resposta mais bonita do mundo, e eu tenho certeza que ela pode ser um pouco melhor, mas eu estava apenas brincando e vendo o que eu poderia fazer

Grite ao mbomb007 para obter dicas sobre espaços em branco e comparadores Além disso, eu vi meu contador de caracteres on-line pegando todas as guias e as transformando em espaços, então a contagem é muito menor do que eu originalmente

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

Mostrando espaço em branco revisado:

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

Isso espera que uma string seja passada de 1 e 0 "10001"e retorne uma string"10101"

Editar: alterado 1/float((j-i)**2)parafloat((j-i)**-2)


!='1'pode ser <'1'e =='1'pode ser >'0'. Além disso, considere esta dica
mbomb007 1/16

Obrigado por essa dica de espaço em branco. Eu definitivamente não sabia disso. Fantástico!
Bioweasel 1/11

Essa dica de espaço em branco só funciona no Python 2, eu acho. Talvez versão inicial do Python 3, mas idk. Você terá que restringir sua resposta ao Python 2 ou alguma versão específica do 3 com ele funcionando.
Mbomb007 1/11

Eu tenho que correr em uma concha 3.5.2 em IDLE e ele está correndo sem um problema, então eu acho que está tudo bem ainda
bioweasel

2

Python 3, 574 471 347 bytes

Provavelmente vou trabalhar nisso um pouco mais, considerando que a outra solução Python é como um quinto desta: [.

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)

Bem, isso é muito melhor agora que aprendi que você pode usar espaços únicos.


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

reescreva a segunda linha if"1"*len(p)==p:return ppara salvar um byte
FlipTack 1/16
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.