Etiket Kamar Mandi Posisi

24

Latar Belakang

Etiket Kamar Mandi, ketika berkaitan dengan urinal yang tersedia, menyatakan bahwa urinoir berikutnya yang harus diisi adalah urin yang meminimalkan ketidaknyamanan total. Persamaan ketidaknyamanan total diberikan oleh set persamaan berikut:

dist (x, y) = jarak linear antara orang x dan orang y dalam ketidaknyamanan Unit Urinal
 (x) = jumlah (1 / (dist (x, y) * dist (x, y))) untuk semua orang y tidak termasuk orang x
 total_Discomfort = jumlah (ketidaknyamanan (x)) untuk semua x

Makalah yang lebih mendalam berurusan dengan masalah yang serupa (tidak persis sama) dapat ditemukan di sini: (Terima kasih kepada @Lembik karena telah mengingatkan saya pada whitepaper yang menakjubkan ini!)


Input output

Diberikan input dari urinal yang kosong dan penuh, output set urinal yang dihasilkan dengan penambahan satu orang. Jika ada dasi untuk posisi urinal harus mengisi kiri ke kanan. Output harus dalam format yang sama dengan input.

  • Jika diberi case dengan urinal penuh, kembalikan input.
  • Input akan selalu memiliki setidaknya satu urinoir yang ditentukan.


Uji Kasus

INPUT -> OUTPUT
1000001 -> 1001001
101010101 -> 111010101
100 -> 101
00000 -> 10.000
1111111 -> 1111111
0100 -> 0101
101000 -> 101001


Aturan

Ini adalah , jadi kode terpendek dalam byte menang. Lubang loop standar dilarang.

Nick Frev
sumber
1
Disarankan untuk menunggu sekitar satu minggu sebelum menerima jawaban. Menerima dalam waktu kurang dari sehari dapat mengurangi jumlah jawaban yang diterima tantangan Anda.
Emigna
1
Saya sarankan menambahkan 0100dan 101000dalam kasus uji (beberapa pendekatan berbasis regex bekerja pada kasus uji yang sebenarnya tetapi tidak akan bekerja pada kasus-kasus yang masih harus ditangani)
Dada
@TheBitByte Bagaimana itu menyinggung? Ini adalah deskripsi yang cukup akurat tentang bagaimana pria memilih urinal di kamar mandi.
mbomb007

Jawaban:

3

Jelly , 13 12 byte

J_þTݲSiṂ$Ṭo

Cobalah online! atau Verifikasi semua kasus uji.

Penjelasan

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
mil
sumber
10

MATL , 19 18 17 byte

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

Cobalah online! Atau verifikasi semua kasus uji (kode yang sedikit dimodifikasi).

Penjelasan

Cukuplah untuk menghitung jarak dari setiap posisi baru potensial ke posisi yang sudah ditempati. Jarak yang tersisa tidak tergantung pada posisi baru potensial, dan karenanya merupakan istilah yang konstan, yang dapat diabaikan.

Mari kita ambil input [1 0 0 0 0 0 1]sebagai contoh.

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
sumber
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

Output dengan memodifikasi array input.

Neil
sumber
4

R, 83 76 67 byte

Baru menyadari bahwa saya dapat menyimpan beberapa byte dengan tidak repot memeriksa apakah kandidat urinal kosong. Ural yang tidak kosong akan selalu mengembalikan Infnilai ketidaknyamanan, sehingga tidak dimasukkan dalam perhitungan. Juga, hanya menggunakan pengindeksan langsung daripada replace, jadi lebih pendek tapi kurang elegan.

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

Penjelasan

x=scan()

Kami membaca status saat ini dari stdin dan menyebutnya x. Kami berasumsi bahwa input adalah urutan 1s dan 0s dipisahkan oleh spasi atau baris baru. Untuk keperluan penjelasan, misalkan kita masukan 1 0 0 0 0 0 1.

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

Kami mengganti nilai xpada indeks tertentu dengan 1. Segala sesuatu di antara [ ]ini mencari tahu apa indeks terbaik.

Karena urinal yang ada tidak berubah, kita tidak perlu mempertimbangkan jarak di antara mereka. Kita hanya perlu mempertimbangkan jarak antara urinal yang ditempati dan kemungkinan yang baru. Jadi kami menentukan indeks urinal yang diduduki. Kami menggunakan which, fungsi untuk mengembalikan indeks vektor logis TRUE. Semua angka dalam R, ketika dipaksa untuk mengetik logical, adalah TRUEjika bukan nol dan FALSEjika nol. Cukup melakukan which(x)akan menghasilkan kesalahan ketik argument to 'which' is not logical,, seperti xvektor numerik. Karena itu kami harus memaksanya masuk akal. !adalah fungsi negasi logis R, yang secara otomatis memaksa ke logis. Menerapkannya dua kali !!x,, menghasilkan vektor TRUEdanFALSEmenunjukkan urinal mana yang ditempati. (Alternatif paksaan setara byte untuk logika melibatkan operator logika &dan |dan builtin Tdan F, misalnya F|xatau T&xseterusnya. !!xTerlihat lebih seram sehingga kita akan menggunakannya.)

                                 which(!!x)

Ini dipasangkan dengan seq(x), yang mengembalikan urutan bilangan bulat dari 1panjang x, yaitu semua lokasi urinoir (dan dengan demikian semua lokasi yang memungkinkan untuk dipertimbangkan).

                          seq(x)

Sekarang kita memiliki indeks urinal kita yang diduduki: 1 7dan urinal kita yang kosong 1 2 3 4 5 6 7. Kami lulus `-`, fungsi pengurangan, ke outerfungsi untuk mendapatkan "pengurangan luar", yang merupakan matriks jarak berikut antara semua urinal dan urinal yang ditempati:

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

Kami mengangkat ini ke -2kekuatan th. (Bagi mereka yang sedikit tersesat, dalam OP, "ketidaknyamanan" didefinisikan sebagai 1 / (distance(x, y) * distance(x, y)), yang menyederhanakan 1/d(x,y)^2, yaitu d(x,y)^-2.)

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

Ambil jumlah setiap baris dalam matriks.

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

Dapatkan indeks nilai terkecil, yaitu urinal optimal. Dalam kasus beberapa nilai terkecil, yang pertama (yaitu paling kiri) dikembalikan.

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

Dan voila, kami memiliki indeks urinal optimal. Kami mengganti nilai pada indeks ini xdengan 1. Dalam hal 1111sebagai input, tidak masalah yang mana yang kami ganti, kami masih akan memiliki output yang valid.

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

Kembalikan input yang dimodifikasi.

x
rturnbull
sumber
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);

Saya yakin ada cara yang jauh lebih cepat untuk melakukannya, tetapi saya memiliki kepala yang kabur dan tidak dapat memikirkannya!

Kode lama

Kode tanpa minifikasi:

$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
sumber
2

Python 3 223 222 165 Bytes

Oke, saya tahu ini bukan jawaban tercantik di luar sana, dan saya yakin itu bisa diturunkan sedikit, tapi saya hanya main-main dan melihat apa yang bisa saya lakukan

Berteriak ke mbomb007 untuk tips tentang ruang putih dan pembanding

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

Menampilkan ruang putih yang direvisi:

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

Asli:

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

Ini mengharapkan string yang diteruskan menjadi seperti 1 dan 0 "10001"dan mengembalikan string"10101"

Edit: Diubah 1/float((j-i)**2)menjadifloat((j-i)**-2)

bioweasel
sumber
!='1'bisa <'1'dan =='1'bisa >'0'. Juga, pertimbangkan tip ini
mbomb007
Terima kasih atas tip spasi putih itu. Saya pasti tidak tahu itu. Itu luar biasa!
bioweasel
Tip spasi putih itu hanya berfungsi di Python 2, saya pikir. Mungkin versi awal Python 3, tetapi idk. Anda harus membatasi jawaban Anda ke Python 2 atau versi 3 tertentu agar bisa berfungsi.
mbomb007
Saya menjalankannya dalam shell 3.5.2 di IDLE dan itu berjalan tanpa masalah, jadi saya pikir tidak apa-apa
bioweasel
2

Python 3, 574 471 347 byte

Saya mungkin akan mengerjakan ini lagi, mengingat solusi Python lainnya seperti seperlima dari yang ini: [.

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)

Nah itu jauh lebih baik sekarang karena saya telah belajar Anda dapat menggunakan spasi tunggal.

Yodle
sumber
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
sumber
tulis ulang baris kedua if"1"*len(p)==p:return puntuk menghemat satu byte
FlipTack