RoboZZle 통역사 인 경우”, “파란색 인 경우”)와

당신의 임무는 RoboZZle 통역사를 작성하는 것입니다. 게임에 익숙하지 않은 경우 robozzle.com비디오를 보거나 아래 설명을 읽으십시오.

로봇은 빨간색, 녹색, 파란색 또는 검은 색의 사각형 사각형 격자에 있습니다. 검은 색 사각형에 액세스 할 수 없습니다. 다른 사람들은 접근 할 수 있고 그들 중 일부는 별을 포함합니다. 목표는 검은 사각형을 밟거나지도에서 떨어지지 않고 모든 별을 모으는 것입니다. 로봇은 하나의 사각형을 차지하고 왼쪽, 오른쪽, 위 또는 아래로 특정 방향을 향합니다. 서브 루틴 F1, F2, …, F5로 그룹화 된 어셈블리와 같은 명령어를 따릅니다. 명령은 한 쌍의 술어 ( “없음”, “적색 인 경우”, “녹색 인 경우”, “파란색 인 경우”)와 조치 ( “앞으로 이동”, “왼쪽으로 돌림”, “오른쪽으로 돌리기”, “현재 사각 빨간색 페인트”, “녹색 페인트”, “파란색 페인트”, “아무것도하지 않음”, “call F1”, …, “call F5”). 서브 루틴 호출은 스택을 사용하며 재귀적일 수 있습니다. 기존 프로그래밍과 마찬가지로 서브 루틴의 마지막 명령이 완료된 후 서브 루틴이 호출 된 지점부터 실행이 계속됩니다. 실행은 F1의 첫 번째 명령에서 시작하여 로봇이 별이있는 모든 사각형을 방문하거나 로봇이 검은 사각형 또는지도 외부에 닿을 때까지 또는 1000 개의 명령이 실행될 때 (조건 자 실패 및 “아무것도하지 않음”동작)까지 계속됩니다. 계산하지 않거나) 실행할 명령이 더 이상 없습니다 (스택 언더 플로).

입력 :

  • a-지도를 인코딩하는 12×16 문자 매트릭스 (일반적으로 언어로 표시되는 문자열 배열)- '#'액세스 할 수없는 (검은 색) 사각형, '*'별이있는 사각형, '.'나머지

  • c-액세스 가능한 사각형의 색상을 설명하는 12×16 문자 매트릭스- 'R'(빨간색), 'G'(녹색) 또는 'B'(파란색). 액세스 할 수없는 사각형은 3 개의 임의의 문자로 표시됩니다.

  • y그리고 x-로봇의 0 기반 행과 열; a[y][x]~로 보장된다'.'

  • d– 방향이 로봇이 직면 : 0 1 2 3권리, 아래로, 즉쪽으로, 위, 왼쪽 (y,x+1), (y+1,x), (y,x-1),(y-1,x)

  • f-단일 문자열, 연결된 F1 … F5 구현. 각 구현은 술어 조치 쌍 (서브 루틴 당 최대 10 쌍)의 시퀀스 (비어있을 수 있음) '|'입니다.

    • 술어 : '_'없음, 'r'빨강, 'g'초록, 'b'파랑

    • 행동 : 'F'앞으로 이동, 'L'좌회전, 'R'우회전, 'r'빨간색 'g'페인트, 녹색 'b'페인트, 파란색 페인트, '1'F1 호출, …, '5'F5 호출, '_'아무것도하지 마십시오

위와 같이 입력 이름을 지정할 필요는 없지만 해당 값은 지정해야합니다.

출력 : 1(또는 true) 로봇이 규칙에 따라 모든 별을 수집하는 경우 0( false) 그렇지 않은 경우

:

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)

“페인트”명령과 관련된 또 다른 :

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

자체 테스트를 생성하려면 robozzle.com의 목록에서 퍼즐로 이동하여 문제를 해결하거나 시도하지 마십시오. 브라우저에서 F12를 누르고 JS 콘솔에 입력하십시오.

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

언어의 결과를 다시 포맷하십시오.

최단 승리. 허점이 없습니다.



답변

프롤로그 (SWI) 574 바이트

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.

온라인으로 사용해보십시오!

이것은 모든 별들이 성공적으로 수집되고 그렇지 않으면 실패하면 호출 될 때 성공하는 술어를 정의합니다. 술어는 다음과 같은 인수를 취합니다 a+c+f+x^y^d.. ac동시에, 역 따옴표 인용 문자열의 목록이어야 f이중 인용 문자열이어야합니다.

설명

이 프로그램은 세 가지 술어를 포함, */2, ^/2,와 +/2. */2첫 줄에 정의 된 조건 입력 처리의 일부분에 대응한다. ^/2술어는 재귀 적 로봇 이동 단계별로 어떻게 계산하고 로봇이 법적으로 모든 별을 수집하고, 그렇지 않으면 실패 할 경우 성공합니다. +/2술어는 프로그램의 기본 조건이며, 대한 입력을 준비 ^/2로부터 약간의 도움으로 술어 */2술어. 이 술어 각각은 기술적으로 두 개의 인수 만 취하지 만 연산자와 패턴 일치를 사용하면 더 많은 인수가있는 것처럼 동작 할 수 있습니다 (여기서이 현상에 대해 자세히 설명 합니다 ).

*/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).

이 술어는 두 가지 주장을 취합니다. 첫 번째는 문자 코드 목록의 목록입니다 (이는 Prolog가 백틱 인용 문자열을 구문 분석하는 방법입니다). 두 번째는 12×16 맵 (으로 표시 X^Y)의 포인트에서 32까지의 문자 맵 과 해당 포인트에 저장된 문자 코드 목록의 연관 코드입니다. 32는 각 문자 코드에 추가되어 색상 매트릭스의 경우 대문자 문자를 소문자 문자로 바꿉니다.

이를 수행하는 방법은을 사용하여 점 쌍과 해당 지점의 문자 코드 목록을 생성하는 것 findall/3입니다. 그런 다음 list_to_assoc/2점에서 해당 지점의 문자 코드까지 해당 연관 맵을 작성하는 데 사용 됩니다.

findall/3술어는 기본적 으로 “템플릿”을 첫 번째 인수로, 목표를 두 번째 인수로, 목록을 세 번째 인수로 취합니다. 술어는 목표가 성공하게하는 가능한 모든 템플리트 값으로 목록을 채 웁니다. 연산자 우선 순위에 전달되는 템플릿으로 인해 findall/3*/2로 분석된다 (X^Y)-D. -템플릿 점의 위치 (대표되도록 오퍼레이터 프롤로그 두 값의 쌍을 나타내고, X^Y(32)를 더한 지점의 문자 코드와 쌍을 () D). (가) 있습니다 ^지점을 나타내는에서 사용이에 연결된 방식에 ^/2술어.

findall/3술어에 전달되는 목표를 고려해 봅시다 .

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

목표에는 목표를 달성하기 위해 각각 성공해야하는 세 가지 술어가 포함됩니다. nth0/3두 번 사용하는 술어 목록의 특정 인덱스에서 값을 가져 오는 데 사용합니다 (이 0이름에 인덱싱 제로 표시). 첫 번째 호출 Y은 문자 행렬 의 세 번째 행을 O저장하고 두 번째 호출은 X해당 행 의 세 번째 문자를에 저장합니다 C. plus/3첫 번째 두 인수가 세 번째 인수와 합치면 최종 술어 가 성공합니다. 이것은 쌍의 문자 코드가 문자 행렬의 문자 코드보다 32 더 크게 만드는 데 사용되며 위에서 언급 한 것처럼 모든 대문자를 소문자로 바꿉니다.

마지막으로 연관 맵이 작성된 목록에 목표가 성공하도록하는 findall/3모든 X^Y-D조합을 저장합니다 L.

더 곧 올 …


답변

자바 스크립트 (ES6), 298 276 264 바이트

@ngn 덕분에 8 바이트 절약

입력을로 (a,c,x,y,d,f), 위치 ac문자 배열 로 취 합니다. 반환 0또는 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

테스트 사례

let f =

(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

getA = _ => [
  "################",
  "################",
  "##*....*...*#.##",
  "##.####.#####.##",
  "##.####.#####.##",
  "##.####*...*#.##",
  "##.########.####",
  "##*........*#.##",
  "################",
  "################",
  "################",
  "################"
].map(s => [...s]);

getC = _ => [
  "RRRRRRRRRRRRRRRR",
  "RRRRRRRRRRRRRRRR",
  "RRRBBBBRGGGGRRRR",
  "RRBRRRRGRRRRRRRR",
  "RRBRRRRGRRRRRRRR",
  "RRBRRRRRGGGBRRRR",
  "RRBRRRRRRRRGRRRR",
  "RRRBBBBGGGGBRBRR",
  "RRRRRRRRRRRRRRRR",
  "RRRRRRRRRRRRRRRR",
  "RRRRRRRRRRRRRRRR",
  "RRRRRRRRRRRRRRRR"
].map(s => [...s]);

y=2; x=6; d=2;

[
  "_FrLg2_1|_FbLrR_2||||", // result:1
  "_FrRg2_1|_FbLrR_2||||", // result:0 (stepped on a black square)
  "_FrLrL_1|_FbLrR_2||||", // result:0 (1000-step limit exceeded)
  "_FrLg2__|________||||"  // result:0 (stack underflow)
]
.forEach(code => console.log('Example #1', code, '-->', f(getA(), getC(), x, y, d, code)));

getA = _ => [
  "#***************",
  "#*###*###*###*##",
  "#*###*###*###*##",
  "***#***#***#***#",
  "***#***#***#***#",
  "*###*###*###*###",
  "***#***#***#***#",
  "***#***#***#***#",
  "***#***#***#***#",
  "*###*###*###*###",
  "*.*#***#***#***#",
  "***#***#***#***#"
].map(s => [...s]);

getC = _ => [
  "RGGGGGGGGGGGGGGG",
  "RBRRRGRRRGRRRGRR",
  "RBRRRGRRRGRRRGRR",
  "RBRRGGGRGGGRGGGR",
  "BRRRGGGRGGGRGGGR",
  "BRRRGRRRGRRRGRRR",
  "BRRRGGGRGGGRGGGR",
  "RBRRGGGRGGGRGGGR",
  "BRRRGGGRGGGRGGGR",
  "BRRRGRRRGRRRGRRR",
  "BGRRGGGRGGGRGGGR",
  "RBRRGGGRGGGRGGGR"
].map(s => [...s]);

y=10; x=1; d=0;

[
  "_2_R_R_1|_FgRgFgFg3rRr4b2_Fgb|_F_F_R|_2_L_r||" // result:1
]
.forEach(code => console.log('Example #2', code, '-->', f(getA(), getC(), x, y, d, code)));

댓글

(                                           // 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

답변

APL (Dyalog 기본) , 236 (233) 바이트

Outgolfer Erik 덕분에 -3

이제 보너스를 주었으므로 샘플 솔루션을 내 도전에 게시하고 있습니다. 여기에는 개선의 여지가 있습니다-더 자유롭게 복사하고 골프를 즐기십시오.

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

온라인으로 사용해보십시오!

위와 동일하며 주석으로 확장되었습니다.

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)