Snow Blow My Driveway!

8

Baru-baru ini ada salju besar, dan jalan masuk saya membutuhkan salju. Jika peniup salju melewati beberapa area yang sudah dilewati salju, maka area tersebut akan terkena salju dan perlu ditiup lagi. Dan tentu saja, peniup salju tidak dapat memulai di tengah jalan masuk, itu harus dimulai dari garasi saya, tempat penyimpanannya.

Lebih formal:

Program Anda mengambil bentuk input standar sebagai string atau array multidimensi yang terlihat seperti berikut:

XXXXOOOOXXXX
X          X
X          X
XXXXXXXXXXXX

Xmewakili area yang tidak dapat dihembuskan salju, Omewakili area di mana peniup salju dapat digunakan, dan ruang kosong mewakili area di mana ada salju. Anda dapat memilih nilai yang berbeda jika diinginkan.

Program Anda harus menampilkan sesuatu seperti berikut:

XXXX*%OOXXXX
Xv<<<^<<<<<X
X>>>>>>>>>^X
XXXXXXXXXXXX

Peniup salju mulai di *. The *selalu menunjuk ke ruang non-bengkel terdekat. The <, >, v, dan ^semua mewakili pointer dari mana arah berikutnya adalah. Mereka mengarahkan peniup salju ke mana harus pergi. Setelah penunjuk menunjuk ke %, blower telah kembali masuk ke garasi, dan seluruh jalan masuk harus jelas.

Peniup salju harus melewati seluruh jalan masuk. Jalur Snowblower tidak pernah bisa tumpang tindih dengan sendirinya. Masukan yang tidak mungkin tidak harus diberikan.

Karena saya tidak ingin berada di luar lebih lama dari yang seharusnya, dan tidak perlu menghabiskan banyak waktu untuk mengetik, program harus sesingkat mungkin. Kode terpendek menang!

Kasus uji:

Kasing uji ini mungkin memiliki beberapa jawaban yang benar. Saya telah memberikan solusi yang memungkinkan di bawah setiap test case.

Uji kasus 1: Yang diberikan dalam contoh.

Uji kasus 2:

XOOOOOX
X     X
X     X
X     XXXXXXXX
X            X
X            X
XXXXXXXXXXXXXX

X*OOO%X
Xv>>>^X
Xv^<<<X
Xv>>>^XXXXXXXX
Xv^<<<<<<<<<<X
X>>>>>>>>>>>^X
XXXXXXXXXXXXXX

Uji kasus 3:

XOOOOX
X    X
X    X
X  XXX
X    X
X    X
XXXXXX

XOO%*X
X>>^vX
X^v<<X
X^vXXX
X^>>vX
X^<<<X
XXXXXX

Uji kasus 4:

XXXXXXXXXXXXX
O           X
O    X      X
O    X      X
O           X
XXXXXXXXXXXXX

XXXXXXXXXXXXX
*>>>>>>>>>>vX
Ov<v<Xv<<<<<X
Ov^v^X>>>>>vX
%<^<^<<<<<<<X
XXXXXXXXXXXXX
Kamerad SparklePony
sumber
Terkait ;-)
Arnauld
2
Bisakah kita berasumsi bahwa 1) garis Oakan selalu berada dalam garis kontinu lurus? 2) bahwa Os akan selalu berada di tepi array? 3) bahwa tidak akan ada ruang utama? 4) bahwa tidak akan ada spasi tambahan (yaitu dalam kasus uji 2 beberapa garis lebih pendek dari yang lain)?
PurkkaKoodari
@ Pietu1998 Ya, untuk mereka semua.
Kamerad SparklePony

Jawaban:

4

JavaScript (ES6), 346 310 299 298 297 296 283 byte

f=(a,y=0,x=0)=>(a[y][x]?a[y][x]=='O'&&(a[y][x]='*',(g=w=>(w=a[y])&&w[x]&&(w[x]<'!'?g(w[x]='v',y++)||g(w[x++]='>',y--)||g(w[--x]='^',y--)||g(w[x--]='<',y++)||+(w[++x]=' '):w[x]=='O'&&!/ /.test(a)?w[x]='%':0))(y++)||g(y-=2)||g(y++,x++)||g(x-=2)||+(a[y][++x]='O'))||f(a,y,x+1):f(a,y+1))
<textarea id="tests">XXXXOOOOXXXX&#10;X          X&#10;X          X&#10;XXXXXXXXXXXX&#10;&#10;XOOOOOX&#10;X     X&#10;X     X&#10;X     XXXXXXXX&#10;X            X&#10;X            X&#10;XXXXXXXXXXXXXX&#10;&#10;XOOOOX&#10;X    X&#10;X    X&#10;X  XXX&#10;X    X&#10;X    X&#10;XXXXXX&#10;&#10;XXXXXXXXXXXXX&#10;O           X&#10;O    X      X&#10;O    X      X&#10;O           X&#10;XXXXXXXXXXXXX</textarea><br><button onclick="for(test of document.getElementById('tests').value.split('\n\n')){console.log(test);arr=test.split('\n').map(line=>line.split(''));f(arr);console.log(arr.map(line=>line.join('')).join('\n'))}">Run</button>

Cukup macet di beberapa tempat, tetapi saya ingin mendapatkan kode di luar sana. Input sebagai array karakter 2D, output dengan memodifikasi array kata.

Versi tidak disatukan

Ini adalah algoritma yang sama persis, menyimpan untuk beberapa truthy / sihir falsy dengan +' 'menjadi NaNmenjadi falsy (dan lagi), beberapa variabel golf dan menggunakan ifs bukan ?:, ||dan &&.

f = (a, y = 0, x = 0) => {         // main function
  if (!a[y][x])                    // check for end of line
    return f(a, y + 1);            // end of line, recursively check next
  if (a[y][x] == 'O') {            // check for valid start position
    a[y][x] = '*';                 // set the start position
    function g() {                 // pathfinder function
      if (!a[y] || !a[y][x])       // check for out of bounds
        return 0;
      if (a[y][x] == ' ') {        // check for snow
        a[y][x] = 'v';             // set current cell to 'down'
        y++;                       // move position down
        if (g()) return 1;         // see if a valid route is found from there
        y--;                       // if not, reset position and try again
        a[y][x] = '>';             // repeat for other directions
        x++;
        if (g()) return 1;
        x--;
        a[y][x] = '^';
        y--;
        if (g()) return 1;
        y++;
        a[y][x] = '<';
        x++;
        if (g()) return 1;
        x++;
        a[y][x] = ' ';             // no route found, reset cell to snow
        return 0;
      }
      if (a[y][x] == 'O'           // check for valid exit
          && !/ /.test(a)) {       // and that no snow is left
        a[y][x] = '%';             // set the exit
        return 1;
      }
    }
    y++;                           // move a cell down from the start position
    if (g()) return 1;             // see if a valid route starts there
    y -= 2;                        // repeat for other directions
    if (g()) return 1;
    y++; x++;
    if (g()) return 1;
    x -= 2;
    if (g()) return 1;
    x++;
    a[y][x] = 'O';                 // no route found, continue on
  }
  return f(a, y, x + 1);           // check the next cell
}
PurkkaKoodari
sumber