Konumsal Banyo Görgü Kuralları


24

Arka fon

Banyo Etiketi, mevcut pisuarlara ait olduğunda, doldurulacak bir sonraki pisuarın toplam rahatsızlığı en aza indiren bir olması gerektiğini belirtir. Toplam rahatsızlık denklemi, aşağıdaki denklem grubundan verilir:

dist (x, y) = idrar birimlerinde x kişi ve y kişi arasındaki doğrusal mesafe
 rahatsızlık (x) = x kişi hariç tüm kişiler için toplam (1 / (dist (x, y) * dist (x, y)))
 total_Discomfort = tüm x için toplam (rahatsızlık (x))

Benzer (tam olarak aynı değil) problemi ile ilgili daha derinlemesine bir makaleye buradan ulaşabilirsiniz: (Beni bu şaşırtıcı teknik incelemeye uyardığın için @ Lembik'e teşekkürler!)


Giriş çıkış

Boş ve dolu pisuarların bir girişi verildiğinde, elde edilen pisuar setini bir kişinin eklenmesi ile alın. Bir pozisyon için bir bağ varsa pisuarların soldan sağa doldurması gerekir. Çıkış, giriş ile aynı formatta olmalıdır.

  • Tam pisuar bulunan bir vaka verilirse, girişi döndürün.
  • Girdi her zaman tanımlanmış en az bir pisuar içerecektir.


Test Kılıfları

GİRİŞ -> ÇIKIŞ
1000001 -> 1001001
101010101 -> 111010101
100 -> 101
00000 -> 10000
1111111 -> 1111111
0100 -> 0101
101000 -> 101001


kurallar

Bu , bayt cinsinden en kısa kod kazanır. Standart ilmek delikleri yasaktır.



1
Bir cevabı kabul etmeden önce yaklaşık bir hafta beklemeniz önerilir. Bir günden az bir sürede kabul etmek, zorla aldığınız cevapların miktarını azaltabilir.
Emigna

1
Ekleme 0100ve 101000test vakalarında önerebilirim (bazı regex tabanlı yaklaşımlar gerçek sınav durumlarında işe yarıyor, ancak hala yapılması gerekenler üzerinde çalışmıyor)
Dada


@TheBitByte Nasıl saldırgan? Erkeklerin tuvalette pisuarları nasıl seçtikleri hakkında oldukça doğru bir açıklama.
mbomb007 11:16

Yanıtlar:


3

Jöle , 13 12 bayt

J_þTݲSiṂ$Ṭo

Çevrimiçi deneyin! veya Tüm test durumlarını doğrulayın.

açıklama

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 bayt

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

Çevrimiçi deneyin! Veya tüm test durumlarını doğrulayın (biraz değiştirilmiş kod).

açıklama

Her potansiyel yeni konumdan zaten işgal edilmiş olanlara olan mesafeyi hesaplamak yeterlidir. Kalan mesafeler potansiyel yeni pozisyona bağlı değildir ve bu nedenle göz ardı edilebilecek sabit bir terim oluşturur.

[1 0 0 0 0 0 1]Örnek olarak girdi alalım.

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 bayt

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

Giriş dizisini değiştirerek çıktı verir.


4

R, 83 76 67 bayt

Aday pisuarların boş olup olmadığını kontrol etmek için canınızı sıkmadan birkaç byte tasarruf edebileceğimi farkettim. Boş olmayan pisuarlar her zaman bir Infrahatsızlık değeri döndürür , bu nedenle hesaplama sırasında dışlanırlar. Ayrıca, doğrudan değil doğrudan dizin kullanarak replace, bu yüzden daha kısa ama daha az zarif.

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

açıklama

x=scan()

Şu anki durumu stdin'den okuyoruz ve diyoruz x. Girdilerin boşluk veya yeni satırlarla ayrılmış 1s ve 0s dizisi olduğunu varsayıyoruz . Açıklama amacıyla diyelim ki girelim 1 0 0 0 0 0 1.

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

xBelirli bir dizindeki değeri 1 ile değiştiririz. Arasındaki her şey [ ]en iyi dizinin ne olduğunu bulmaktır.

Mevcut pisuarlar değişmez olduğu için, aralarındaki mesafeleri düşünmemize gerek yoktur. Sadece işgal edilmiş pisuarlar ve olası yenileri arasındaki mesafeleri göz önünde bulundurmamız gerekir. Bu yüzden işgal altındaki pisuarların indekslerini belirliyoruz. whichMantıksal bir vektörün indekslerini döndüren bir fonksiyon kullanıyoruz TRUE. R Tüm sayılar, türüyle zaman logicalvardır TRUESıfır dışındaki eğer FALSEsıfır ise. Basitçe yapmak which(x), sayısal bir vektörde olduğu argument to 'which' is not logicalgibi bir tür hatayla sonuçlanır x. Bu nedenle mantıklı olmaya zorlamalıyız. !R'nin otomatik olarak mantığa zorlayan mantıksal olumsuzlama işlevidir. İki kez uygulayarak !!x, bir vektör verir TRUEveFALSEhangi pisuarların işgal edildiğini gösterir. (Mantıksal için alternatif bayt eşdeğer zorlamalar, mantıksal operatörleri &ve |ve yerleşikleri içerir Tve Förneğin F|xveya T&xdiğerleri !!xvb.

                                 which(!!x)

Bu, seq(x)tamsayı sırasını 1uzunluğuna x, yani tüm pisuar konumlarına (ve dolayısıyla göz önünde bulundurulacak tüm olası konumlara) geri döndüren eşleştirilir .

                          seq(x)

Şimdi işgal edilmiş pisuvarlarımızın indeksleri var: 1 7boş pisuarlarımız 1 2 3 4 5 6 7. Biz geçmesi `-`için, toplama, çıkarma işlevi outertüm pisuar ve işgal pisuar arasındaki mesafeleri aşağıdaki matristir "dış çıkarma", almak için işlevi:

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

Bunu -2inci gücüne yükseltiriz . (Biraz kaybedilenler için OP'de "rahatsızlık" yani 1 / (distance(x, y) * distance(x, y))basitleştirici olarak tanımlanmaktadır .)1/d(x,y)^2d(x,y)^-2

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

Matristeki her satırın toplamını alın.

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

En küçük değerin dizinini alın, yani en uygun pisuar. En küçük değerlerin çoklu olması durumunda, ilk (yani en solda) bir geri döndürülür.

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

Ve voilà, en uygun pisuarın indeksine sahibiz. Biz bu endeksine değerini değiştirmek xile 1. 1111Girdi durumunda, hangisini değiştirdiğimiz önemli değil, yine de geçerli bir çıktı elde edeceğiz.

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

Değiştirilen girişi döndürün.

x

2

PHP, 135 bayt

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

Bunu yapmanın çok daha hızlı bir yolu olduğundan eminim, ancak bulanık bir kafa var ve birini düşünemiyorum!

Eski kod

Minyatür olmayan kod:

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

Tamam, buranın en güzel cevabı olmadığını biliyorum ve eminim biraz golf oynayabiliyordum, ama sadece etrafı karıştırıp ne yapabileceğimi görüyordum.

Beyaz boşluk ve karşılaştırıcılarla ilgili ipuçları için mbomb007'ye not edin Ayrıca çevrimiçi karakter sayacımın tüm sekmeleri alıp boşluklara çevirdiğini gördüm, bu yüzden sayım başlangıçta sahip olduğumdan çok daha az

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

Gözden geçirilmiş boşluk gösteriliyor:

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

Orijinal:

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

Bu, 1'lerin "10001"ve 0'ların benzerlerine iletilen bir dize bekler ve bir dize döndürür"10101"

Düzenleme: Değiştirildi 1/float((j-i)**2)içinfloat((j-i)**-2)


!='1'olabilir <'1've =='1'olabilir >'0'. Ayrıca, bu ipucunu
mbomb007

Bu boşluk ipucu için teşekkürler. Bunu kesinlikle bilmiyordum. Bu harika!
bioweasel

Bu boşluk ipucu sadece Python 2'de çalışıyor sanırım. Belki Python 3'ün erken sürümü, ama idk. Cevabınızı Python 2 ile veya 3'ün belirli sürümleriyle sınırlandırmanız gerekecek.
mbomb007


2

Python 3, 574 471 347 bayt

Muhtemelen bu konuda biraz daha çalışacağım, diğer Python çözümünün bunun beşte biri olduğunu düşünerek: [.

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)

Eh, şimdi öğrendiğim kadarıyla tek boşluk kullanabileceğini çok daha iyi.


1

Python, 165 163 158 147 141 140 139 bayt

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

if"1"*len(p)==p:return pbir baytı kaydedecek şekilde ikinci satırı yeniden yazar
FlipTack
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.