スノーブローマイドライブウェイ!


8

最近大雪が降りましたが、私道は雪が吹く必要があります。除雪機がすでに吹雪しているエリアを越えた場合、そのエリアには雪が吹き付けられ、再び吹く必要があります。そしてもちろん、除雪機は私道の真ん中で始めることはできません、それはそれが保管されている私のガレージから始める必要があります。

より正式には:

プログラムは、標準形式の入力を、次のような文字列または多次元配列として受け取ります。

XXXXOOOOXXXX
X          X
X          X
XXXXXXXXXXXX

X吹雪不可Oエリア、除雪機設置可能エリア、空スペースは雪のあるエリア 必要に応じて、異なる値を選択できます。

プログラムは次のようなものを出力する必要があります。

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

除雪機はから始まり*ます。は*常に最も近い非ガレージスペースを指します。<>v、および^すべての次の方向がどこにあるのポインタを表します。彼らはどこに行くべきか除雪機を指しています。ポインターがをポイントする%と、送風機がガレージに再到着し、私道全体がきれいになります。

除雪機は私道全体を越えなければなりません。除雪機の経路が重なることはありません。不可能な入力を与えてはなりません。

必要以上に長く外に出たくなく、タイピングに多くの時間を費やす必要がないため、プログラムはできるだけ短くする必要があります。最短のコードが勝ちます!

テストケース:

これらのテストケースには、複数の正解がある場合があります。各テストケースの下に可能な解決策を示しました。

テストケース1:例で示したもの。

テストケース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

テストケース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

テストケース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


2
1 Oのが常に直線であると仮定できますか?2)Osは常に配列の端にありますか?3)先行スペースがないこと?4)末尾にスペースがないこと(つまり、テストケース2では、一部の行が他の行よりも短い)?
PurkkaKoodari 2017年

@ Pietu1998はい、それらすべてに。
同志SparklePony 2017年

回答:


4

JavaScriptの(ES6)、346 310 299 298の 297 296 283バイト

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>

一部の場所ではかなりハックですが、コードをそこに送りたかったのです。2D文字配列として入力し、上記の配列を変更して出力します。

非ゴルフバージョン

これは、同じ厳密なアルゴリズムである、といくつかのtruthy / falsy魔法のために保存+' 'されているNaNfalsyている(といくつかのより多くの)、いくつかのゴルフ変数と使用してif秒の代わりに?:||&&

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
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.