Kontrol Gravitasi

8

Tugas Anda adalah menemukan total tujuan objek yang jatuh ke sebuah planet, Anda akan mendapatkan input seperti ini:

7
...#...     
.......  
#..O..#
.......  
...#...
.......
.......

di mana O adalah planet dan # adalah objek, perhatikan bahwa planet akan menarik objek dari untuk arah dasar (BERITA). Anda harus mengeluarkan:

    #
   #O#
    #

yaitu objek setelah mencapai tujuannya.

Angka pertama yang diberikan sebagai input adalah panjang kisi (nxn), dalam contoh di atas adalah 7.

Objek harus selalu bergerak dalam arah terpendek (perhatikan bahwa arah yang diperbolehkan hanya horisontal dan vertikal; objek tidak dapat bergerak secara diagonal)

Jika suatu objek berjarak sama dari dua arah, arahnya harus sesuai dengan arah jam:

    ..#       
    ...  
    O..  

Akan mencapai sisi ini:

    ...
    ...
    O#.

Jika suatu benda bertabrakan dengan planet ini, ia akan berhenti. Jika bertabrakan dengan objek lain mereka menjadi satu objek,

 4
 .#..
 #...
 ....  
 .O..

akan menjadi:

  ....
  ....
  .#..
  .O..

Satu contoh terakhir:

6
..#...
.#....
......
.#O...
....#.
......

Keluaran:

......
......
..#...
.#O#..
......
......

Catatan: Anda harus menampilkan bentuk akhir, sehingga semua keluaran diterima selama menunjukkan bentuk akhir dari planet ini.

misalnya untuk input ini:

...#
....
.O..
....

Haruskah output:

O#

atau

....
....
.O#.
....

Keduanya diterima.

Ini sehingga jawaban terpendek akan menang

Catatan 2:

Seperti yang mungkin Anda perhatikan, itu .merupakan vaccum sehingga jalur terpendek adalah jumlah titik terpendek.

Sebagai contoh:

.#.
...
.O.

Tidak diterima

O#

karena jalur terpendek adalah vertikal. Catatan 3:

Objek harus selalu bergerak sejajar dengan planet di salah satu dari empat arah (memilih yang terpendek)

     |<#
     |
     |  
-----O------
     |

Pembatasan:

2 <= n <= 100

Mhmd
sumber
Berapa ukuran input yang mungkin?
undergroundmonorail
2
Tolong jelaskan "arah terpendek."
Ken A
@ KenAA saya pikir itu bisa diulangi seperti: objek bergerak secara diagonal menuju planet sampai mereka sejajar dengan planet (setelah itu mereka akan bergerak lurus menuju planet); jika suatu benda akhirnya menyentuh planet secara diagonal, gerakkan satu langkah terakhir ke arah berlawanan arah jarum jam. Ini harus mengarah pada hasil yang sama dengan spesifikasi OP. Tetapi klarifikasi oleh OP akan menyenangkan.
Martin Ender
Saya perhatikan contoh Anda di atas memiliki spasi spasi di akhir beberapa baris. Apakah aman untuk menganggap hal yang sama mungkin benar dari input yang diharapkan akan ditangani oleh program?
skibrianski
@skib no. Mungkin salah ketik tetapi input tidak memiliki spasi spasi.
Mhmd

Jawaban:

2

Perl, 156 153 148

$n=$_+1;
s/.+\n//;
$o=index$_,O;
$x=$o%$n-$-[0]%$n,
pos=$o+(($==($o-$-[0])/$n)&&$x/$=>-1&&$x/$=<=1?$=>0?-$n:$n:0<=>$x),
s/\G./x/ while s/#/./;
y/x/#/

Baris baru untuk keterbacaan. Jalankan dengan -0777p(5 ditambahkan ke hitungan), masukan melalui STDIN.

Lebih mudah dibaca:

$n=$_+1;
s/.+\n//;
$o=index$_,O;
while(s/#/./){
    $x=$o%$n-$-[0]%$n;
    $==($o-$-[0])/$n;
    pos=$o+(
        $=
        &&$x/$=>-1
        &&$x/$=<=1
            ?$=>0
                ?-$n
                :$n
            :0<=>$x

    );
    s/\G./x/
}
y/x/#/
pengguna2846289
sumber
Wow oO =) penjelasan lebih lanjut akan menyenangkan bagi mereka yang tidak akrab dengan mesin re Perl dan variabel khusus.
skibrianski
@skibrianski, terima kasih. Meskipun saya tidak melakukan sesuatu yang istimewa dan lebih mudah bagi saya untuk menjawab setelah catatan ditambahkan ke OP, Anda benar: kita harus mendokumentasikan kode kita.
user2846289
Apa yang mungkin tidak jelas pada pandangan pertama adalah menggunakan $=variabel 'magick' (yang bisa hanya bilangan bulat - menyelamatkan kita 5 karakter 'int ()'), dan menggunakan \Gjangkar dalam pola pencarian. Di sini kita mengatur posisinya dengan menetapkan ke posfungsi (yang argumen default-nya $_)
user2846289
6

Mathematica, 206 byte

f=(m=Characters@StringSplit@#;o=#-Join@@m~(p=Position)~"O"&/@m~p~"#";h=If[MemberQ[#3/@o,{m_,n_}/;m#<0&&m#<=n#2<-m#],"#",e]&;{e=".",h[1,1,#&],e,n="\n",h[1,-1,r=Reverse],"O",h[-1,1,r],n,e,h[-1,-1,#&],e}<>"")&

Agak lebih mudah dibaca:

f[input_] := (
  map = Characters @ StringSplit @ input;
  planet = Flatten[Position[map, "O"]];
  objects = Map[# - planet &, Position[map, "#"]];
  helper[pattern_] := If[
    Length[Position[objects, pattern]] > 0, 
    "#", 
    "."
  ];
  StringJoin[{
    ".", h[{m_, n_} /; m < 0 && m <= n < -m], ".", "\n",
    h[{m_, n_} /; n < 0 && n < m <= -n], "O", h[{m_, n_} /; n > 0 && -n <= m < n], "\n",
    ".", h[{m_, n_} /; m > 0 && -m < n <= m], "."
  }]
);

Seperti yang Anda lihat, saya hanya mengambil satu input yang merupakan string yang berisi peta input. Ini karena saya tidak akan menggunakan integer ukuran. Jika Anda bersikeras pada format input, saya dapat mengubah string input ke argumen kedua untuk satu karakter lagi.

Adapun algoritma, saya hanya mengumpulkan semua {Δx, Δy}pasangan objek dan mencari satu pasangan di setiap kuadran dengan kondisi yang diteruskan h. Saya kira ini juga bagian yang bisa diturunkan lebih jauh.

Martin Ender
sumber
Saya tidak tahu Anda adalah penggemar Mathematica juga!
Andrew Cheong
1
@AndrewCheong Saya kira itu datang secara alami ketika Anda seorang pengembang perangkat lunak yang mempelajari fisika. ;)
Martin Ender
5

perl, 270 karakter

3 langkah: 1) menemukan planet dan satelit di input, 2) menentukan kuadran untuk setiap satelit, 3) output

sub _{"#"}$D=<>;$\=$/;for$L(1..$D){for$M(1..$D){$/=\1;$_=<>;$p=$M,$q=$L if/O/;push@s,[$M,$L] if/#/}$/=$\;<>}for(@s){$x=$_->[0]-$p,$y=$_->[1]-$q;($x<0&&$x<$y&&$y<=-$x?$l:$x>0&&-$x<=$y&&$y<$x?$r:$y<0&&$y<=$x&&$x<-$y?$u:$d)=_}$_=$l?" #":_;$u&&print;print $l."O$r";$d&&print

Kurang golf:

sub _{"#"}
$D=<>;
$\=$/;
for$L(1..$D){
  $/=\1;
  for$M(1..$D){
    $_=<>;
    $p=$M,$q=$L if/O/;
    push@s,[$M,$L] if/#/;
  }
  $/=$\;
  <>
}

for(@s){
  $x=$_->[0]-$p,$y=$_->[1]-$q;  

  ($x<0&&$x<$y&&$y<=-$x ? $l :
   $x>0&&-$x<=$y&&$y<$x ? $r :
   $y<0&&$y<=$x&&$x<-$y ? $u : $d)=_;
}

$_=$l?" #":_;
$u && print;
print$l."O$r";
$d && print;
skibrianski
sumber