助けてください、私は無限の工場に閉じ込められています!


26

この課題は、ザックトロニクスのゲームInfinifactoryに大まかに触発されています。

で表されるコンベアの長方形グリッドのトップダウンビューが表示され>v<^ます。スペースで表されるコンベアのないセルが存在する場合があります。以下に例を示します。

> <vv    <
 v ^ >v v 
  >v^^>vv^
    ^>^ v 
>  v<v  >>
  >v v<^  

この設定は、無限のスペースに暗黙的に囲まれています。

さらに、グリッドの左上隅にあるコンベヤー上に配置される長方形の貨物の寸法が与えられます。あなたの仕事は、貨物が静止するかどうか、またはループで移動するかどうかを把握することです。

もちろん、貨物は一度に複数のコンベヤーをカバーする可能性が高いため、各ステップで貨物の方向を把握するためのルールは次のとおりです。

  1. 反対側のコンベヤーは互いにキャンセルします。したがって、3x2の貨物が次のパッチのいずれかをカバーする場合(明確にするためにハイフンとパイプで概説)、結果は同じになります。

    +---+   +---+   +---+
    |>>^|   |  ^|   |v^^|
    |^<<|   |^  |   |^^v|
    +---+   +---+   +---+
    

    これらについても同じことが言えます。

    +---+   +---+   +---+
    |v^<|   |   |   |><>|
    |>>>|   |>> |   |>><|
    +---+   +---+   +---+
    

    貨物の下のコンベアの正確な位置は無関係であるため、どのペアをキャンセルしてもかまいません。

    このキャンセルは、他のルールの前に適用されます。したがって、他のルールでは、最大2方向のコンベヤーのみが存在します。

  2. 貨物がコンベヤーをまったく覆わない場合(すべてのコンベヤーがキャンセルされる、スペースのみを覆うため、またはグリッドから完全に移動したため)、貨物​​は停止します。
  3. 貨物が一方の方向よりも多くのコンベヤをカバーしている場合、貨物はその方向に移動します。たとえば、3x2の貨物が次のパッチをカバーした場合

    >>
    ^>^
    

    より多くがあるので、それは、右に移動する>よりも^。一方、それがカバーした場合

    >>^
      ^
    

    間のタイがありますので、この規則は、適用されない>とは^

  4. これにより、隣接する方向間に同点がある場合のみが残ります(反対方向間の同点がキャンセルされます)。この場合、貨物は既に移動している軸に沿って移動し続けます。たとえば、右移動または左移動の3x2貨物がパッチを覆っている場合

    >>^
    ^  
    

    右に移動します。このパッチに到着して上下に移動した場合、代わりに上に移動します。この種の衝突がシミュレーションの最初のステップで発生する場合、貨物が右に動いていたと仮定します。

詳細な例

上部のコンベアグリッドと3x2の貨物を考えてください。以下は、プロセスの段階的な視覚化です。各ステップはグリッドで構成され、貨物はで表され#、貨物で覆われたコンベヤーを示す小さなボックス、キャンセル後のコンベヤーを備えた別のボックス、および貨物の移動場所を決定するルールで構成されます。

 ###vv    <    > <vv    <    > <vv    <    > <vv    <    > <vv    <    > <vv    <
 ###^ >v v     ###^ >v v      v ^ >v v      v ^ >v v      v ^ >v v      v ^ >v v 
   >v^^>vv^    ###v^^>vv^    ###v^^>vv^     ###^^>vv^      ###^>vv^      >###>vv^
     ^>^ v         ^>^ v     ### ^>^ v      ###^>^ v       ###>^ v        ###^ v 
 >  v<v  >>    >  v<v  >>    >  v<v  >>    >  v<v  >>    >  v<v  >>    >  v<v  >>
   >v v<^        >v v<^        >v v<^        >v v<^        >v v<^        >v v<^  

+---+  +---+  +---+  +---+  +---+  +---+  +---+  +---+  +---+  +---+  +---+  +---+
|> <|  |   |  | v |  | v |  |  >|  |  >|  | >v|  | >v|  |>v^|  |> ^|  |v^^|  | ^^|
| v |  | v |  |  >|  |  >|  |   |  |   |  |   |  |   |  |  ^|  |   |  | ^>|  |  >|
+---+  +---+  +---+  +---+  +---+  +---+  +---+  +---+  +---+  +---+  +---+  +---+

   Rule 3        Rule 4        Rule 3        Rule 4        Rule 4        Rule 3

 ================================================================================

 > <vv    <    > <###   <    > <vv    <
  v ###v v      v ###v v      v ###v v 
   >###>vv^      >v^^>vv^      >###>vv^
     ^>^ v         ^>^ v         ^>^ v 
 >  v<v  >>    >  v<v  >>    >  v<v  >>
   >v v<^        >v v<^        >v v<^  

+---+  +---+  +---+  +---+  +---+  +---+
|^ >|  |  >|  |vv |  | v |  |^ >|  |  >|
|v^^|  | ^^|  |^ >|  |  >|  |v^^|  | ^^|
+---+  +---+  +---+  +---+  +---+  +---+

   Rule 3        Rule 4        Rule 3

この時点で、貨物は最後の2つのフレーム間でループに入ります。

次に、代わりに2x3の貨物を検討します。

 ##<vv    <    >##vv    <    > <vv    <    > <vv    <    > <vv    <    > <vv    <
 ## ^ >v v      ##^ >v v      ##^ >v v      v ^ >v v      v ^ >v v      v ^ >v v 
 ##>v^^>vv^     ##v^^>vv^     ##v^^>vv^     ##v^^>vv^      ##^^>vv^      >v^^>vv^
     ^>^ v         ^>^ v      ## ^>^ v      ## ^>^ v       ##^>^ v       ##^>^ v 
 >  v<v  >>    >  v<v  >>    >  v<v  >>    >##v<v  >>    > ##<v  >>    > ##<v  >>
   >v v<^        >v v<^        >v v<^        >v v<^        >v v<^        ## v<^  

 +--+  +--+    +--+  +--+    +--+  +--+    +--+  +--+    +--+  +--+    +--+  +--+
 |> |  |> |    | <|  |  |    |v |  |v |    | >|  | >|    |>v|  |>v|    |  |  |  |
 | v|  | v|    |v |  |v |    | >|  | >|    |  |  |  |    |  |  |  |    | v|  | v|
 |  |  |  |    | >|  |  |    |  |  |  |    |  |  |  |    | v|  | v|    |>v|  |>v|
 +--+  +--+    +--+  +--+    +--+  +--+    +--+  +--+    +--+  +--+    +--+  +--+

   Rule 4        Rule 3        Rule 4        Rule 3        Rule 3        Rule 3

 ================================================================================

 > <vv    <    > <vv    <    > <vv    <
  v ^ >v v      v ^ >v v      v ^ >v v 
   >v^^>vv^      >v^^>vv^      >v^^>vv^
     ^>^ v         ^>^ v         ^>^ v 
 > ##<v  >>    >  v<v  >>    >  v<v  >>
   ## v<^        ## v<^        >v v<^  
   ##            ##            ##
                 ##            ##
                               ##

 +--+  +--+    +--+  +--+    +--+  +--+
 | v|  | v|    |>v|  |>v|    |  |  |  |
 |>v|  |>v|    |  |  |  |    |  |  |  |
 |  |  |  |    |  |  |  |    |  |  |  |
 +--+  +--+    +--+  +--+    +--+  +--+

   Rule 3        Rule 4        Rule 2

最後のステップでは、貨物がグリッドから移動したため、規則2が適用されます。したがって、貨物は停止し、ループは発生しません。

ルールと仮定

入力は、貨物の幅と高さとともに、上記のコンベアグリッドになります。これらの3つのパラメーターは、任意の便利な順序と形式で使用できます。グリッドのために、あなたが行と単一の文字列を読み取ることができることは、この手段は、個々のグリッドセルがまだ文字で表されている限り、改行または他の文字、または文字列の配列、又は文字の配列の配列によって分離>v<^およびスペース。

セットアップの結果、少なくとも2フレームのループが発生する場合は真実の値を、貨物が停止する場合は偽の値を出力する必要があります。

グリッドがスペースのある長方形にパディングされ、貨物が最初にグリッドに収まると仮定できます。

プログラムまたは関数を作成し、STDIN(または最も近い代替)、コマンドライン引数または関数引数を介して入力を取得し、STDOUT(または最も近い代替)、関数の戻り値または関数(out)パラメーターを介して結果を出力できます。

これはコードゴルフなので、最短の回答(バイト単位)が勝ちです。

テストケース

テストケースはグリッドごとにグループ化されます。

Grid (2x2):

>v
^<

Width  Height  Loop?
1      1       True
1      2       True
2      1       True
2      2       False

Grid (3x3):

> v

^ <

Width  Height  Loop?
1      1       False
1      2       False
1      3       False
2      1       False
2      2       True
2      3       True
3      1       False
3      2       True
3      3       False

Grid (4x3):

>^>v
v^v 
^ <<

Width  Height  Loop?
2      2       False

Grid (6x5):

>v>v>v
^v^v^v
^v^v^v
^>^>^v
^<<<<<

Width  Height  Loop?
1      1       True
1      2       False
2      1       True
2      2       True
2      4       True
2      5       False
3      1       False
3      2       True
3      3       True
3      5       True
6      2       False
6      3       True
6      5       False

Grid (10x6):

> <vv    <
 v ^ >v v 
  >v^^>vv^
    ^>^ v 
>  v<v  >>
  >v v<^  

Width  Height  Loop?
1      1       False
2      3       False
2      6       False
3      2       True
5      4       False
6      1       True
10     6       False

テストケースの追加セットとして、グリッドがスペースのみで構成される入力は、偽の結果を生成する必要があることを考慮してください。

すべてのテストケースを手動で確認したため、間違いを犯したと思われる場合はお知らせください。



4
私は...単収縮プレイズポケモンフラッシュバックを取得しています@Fatalize
undergroundmonorail

「あなたの入力は、貨物の幅と高さとともに、上記のコンベアグリッドになります。これらの3つのパラメーターは、都合の良い順序と形式で受け取ることができます。」-これは、コンベヤーグリッドをアレイのアレイとして取り込むことができるということですか?つまり、を持つ2x2グリッド[^^/v<][[0,1] [0,1];[0,-1] [-1,0]]?それとも、STDIN、文字列入力、文字配列入力などであるかどうかは私たち次第ですが、それでも^、v、>、および<の形式である必要がありますか?
グレンO

@GlenO改行(または他の文字)で区切られた文字列、文字列の配列、または文字の配列の配列を使用できますが、各セルは文字><^vまたはスペースで表す必要があります。それを明確にします。
マーティンエンダー

では、継続する方向が選択肢の1つではない場合、貨物が紛争に移行するとどうなりますか?つまり、右に動いていた場合、上と左のどちらかを選択する必要があります。
ジョシュア

回答:


7

ルビー、306 298 251 204 198

->g,w,h{m=->y,x,d,v=[]{q=y,x
r=->s{([""]*h+g)[y+h,h].map{|l|(?x*w+l)[x+w,w]}.join.count s}
z=k=r[?v]-r[?^],j=r[?>]-r[?<]
q[d=[d,1,0][j*j<=>k*k]]+=z[d]<=>0
v&[q<<d]!=[]?q!=v[-1]:m[*q,v<<q]}
m[0,0,1]}

編集:いくつかの驚くべきトリックを適用してコードを大幅に短縮したVenteroに感謝します!

入出力

このコードは、3つのパラメーターを受け取るルビー関数を表します。

  • 文字列の配列として表されるグリッド(各行は異なる文字列です)
  • 貨物の幅
  • 貨物の高さ

1ループnilがある場合は(真)、貨物が静止している場合は(偽)を返します。

テスト

ここでは、Martinのすべてのテストに合格しています:http : //ideone.com/zPPZdR

説明

コードには巧妙なトリックはありません。ルールの非常に簡単な実装です。

以下のコードでmoveは、ルールに従って移動する再帰関数です。

  • ループの場合に真実を返します
  • 休憩の場合に偽を返します
  • そうでない場合は、次の移動を実行するために自分自身を呼び出します

より読みやすいバージョンはこちらから入手できます

注:ゴルフコードはいくつかの変更が加えられ、読み取り可能なバージョンとは異なります。


r4つの方向以外に追加のエントリが含まれているかどうかは関係ないr[y>=0&&x>=0&&g[y]&&g[y][x]]+=1ため、数バイトを節約する必要があります。
ヴェンテロ

私はもう少しゴルフの自由を取りました。気にしないでください:ideone.com/k69BmH
Ventero

@Venteroうわー、あなたはコードに驚くべきことをしました。ハッシュをラムダに変換することを考えたことがありませんでした。私はプログラムを短縮するために私のアイデアのいくつかを試していましたが、あなたがやったことの近くにはありませんでした。どうもありがとう!
クリスチャンルパスク

2
負のインデックスの処理をわずかに短くして200に下げました。今のところはそのままにしておきます。ideone.com
Ventero

2
実際、198:ideone.com/ptKrzf :)
Ventero

8

Python 2、207バイト

def f(L,w,h,u=0,v=0,D=1,S=[]):a,b,c,d=map(`[r[u*(u>0):u+w]for r in L[v*(v>0):v+h]]`.count,"v^><");D=cmp(abs(a-b),abs(c-d))<D;T=u,v,D;return T in S or a-b|c-d and f(L,w,h,u+cmp(c,d)*D,v+cmp(a,b)*0**D,D,S+[T])

行のリストとしてグリッドを入力します。例えば

['>v>v>v', '^v^v^v', '^v^v^v', '^>^>^v', '^<<<<<']

幅と高さが続きます。返品0またはTrueそれに応じて。

説明

def f(L,          # Grid
      w,h,        # Width, height of cargo
      u=0,v=0,    # Position of top-left of cargo, initially (0, 0)
      D=1,        # Moving left/right = 1, up/down = 0
      S=[]        # Seen (pos, axis) pairs, initially empty
     ):     

     # Arrows under cargo - no need for "".join since we only need to count v^<>
     A = `[r[u*(u>0):u+w]for r in L[v*(v>0):v+h]]`

     # Count for each arrow
     a,b,c,d=map(A.count,"v^><")

     # Golfed form of abs(a-b) < abs(c-d) or (abs(a-b) == abs(c-d) and D == 1)
     D=cmp(abs(a-b),abs(c-d))<D
     T=u,v,D

     return (T in S                # Return True if (pos, axis) previously seen
             or a-b|c-d               # Return 0 if all conveyors cancel
             and f(L,w,h,             # Otherwise, recurse
                   u+cmp(c,d)*D,      # Update u if moving left/right
                   v+cmp(a,b)*0**D,   # Update v if moving up/down
                   D,
                   S+[T]          # Add (pos, axis) to seen
                  )
            )

cmp変数に代入して短くすることはできませんか?
ブルー

すでに訪れた位置をチェックすることでサイクルを検出するだけで十分ですか?ルール4に基づいて、次のステップは前の方向の影響を受けることもあります。したがって、同じ位置に2回到着することは可能ですが、以前のさまざまな方向に基づいてさまざまな方向に移動するため、サイクルはありません。
レトコラディ

@muddyfishそれはちょうど損益分岐点になるだろう
-Sp3000

@RetoKoradiうまくいけば
Sp3000

はい、D位置キーに追加する必要があります。
レトコラディ

8

ジュリア- 394の 300 246 214バイト

f(A,x,y)=(Z=sign;(S,T)=size(A);X=x+1;Y=y+1;G=fill(5,S+2y,T+2x);G[Y:S+y,X:T+x]=A;C=0G;D=1;while C[Y,X]!=D C[Y,X]=D;i,j=sum(i->1-[19 8]i%82%3,G[Y:Y+y-1,X:X+x-1]);D=Z(2i^2-2j^2+(i!=0)D);X+=Z(i+D*i);Y+=Z(j-D*j)end;D^2)

貨物がループする場合は1を返し、停止する場合は0を返します。ジュリアはブールコンテキストで0と1を許可していません...しかし、私は値を考えるという点では、「厳密に」truthy / falsyではありませんxそのためbool(x)==truetruthyあるとbool(x)==falsefalsyですが。

入力Aは、文字配列の形式でなければなりません。コンベアグリッドをコピー/貼り付けする場合は、適切な形式にする必要があります。手動で処理する必要がないようにするには、次を使用します。

A=foldl(hcat,map(collect,split("""(PASTE GRID HERE)""","\n")))'

明らかに、(PASTE GRID HERE)グリッド自体に置き換える必要があります。各行の最後にあるスペースを再確認して、実際にすべてのスペースがあることを確認します(すべての行が同じ長さであることを確認しません)。この行は、実際のソリューションコードの一部ではなく、ソリューションコードの使用を少し簡単にするための便利なコードです。

ゴルフをしていない:

function f(A,x,y)
  # Determine size of grid for use later
  (S,T)=size(A)
  # Initialise starting position (performed here to save characters)
  X=x+1
  Y=y+1
  # Create an expanded field that is functionally "spaces" (to provide
  # spaces at edges for the cargo to stop in)
  G=fill(5,S+2y,T+2x)
  # Put the conveyor grid into centre of the expanded field
  G[Y:S+y,X:T+x]=A
  # Create an array storing the most recent movement direction:
  # will use 1=horizontal, -1=vertical, 0=stopped
  C=0G
  # Initialise current direction (same system as C)
  D=1
  # Loop until it finds itself repeating a coordinate/direction pair
  while C[Y,X]!=D
    # Mark current coordinate/direction pair in array
    C[Y,X]=D
    # Determine the net coordinate pairing, stored in two variables
    # for golf purposes *SEE NOTE*
    i,j=sum(i->1-[19 8]i%82%3,G[Y:Y+y-1,X:X+x-1])
    # Determine new movement axis (if D=0, cargo stopped)
    D=sign(2i^2-2j^2+(i!=0)D)
    # Update X or Y depending on signs of D and the appropriate direction
    X+=sign(i+D*i)
    Y+=sign(j-D*j)
  end
  # if D=±1, return 1 (cargo is still moving), otherwise return 0
  return D^2
end

注:1-[19 8]i%82%3私が見つけた最も効率的な方法で、5つの可能な文字を適切な座標ペアにマップするために選択されました。これは、作成時にスペースを埋めるために5を使用する理由でもあります。これはG、にマッピングされる1桁の文字です[0 0]

使用例:

julia> A=foldl(hcat,map(collect,split(""">v>v>v
       ^v^v^v
       ^v^v^v
       ^>^>^v
       ^<<<<<""","\n")))';

julia> f(A,2,1)
true

julia> f(A,3,3)
true

julia> f(A,5,2)
false

f(A,x,y)=はより短いf=(A,x,y)->
アレックスA.

@AlexA。-本当ですが、その後、私はおそらくそれを削除し、f=ゴルフを終えたら匿名機能にします。
グレンO

1
複数のパラメーターがある場合、名前付き関数と匿名関数の場合、同じ長さになります。f()=()->
アレックスA.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.