Yardım et, sonsuz bir fabrikada mahsur kaldım!


26

Bu zorluk, Zachtronics oyunu Infinifactory oyunundan gevşek bir şekilde esinlenmiştir .

Size temsil edilen dikdörtgen konveyör ızgarasının üstten görünüşü verilir >v<^. Boşluklarla temsil edilen, taşıyıcıları olmayan hücreler olabilir. İşte bir örnek:

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

Bu kurulum, sınırsız sayıda boşlukla çevrilidir.

Ayrıca, kılavuzun üst sol köşesindeki konveyörlere yerleştirilen dikdörtgen bir kargo parçasının ebatları verilmiştir. Göreviniz, kargonun şimdiye kadar dinlenip gelmediğini veya bir döngü içinde hareket edip etmeyeceğini bulmak.

Elbette, kargo bir kerede birden fazla konveyörü kapsayacak gibi gözüküyor, işte her adımda kargonun yönünü bulmak için kurallar:

  1. Karşı konveyörler birbirini iptal eder. Öyleyse, 3x2'lik bir kargo aşağıdaki yamalardan herhangi birini kapsıyorsa (netlik için kısa çizgiler ve borularla özetlenir), sonuç aynı olacaktır:

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

    Aynısı bunlar için de geçerli:

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

    Yükün altındaki bir konveyörün tam konumu önemli olmadığı için, hangi çiftleri iptal ettiğiniz önemli değildir.

    Bu iptal diğer kurallardan önce uygulanır. Bu nedenle, diğer kurallar için en fazla iki yönde konveyörler olacaktır.

  2. Kargo hiç bir konveyörü kapsamıyorsa (tüm konveyörler iptal edildiğinden, yalnızca boşlukları kapladığından veya tamamen ızgaradan çıktığından dolayı), durmaya başlar.
  3. Kargo bir yönden diğerine göre daha fazla konveyör kaplarsa, kargo bu yönde hareket eder. Örn, 3x2'lik bir kargo aşağıdaki yamayı kaplarsa

    >>
    ^>^
    

    daha vardır, çünkü sağa hareket edeceğini >daha ^. Öte yandan, eğer kaplanmışsa

    >>^
      ^
    

    bu kural geçerli olmaz, çünkü >ve arasında bir bağ var ^.

  4. Bu, yalnızca bitişik yönler arasında bir bağ bulunduğu hallerde kalır (zıt yönler arasındaki bir bağ iptal edilirdi). Bu durumda, kargo zaten ilerliyor ekseninde hareket eden tutar. Örneğin bir sağ hareket halinde ya da sola hareket eden 3x2 kargo şimdi yama kapsayan

    >>^
    ^  
    

    sağa doğru hareket ederdi. Bu yamaya gelmiş veya aşağı yukarı hareket etmiş olsaydı, şimdi yerine yükselirdi. Bu tür bir çatışma simülasyonun ilk aşamasında meydana gelirse, kargonun sağa doğru hareket ettiğini varsayalım.

Detaylı örnekler

Konveyör ızgarasını en üstte ve 3x2 yükte düşünün. Aşağıdaki işlemin adım adım görselleştirilmesidir. Her adım, şebekenin kargo tarafından temsil edilen #, kargo kapsamındaki konveyörleri gösteren küçük bir kutu, iptal edildikten sonra konveyörlerle birlikte başka bir kutu ve kargonun nereye hareket ettiğini belirleyen kuraldan oluşur:

 ###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

Bu noktada, kargo son iki çerçeve arasında bir halka girer.

Şimdi bunun yerine 2x3 kargo düşünün:

 ##<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

Son adımda, kural 2 geçerlidir çünkü kargo şebekeden ayrılmıştır, bu nedenle dinlenmeye başlar ve bir döngü olmaz.

Kurallar ve Varsayımlar

Girişiniz, yükün genişliği ve yüksekliği ile birlikte yukarıda açıklandığı gibi taşıyıcı ızgara olacaktır. Bu üç parametreyi uygun bir sıra ve biçimde alabilirsiniz. Izgara için, çizgi ile tek bir karakter dizisi okuyabileceği bu araçlar bireysel ızgara hücreleri yine karakterlerle temsil edilen sürece, yeni satır veya diğer karakterler veya şeritlerinin bir dizi ya da bir karakterler dizileri bir dizi ile ayrılmış >v<^ve alanlarda.

Sen çıkışı gerektiği truthy en az iki kare veya bir döngü içinde kurulum sonuçları ise değer falsy değere kargo dinlenmeye gelecek eğer.

Kılavuzun boşluklu bir dikdörtgene yatacağını ve kargonun başlangıçta ızgaraya sığacağını kabul edebilirsiniz.

STDIN (veya en yakın alternatif), komut satırı argümanı veya işlev argümanı yoluyla giriş alarak ve sonucu STDOUT (veya en yakın alternatif), fonksiyon dönüş değeri veya function (out) parametresi ile çıktı alarak bir program veya işlev yazabilirsiniz.

Bu kod golf, yani en kısa cevap (bayt cinsinden) kazanır.

Test Kılıfları

Test vakaları ızgaralarla gruplandırılmıştır.

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

Ek bir test durumu kümesi olarak, ızgaranın yalnızca boşluktan oluştuğu herhangi bir girişin sahte bir sonuç vermesi gerektiğini düşünün.

Tüm test durumlarını manuel olarak kontrol ettim, bu yüzden bir hata yaptığımı düşünüyorsan haberim olsun.



4
Ben ... Twitch Plays Pokemon geri dönüşleri alıyorum @Fatalize
undergroundmonorail

"Girişiniz, yukarıda belirtilen kargo taşıyıcısının genişliği ve yüksekliği ile birlikte konveyör ızgarası olacaktır. Bu üç parametreyi herhangi bir uygun sıra ve biçimde alabilirsiniz." - bu, konveyör ızgarasının bir dizi dizi olarak alınabileceği anlamına mı geliyor? Yani, 2x2 olan bir ızgara [^^/v<]olur [[0,1] [0,1];[0,-1] [-1,0]]mu? Yoksa STDIN, bir dize girişi, bir karakter dizisi girişi, vs. olup olmadığı bize mi geliyor, ama yine de ^, v,> ve <şeklinde mi olması gerekiyor?
Glen O

@GlenO Yeni bir satır (veya başka bir karakter) ayrılmış bir dize, bir dizi dizisi veya bir dizi karakter dizisi alabilir, ancak her hücre yine de karakterler ><^vveya boşlukla temsil edilmelidir . Bunu açıklığa kavuşturacağım.
Martin Ender

Peki kargo, devam eden yönün seçimlerden biri olmadığı bir çatışmaya girerse ne olur? Yani, eğer doğru hareket ediyorsa ve şimdi yukarı ve sola doğru seçim yapmalı.
Joshua,

Yanıtlar:


7

Ruby, 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]}

Düzenleme: Bazı şaşırtıcı hileler uygulayarak kodu çok kısaltan Ventero için çok teşekkürler!

Giriş ve çıkış

Kod, üç parametre alan bir yakut fonksiyonunu temsil eder:

  • dizi dizisi olarak gösterilen ızgara (her satır farklı bir dizedir)
  • kargonun genişliği
  • kargonun yüksekliği

1Bir döngü olması durumunda geri döner (truthy) veya nilyükün istirahat etmesi durumunda (sahte).

Testler

İşte Martin'in tüm testlerini geçiyor: http://ideone.com/zPPZdR

açıklama

Kodda akıllıca numaralar yoktur; bu kuralların oldukça basit bir uygulamasıdır.

Aşağıdaki kodda move, kurallara göre hareket eden özyinelemeli bir işlevdir ve:

  • bir döngü halinde gerçeği döndürür
  • istirahat durumunda sahte döner
  • Aksi takdirde bir sonraki hareketi yürütmek için kendisini çağırır.

Burada daha okunaklı bir sürüm var .

Not: Golf kodu birçok modifikasyona tabi tutulmuştur ve artık okunabilir versiyona benzemektedir.


rDört yönden başka ek girdiler içerip içermediği önemli olmadığı için , r[y>=0&&x>=0&&g[y]&&g[y][x]]+=1birkaç bayttan tasarruf etmelisiniz.
Havai

Golf olaylarını biraz daha ileri götürdüm, umarım sakıncası yok: ideone.com/k69BmH
Ventero

@ Vincent Wow, koda inanılmaz şeyler yaptınız. Haşamı bir lambdaya dönüştürmeyi asla düşünmezdim. Programı kısaltmak için bazı fikirlerimi deniyordum, ama yaptığınız hiçbir yere yakın değildi. Çok teşekkürler!
Cristian Lupascu

2
Negatif endeksleri biraz daha kısa sürede ele alarak 200'e düşürdüm
Ventero 19

2
Aslında, 198: ideone.com/ptKrzf :)
Ventero

8

Python 2,207 bayt

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])

Izgarayı satır listesi olarak girin, örn.

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

ardından genişlik ve yükseklik. Döner 0veya Truebuna göre.

açıklama

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
                  )
            )

cmpBir değişkene atayarak kısaltamaz mısınız?
Mavi

Zaten ziyaret edilmiş pozisyonları kontrol ederek döngüleri tespit etmek yeterli mi? Kural 4'e dayanarak, bir sonraki adım önceki yönden de etkilenebilir. Böylece, aynı pozisyona iki kez varabilmeniz mümkün değil, ancak önceki yöne göre farklı yöne hareket ettiğiniz için bir döngünüz olmayabilir.
Reto Koradi

@muddyfish Bu sadece kırmak bile
Sp3000

@RetoKoradi Umarım düzeltildi
Sp3000 17:15

Evet, Dpozisyon tuşuna ekleyerek yapmalısınız.
Reto Koradi

8

Julia - 394 300 246 214 bayt

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)

Kargo dönerse 1, durduğunda 0 döndürür. Bu "kesinlikle" truthy / falsy değildir, çünkü Julia, boole bağlamlarında 0 ve 1'e izin vermez ... ama xbunun bool(x)==trueiçin truthy ve falsy olan değerleri göz önünde bulundururum bool(x)==false.

Giriş A, bir karakter dizisi biçiminde olmalıdır. Konveyör ızgarasını kopyalayıp yapıştırıyorsanız, uygun forma almanız gerekir. El ile ele almak zorunda kalmamak için aşağıdakileri kullanın:

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

Açıkçası, (PASTE GRID HERE)ızgara ile değiştirilmelidir. Aslında tüm boşluklara sahip olduğundan emin olmak için her çizginin sonundaki boşlukları iki kez kontrol edin (tüm çizgilerin eşit uzunlukta olduğundan emin olmak için kontrol etmez). Bu satırın gerçek çözüm kodunun bir parçası olmadığını, çözüm kodunun kullanımını biraz daha kolay hale getirmek için uygun bir kod parçası olduğunu unutmayın.

Ungolfed:

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

Not: 1-[19 8]i%82%3bulabildiğim en verimli yöntemle beş olası karakteri uygun koordinat çiftleriyle eşleştirmek için seçildi. Bu aynı zamanda, oluştururken boşlukları doldurmak için 5 kullanılmasının nedenidir G- eşleştirilecek tek basamaklı bir karakter [0 0].

Kullanım örneği:

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)=daha kısa f=(A,x,y)->.
Alex A. 19:

@AlexA. - doğru, ama sonra, f=golf oynamayı bitirdiğimde muhtemelen onu kaldırır ve anonim bir işlev haline getiririm.
Glen O

1
Birden fazla parametre olduğunda adsız bir fonksiyona karşı adlandırılmış bir fonksiyona karşı aynı uzunlukta olacaktır. f()=karşı ()->.
Alex A.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.