RoboZZle tercüman


10

Göreviniz bir RoboZZle yorumlayıcısı yazmaktır. Oyuna aşina değilseniz, lütfen robozzle.com adresindeki videoyu izleyin veya aşağıdaki açıklamamı okuyun.

Bir robot, kırmızı, yeşil, mavi veya siyah renkli dikdörtgen bir ızgara üzerinde yaşar. Siyah karelere erişilemez. Diğerlerine erişilebilir ve bazılarında yıldız vardır. Amaç, siyah karelere basmadan veya haritadan düşmeden tüm yıldızları toplamaktır. Robot bir kareyi işgal eder ve belirli bir yöne bakar - sola, sağa, yukarı veya aşağı. F1, F2, ..., F5 alt rutinlerine gruplanmış montaj benzeri talimatları takip eder. Bir talimat bir çift yüklem ("hiçbiri", "kırmızı ise", "yeşil ise", "mavi ise") ve bir eylem ("ileri git", "sola dön", "sağa dön"), "mevcut kareyi kırmızıya boya", "yeşil boya", "mavi boya", "hiçbir şey yapma", "F1'i ara", ..., "F5'i ara"). Altyordamlara yapılan çağrılar bir yığın kullanır ve özyinelemeli olabilir. Tıpkı konvansiyonel programlamada olduğu gibi, bir altyordamın son talimatı tamamlandıktan sonra, yürütme altyordamın çağrıldığı noktadan itibaren devam eder. Uygulama, F1'in ilk talimatından başlar ve robot yıldızlarla tüm kareleri ziyaret edene veya robot siyah bir kareye veya haritanın dışına adım atana veya 1000 talimat yürütüldüğünde (başarısız tahminler ve "hiçbir şey yapma" eylemleri gerçekleşene kadar devam eder. sayılmaz) veya yürütmek için başka talimat yoktur (yığın düşük akışı).

girişler:

  • a- bir haritayı kodlayan 12x16 karakterlik bir matris (genellikle dilinizde gösterildiği gibi, örneğin dizeler dizisi) - '#'erişilemez (siyah) kareler için, '*'yıldız içeren kareler '.'için, geri kalanı için

  • c- erişilebilir karelerin renklerini tanımlayan 12x16 karakterlik bir matris - 'R'(kırmızı), 'G'(yeşil) veya 'B'(mavi). Ulaşılamayan kareler üçünden rasgele bir harfle temsil edilecektir.

  • yve x- robotun 0 tabanlı sırası ve sütunu; a[y][x]olduğu garanti edilmektedir'.'

  • d- yön robot karşı karşıyadır: 0 1 2 3hakkı için, aşağı, yani doğru, yukarı, sol (y,x+1), (y+1,x), (y,x-1),(y-1,x)

  • f- tek bir dize, F1 ... F5'in sıralı uygulamaları. Her uygulama, a ile sonlandırılmış (muhtemelen boş) yüklem eylemi çiftleri dizisidir (alt rutin başına en fazla 10 çift) '|'.

    • yüklemler: '_'hiçbiri, 'r'kırmızı, 'g'yeşil, 'b'mavi

    • eylemler: 'F'ileri git, 'L'sola 'R'dön, sağa dön, 'r'kırmızı 'g'boya, yeşil 'b'boya, mavi boya, '1'F1'i ara, ..., '5'F5'i ara, '_'hiçbir şey yapma

Girdilerinizi yukarıdaki gibi adlandırmanız gerekmez, ancak değerleri belirtildiği gibi olmalıdır.

Çıktı: 1(veya true) robot tüm yıldızları kurallara göre toplarsa, 0( false) aksi takdirde.

Örnek :

a=["################","################","##*....*...*#.##","##.####.#####.##","##.####.#####.##","##.####*...*#.##","##.########.####","##*........*#.##","################","################","################","################"]
c=["RRRRRRRRRRRRRRRR","RRRRRRRRRRRRRRRR","RRRBBBBRGGGGRRRR","RRBRRRRGRRRRRRRR","RRBRRRRGRRRRRRRR","RRBRRRRRGGGBRRRR","RRBRRRRRRRRGRRRR","RRRBBBBGGGGBRBRR","RRRRRRRRRRRRRRRR","RRRRRRRRRRRRRRRR","RRRRRRRRRRRRRRRR","RRRRRRRRRRRRRRRR"]
y=2; x=6; d=2

// and then depending on "f":
f="_FrLg2_1|_FbLrR_2||||" // result:1
f="_FrRg2_1|_FbLrR_2||||" // result:0 (stepped on a black square)
f="_FrLrL_1|_FbLrR_2||||" // result:0 (1000-step limit exceeded)
f="_FrLg2__|________||||" // result:0 (stack underflow)

"Boya" talimatlarını içeren başka bir örnek :

a=["#***************","#*###*###*###*##","#*###*###*###*##","***#***#***#***#","***#***#***#***#","*###*###*###*###","***#***#***#***#","***#***#***#***#","***#***#***#***#","*###*###*###*###","*.*#***#***#***#","***#***#***#***#"]
c=["RGGGGGGGGGGGGGGG","RBRRRGRRRGRRRGRR","RBRRRGRRRGRRRGRR","RBRRGGGRGGGRGGGR","BRRRGGGRGGGRGGGR","BRRRGRRRGRRRGRRR","BRRRGGGRGGGRGGGR","RBRRGGGRGGGRGGGR","BRRRGGGRGGGRGGGR","BRRRGRRRGRRRGRRR","BGRRGGGRGGGRGGGR","RBRRGGGRGGGRGGGR"]
y=10; x=1; d=0
f="_2_R_R_1|_FgRgFgFg3rRr4b2_Fgb|_F_F_R|_2_L_r||"
// result:1

Kendi testinizi oluşturmak için robozzle.com adresindeki listeden bir bulmacaya gidin , çözmeye çalışın (veya çözmeyin ), tarayıcınızda F12 tuşuna basın, JS konsoluna yazın:

r=robozzle;s=JSON.stringify;with(r.level)console.log('a='+s(Items)+'\nc='+s(Colors)+'\ny='+RobotRow+'\nx='+RobotCol+'\nd='+RobotDir+'\nf='+s(r.encodeSolution()))

ve sonucu diliniz için yeniden biçimlendirin.

En kısa kazanç. Boşluk yok.


1
Verileri göstermek için sağlananlar yerine farklı karakterler kullanabilir miyiz?
HyperNeutrino

1
"Loop it" yarışmasına APL yanıtınız için, karmaşık açıyı azaltarak son açı değerini sıralayabilirsiniz.
user202729

1
@ user202729 Uh, burada bu meydan okuma hakkında bir yorum beklemiyordum :) Fikriniz işe yarıyor, teşekkürler! Karakter sayısını çok utanç verici hale getirmeden uygulamaya çalışacağım.
ngn

1
Karakter matrislerini, yer ve karakter çiftlerinin bir listesi olarak alabilir miyiz?
0

1
@ 0 'Burada takip ettiğim ilke (ayrıca bkz. HyperNeutrino'nun yorumu) robozzle.com'da kullanılan giriş formatına mümkün olduğunca yakın kalmaktır, bu yüzden bir çift listesi olmamasından korkuyorum.
ngn

Yanıtlar:


5

Prolog (SWI) , 574 bayt

Z*A:-findall(X^Y-D,(nth0(Y,Z,O),nth0(X,O,C),plus(32,C,D)),L),list_to_assoc(L,A).
N^C^G^[P,I|R]^F^X^Y^D:-map_assoc(\=(74),G);N<1e3,get_assoc(X^Y,G,J),J>67,put_assoc(X^Y,G,78,H),T=N+1,((I\=95,(P=95;get_assoc(X^Y,C,P)))->(between(49,53,I),plus(48,M,I),nth1(M,F,Q),append(Q,R,S),T^C^H^S^F^X^Y^D;member(I,`RL`),E is(D-I//3)mod 4,T^C^H^R^F^X^Y^E;I=70,(D=0,U is X+1;D=1,V is Y+1;D=2,U is X-1;D=3,V is Y-1),(U=X;V=Y),T^C^H^R^F^U^V^D;I>97,put_assoc(X^Y,C,I,W),T^W^H^R^F^X^Y^D);N^C^H^R^F^X^Y^D).
A+C+F+L:-A*G,C*B,split_string(F,"|","",P),maplist(string_codes,P,[M|N]),0^B^G^M^[M|N]^L.

Çevrimiçi deneyin!

Bu, tüm yıldızların başarılı bir şekilde toplanması ve aksi takdirde başarısız olması durumunda çağrıldığında başarılı olduğunu belirten bir tanım tanımlar. Yüklem gibi bağımsız değişkenleri alır: a+c+f+x^y^d.. ave csüre, ters tırnak alıntı dizeleri listeleri olmalıdır fçift tırnak dize olmalıdır.

açıklama

Bu program üç yüklemleri içeren, */2, ^/2, ve +/2. */2İlk satırda tanımlanmış olan temel fonksiyonlar, giriş işlemlerinin bir parçası sorumludur. ^/2Yüklem yinelemeli robot hareket adım adım nasıl hesaplar ve robot yasal tüm yıldızları toplayarak aksi başarısız olursa başarılı olur. +/2Yüklem programın ana yüklem ve için girdi hazırlar ^/2bazı yardımıyla yüklemi */2yüklemi. Bunların her birinin teknik olarak sadece iki argüman aldığını unutmayın, ancak operatörler ve kalıp eşleşmesini kullanarak daha fazla argümanları varmış gibi davranabilirler (bu fenomeni burada daha ayrıntılı olarak tartışıyorum ).

*/2

Z*A:-findall(X^Y-D,(nth0(Y,Z,O),nth0(X,O,C),plus(32,C,D)),L),list_to_assoc(L,A).

Bu yüklem iki argüman gerektirir. Birincisi, karakter kodlarının bir listesidir (Prolog, tırnak işaretli dizeleri bu şekilde ayrıştırır). İkincisi, 12x16 haritasındaki noktalardan (olarak temsil edilir X^Y) 32'ye artı karakter kodları listesinde o noktada depolanan karakter koduyla ilişkilendirilebilir bir haritadır . 32 karakter kodlarının her birine eklenir, böylece renk matrisi için büyük harfli karakterleri küçük harfli karakterlere dönüştürür.

Bunu yapmanın yolu, nokta noktalarının ve o noktadaki karakter kodlarının bir listesini oluşturur findall/3. Daha sonra list_to_assoc/2noktalardan o noktadaki karakter koduna karşılık gelen ilişkilendirilebilir harita oluşturmak için kullanılır.

findall/3Yüklem yerleşik bir ilk argüman, ikinci argüman olarak bir hedef ve üçüncü bağımsız değişken olarak bir liste olarak bir "şablon" sürer. Yüklem, listeyi hedefin başarılı olmasına neden olan olası tüm olası değerlerle doldurur. Operatör önceliği, geçirilir şablona nedeniyle findall/3de */2olduğu gibi çözümlenir (X^Y)-D. -Şablon noktasının konumunu temsil eder (böylece operatör Prolog iki değerlerinin bir çiftini temsil eder X^Y32 artı noktasının karakter kodu ile eşleştirilmiş) ( D). ^Noktayı temsil ederken kullanılanın ^/2yükleme hiçbir şekilde bağlı olmadığını unutmayın .

Yüklemine aktarılan hedefi ele alalım findall/3.

nth0(Y,Z,O),nth0(X,O,C),plus(32,C,D) % Note that the O (oh) is not a 0 (zero)

Hedef, her birinin başarılı olması için başarılı olması gereken üç tahmin içerir. nth0/3İki kez kullanılan yüklem listesinin belli bir dizinde değeri elde etmek için kullanılır ( 0adında da endeksli sıfır olduğunu gösterir). İlk çağrı Y, karakter matrisinin th satırını O, ikinci çağrı Xise o satırdaki th karakterini saklar C. Son plus/3iki argüman, ilk iki argümanı üçüncü argümanıyla toplanırsa başarılı olur. Bu, çiftteki karakter kodunun, yukarıda belirtildiği gibi tüm büyük harfleri küçük harfe çevirecek olan karakter matrisindeki karakter kodundan 32 daha büyük olmasını sağlamak için kullanılır.

Son olarak , amacının başarılı olmasına neden olan findall/3tüm X^Y-Dkombinasyonları Lilişkilendirilebilir haritanın oluşturulduğu listede saklar .

Çok Yakında ...


4

JavaScript (ES6), 298 276 264 bayt

@Ngn sayesinde 8 bayt kaydedildi

Girdi , karakter dizisi dizisi olarak (a,c,x,y,d,f), nerede ave cdiziler olarak alınır. 0Veya döndürür 1.

(a,c,x,y,d,f,k=1e3)=>(g=(F,p=0,s=f.split`|`[F],r=a[y])=>!k|!r|x&16||r[x]<'$'?2:/\*/.test(a)?(r[x]=o=0,(I=s[p+1],P=s[p])&&(P<'b'|P==c[y][x].toLowerCase()&&I!='_'&&k--?+I?o=g(I-1):I=='L'?d--:I=='R'?d++:I<'b'?y+=(d&=3,x-=~-d%2,2-d)%2:c[y][x]=I:0,o||g(F,p+2))):1)(0)&1

Test senaryoları

Yorumlananlar

(                                           // main function taking:
  a, c, x, y, d, f,                         //   - input variables
  k = 1e3                                   //   - k = instruction counter
) => (                                      //
  g = (                                     // g = recursive execution function, taking:
    F,                                      //   - F = subroutine id
    p = 0,                                  //   - p = instruction pointer
    s = f.split`|`[F],                      //   - s = instruction string
    r = a[y]                                //   - r = current row in a[]
  ) =>                                      //
    !k |                                    // if we've executed 1000 instructions
    !r | x & 16 ||                          // or we've felt out of the map
    r[x] < '$' ?                            // or we've reached a black square:
      2                                     //   exit with error code 2
    :                                       // else:
      /\*/.test(a) ? (                      //   if there are still some stars:
        r[x] = o = 0,                       //     mark the current cell as visited
        (I = s[p + 1], P = s[p]) &&         //     I = instruction, P = predicate
        (                                   //     if P is defined:
          P < 'b' |                         //       if the predicate is '_'
          P == c[y][x].toLowerCase()        //       or it matches the color of the cell
          && I != '_'                       //       and the instruction is not '_',
          && k-- ?                          //       then decrement k and:
            +I ?                            //         if I is '1' ... '5':
              o = g(I - 1)                  //           process call to subroutine
            :                               //         else:
              I == 'L' ?                    //           if I is 'L':
                d--                         //             turn left
              :                             //           else:
                I == 'R' ?                  //             if I is 'R':
                  d++                       //               turn right
                :                           //             else:
                  I < 'b' ? (               //               if I is not a color:
                    y += (                  //                 I must be 'F',
                      d &= 3,               //                 so make the bot advance
                      x -= ~-d % 2,         //                 by updating x
                      2 - d                 //                 and y
                    ) % 2                   //
                  ) :                       //               else:
                    c[y][x] = I             //                 paint the current cell
          :                                 //       else:
            0,                              //         do nothing
          o ||                              //       provided that o is equal to 0,
          g(F, p + 2)                       //       go on with the next instruction
        )                                   //     end of instruction execution
      ) :                                   //   else:
        1                                   //     success: return 1
  )(0) & 1                                  // initial call to the subroutine F1

x+='2101'[d&3]-1,y+='1210'[d&3]-1->d&=3,x+=(1-d)%2,y+=(2-d)%2
ngn

1
xBen değiştirmek mi düşünüyorsun, 1 en fazla tarafından değiştirir x&~15ilex&16
ngn

1

APL (Dyalog Klasik) , 236 233 bayt

-3 Outgolfer Erik sayesinde

Şimdi bonusu verdim, kendi zorluğuma örnek bir çözüm gönderiyorum. Burada iyileştirme için yer var - daha fazla kopyalamak ve golf oynamaktan çekinmeyin.

a c r d f←⎕⋄c819cF0,('|'1f)/⍳≢ftn0
{~(⊂r)∊⍳⍴a:0'#'=ra:0p q2f↓⍨⊃⌽t⋄(_p'|')∧×≢t:0_:∇t↓←¯1⋄(⊃⌽t)+←2⋄~p'_',rc:∇0n+←1n>999:0⋄(ra)←'.'⋄~'*'a:1r+←(q'F'11 90j1*dd+←4|'.R.L'qq'rgb':∇(rc)←qq∊⎕d:∇t,←F[⍎q]⋄∇0}0

Çevrimiçi deneyin!

Yukarıdaki ile aynı, yorumlarla genişletildi:

io0                    0-based indices (not counted in the score)
a c r d f←⎕              decompose eval'ed input (⎕) into variables
c←819⌶c                 ⍝ make c lowercase
F←0,('|'=¯1⌽f)/⍳≢f      ⍝ split f at the '|'-s
t←n←0                   ⍝ t:stack, n:step counter
{                       ⍝ lambda
  ~(⊂r)∊⍳⍴a:0           ⍝ if the robot is off the map, return 0
  '#'=r⌷a:0             ⍝ if the robot is on a wall, return 0
  p q2f↓⍨⊃⌽t           current instruction - p:predicate, q:action
  (_p'|')∧1≥≢t:0       if at end of func and stack is empty, return 0
  _:∇t↓←¯1               if at end of func, pop from stack and recurse
  (⊃⌽t)+←2               increment program counter (top of stack)
  ~p'_',rc:∇0          if predicate doesn't match cell colour, recurse
  n+←1⋄n>999:0          ⍝ if too meany steps, return 0
  (r⌷a)←'.'             ⍝ consume star
  ~'*'∊a:1              ⍝ if no more stars left, return 1
  r+←(q≡'F')×11 9○0j1*d ⍝ if action is F, move forward
  d+←4|'.R.L'⍳q         ⍝ if action is L or R, turn left or right
  q∊'rgb':∇(r⌷c)←q      ⍝ if action is paint (r,g,b), do it
  q∊⎕d:∇t,←F[⍎q]        ⍝ if action is F1...F5, push on stack and recurse
  ∇0                    ⍝ action is nop (_), recurse
}0                      ⍝ call the lambda (argument will be ignored)


@EriktheOutgolfer değişikliği uygulandı, teşekkürler
ngn
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.