Tarik magnet dalam array

20

Latar Belakang

Saya memiliki deretan magnet yang kuat dan banyak benda logam di antara mereka. Di mana magnet akan menarik mereka?

Memasukkan

Input Anda adalah array bilangan bulat non-negatif, yang akan berisi setidaknya satu 1. Anda dapat menggunakan format apa pun yang masuk akal.

The 0s array mewakili ruang kosong, dan 1s mewakili magnet tetap. Semua angka lainnya adalah benda logam, yang ditarik oleh magnet. Setiap objek akan ditarik ke arah magnet terdekat (jika ada dasi, objek tersebut ditarik ke kanan), dan ia bergerak ke arah itu hingga menyentuh magnet atau objek lain. Pada akhirnya, semua benda berkerumun di sekitar magnet. Urutan objek dipertahankan.

Keluaran

Output Anda adalah larik di mana setiap objek telah ditarik sedekat mungkin dengan magnet terdekat. Seharusnya memiliki format yang sama dengan input.

Contoh

Pertimbangkan array

[0,0,2,0,1,1,0,2,0,3,0,5,0,1,0]

Yang paling kiri 2akan ditarik ke arah pasangan magnet pertama, seperti halnya yang kedua 2. The 3memiliki magnet empat langkah di kedua arah, sehingga akan ditarik ke kanan. Yang 5juga akan ditarik ke kanan, dan itu bergerak di antara 3magnet. Output yang benar adalah

[0,0,0,2,1,1,2,0,0,0,0,3,5,1,0]

Aturan dan penilaian

Anda dapat menulis program atau fungsi lengkap. Hitungan byte terendah menang, dan celah standar tidak diizinkan.

Uji kasus

[0,1,0] -> [0,1,0]
[1,0,2,0,0,1,0] -> [1,2,0,0,0,1,0]
[7,0,5,0,0,1,0] -> [0,0,0,7,5,1,0]
[1,0,3,0,1,0,3,0,1] -> [1,0,0,3,1,0,0,3,1]
[1,0,0,0,0,0,0,7,3] -> [1,7,3,0,0,0,0,0,0]
[1,2,3,4,5,6,7,8,9,10,11,0,0,0,1] -> [1,2,3,4,5,6,7,0,0,0,8,9,10,11,1]
[12,3,0,0,1,0,1,3,0,0,6,12,0,0,0,1] -> [0,0,12,3,1,0,1,3,6,0,0,0,0,0,12,1]
Zgarb
sumber

Jawaban:

7

Pyth, 28 20

[email protected]?bhaDk_x1QkQ~hZQ

Terima kasih @ThomasKwa untuk bermain golf 6 byte!

Ini menyalahgunakan penyortiran stabil dengan menetapkan ke semua nilai 1 atau lebih besar dalam daftar indeks 1 terdekat (ikatan rusak ke paling kanan 1) dan kemudian menyortir daftar dengan nilai-nilai ini. Nol diberikan indeks mereka sendiri sebagai nilai sortir mereka.

Test Suite

Suite Verifikasi

Penjelasan:

[email protected]?bhaDk_x1QkQ~hZQ  ##  implicit: Q = eval(input())
o                  Q  ##  Sort Q using the values of the lambda below
 @              ~hZ   ##  select the value from the matching index of the enumerate
  .e           Q      ##  enumerate with b = value, k = index
    ?b                ##  ternary on b
      haDk_x1Q        ##  if true, this thing
              k       ##  otherwise use the index as the sort weight
          _x1Q        ##  the indices of 1 in Q, given in reverse order 
                      ##  (the reverse makes it sort to the right because of stable sorts)
       aDk            ##  sort those indices by |index - k|
      h               ##  take the first value

Contoh:

Ambil test case [1,0,3,0,1,0,3,0,1], misalnya. Ketika kami menerapkan enumerasi, nol semua akan mendapatkan indeks mereka sendiri sebagai nilai semacam, jadi saya akan melewati itu, dan melakukan satu dan tiga.

Untuk yang pertama, kita mendapatkan indeks yang: [0, 4, 8]. Kemudian balikkan, dan urutkan berdasarkan nilai absolut indeks dikurangi indeks yang, yang kebetulan nol di sini. Jadi kita [0, 4, 8]kembali lagi. Nilai pertama 0jadi kami menggunakannya.

Untuk ketiganya, kita mendapatkan indeks terbalik dan melakukan pengurutan yang sama tetapi menggunakan dua sebagai indeks ketiganya, jadi keduanya 0dan 4memberikan nilai yang sama untuk perbedaan absolut, jadi kita dapatkan: [4, 0, 8]dan kita ambil 4.

Maka array "nilai sorting" akhir akan menjadi [0, 1, 4, 3, 4, 5, 8, 7, 8]. Berkat jenis stabil, ikatan rusak oleh urutan nilai-nilai awalnya muncul, jadi kami mendapatkan array akhir yang kita inginkan.

FryAmTheEggman
sumber
Menyortir berdasarkan indeks terdekat 1adalah ide bagus!
Zgarb
4

Retina , 97 72 byte

+`(?<=\b1(,1*)*?)(\B,(11+)|,(11+))\b(?!(?<-1>,1*)*,1\b)|(11+),\B
$3,$4$5

Input diharapkan menjadi daftar yang dipisahkan koma dari bilangan bulat unary (pembatas terkemuka dan tambahan seperti [...]berfungsi dengan baik).

Jalankan semua test case di sini. (Untuk kenyamanan, ini menangani konversi dari dan ke desimal secara otomatis.)

Ini adalah ide yang sangat berbeda yang menghindari kelompok penyeimbang yang mahal dengan menggunakan beberapa tahap. Saat ini 6 byte lebih panjang, tetapi mungkin lebih golf:

,1\b
>1
\b1,
1<
(T`,`<`<1*,
)T`,`>`,1*>
+`(1+>)>
>$1
+`<(<1+\b)(?!>)
$1<
<|>
,
Martin Ender
sumber
Begitu saya melihat tantangan ini, saya pikir Retina akan cocok (+1)
Michael Klein
@MichaelKlein Terima kasih, tapi saya tidak berpikir itu benar. Saya terkejut bahkan mengalahkan JavaScript, tapi saya cukup yakin itu tidak akan bertahan melawan salah satu bahasa golf.
Martin Ender
Sangat cocok karena saya segera mulai berpikir bagaimana menyelesaikannya di Retina
Michael Klein
3

JavaScript (ES6), 108 byte

a=>a.map(_=>a.map((x,i)=>x>1?a[j=(n=a.indexOf(1,i))<0|n-i>i-p?i-1:i+1]?0:a[a[i]=0,j]=x:x<1?0:p=i,p=-1/0))&&a

Penjelasan

Iterasi setiap sel dan jika mengandung logam, periksa apakah sel berikutnya dalam arah magnet terdekat kosong, dan jika ya, gerakkan ke sana. Proses ini diulang berkali-kali sampai semua logam bergerak sejauh mungkin.

var solution =

a=>
  a.map(_=>                  // loop a.length times to ensure completeness
    a.map((x,i)=>            // for each cell item x at index i
      x>1?                   // if the cell contains metal
        a[j=                 // j = index of cell to move to
          (n=a.indexOf(1,i)) // n = index of next magnet
          <0|n-i>i-p?i-1:i+1 // set j to previous or next cell based on closest magnet
        ]?0:                 // if cell j is empty
          a[a[i]=0,j]=x      // set it to x and set cell i to 0
      :x<1?0:                // else if the cell contains a magnet
        p=i,                 // set p to the index of this magnet
      p=-1/0                 // p = index of previous magnet, initialise to -Infinity
    )
  )
  &&a                        // return a
<input type="text" id="input" value="1,2,3,4,5,6,7,8,9,10,11,0,0,0,1" />
<button onclick="result.textContent=solution(input.value.split(',').map(n=>+n))">Go</button>
<pre id="result"></pre>

pengguna81655
sumber
2

PHP, 337 karakter

<?$i=explode(",",$argv[1]);$m=$n=[];foreach($i as$k=>$v)if($v>0)eval("array_push(\$".($v<2?"m":"n").",$k);");for($p=0;$p<count($i);$p++)foreach($i as$k=>$v)if($v>1){$i[$k]=0;$r=-1;foreach($m as$_)if($r<0||abs($k-$r)>abs($_-$k))$r=$_;while($i[$r]>0)$r+=($r<$k?1:-1);$i[$r]=$v;}$s="";foreach($i as$v)$s.=$v.",";echo substr($s,0,-1)."\n";?>

Ya ini sangat panjang, karena PHP sebenarnya bukan bahasa untuk bermain golf, tetapi ia berfungsi dan saya MENYENANGKAN, jadi tidak masalah bagi saya. Tentu saja saya terbuka untuk kemungkinan kekurangan.

Juga ada fitur bug kecil yang berpikir, jadi misalnya di sini:

root@raspberrypi:~/stack# php magnet.php 12,3,0,0,1,0,1,3,0,0,6,12,0,0,0,1
0,0,3,12,1,0,1,3,6,0,0,0,0,0,12,1

kelihatannya 12 ajaib itu ada di depan 3, tapi itu tidak benar!

3 menghormati jumlah yang lebih besar dan membiarkannya mendekati maget!

timmyRS
sumber