오래 전에 RPG 게임에 더 많은 시간을 할애했을 때 일부 플레이어의 문제 중 하나는 파티 움직임을 추적하고 적절한지도를 그리는 것이 었습니다. 그래서 나는 여러분 이이 문제를 어떻게 다루는 지 확인하기 위해 아이디어를 얻었습니다.
작업은 방향의 입력 매개 변수 목록 (선택한 구조로 전달됨) ^v<>
, 던전의 표시 맵을 사용 하는 함수를 작성하는 것 입니다. 입력 예 : >>>vvv<<<^^^
출력은 다음과 같습니다.
+----+ +----+
| | |>>>v|
| ++ | |^++v|
| ++ | because |^++v|
| | |^<<<|
+----+ +----+
테스트 케이스
>>>>>>vvvvv<<<<^^^>>v
+-------+
| |
+-+---+ |
| | |
| + | |
| +-+ |
| |
+-----+
^^^^^vvv<<<^^vv>>>>>>>>vv>><<^^^^v>>>>v^<^
+-+
+-+| | +-++-+
| || | | ++ ++
| ++ +-+ |
| +-+ |
+--+ +-+ +-+-+
| | | |
+-+ +---+
골프 코드 챌린지이므로 가장 짧은 코드가 승리합니다.
행복한 골프.
편집
늦게 편집해서 죄송합니다. 최근에 시간이 많지 않았습니다.
움직임에 따라 맵이 생성됩니다. 보행 중에 방문한 복도 만 포함해야합니다. 따라서 하나의 큰 방을 만드는 것은 올바른 대답이 아닙니다.
맵에는 세 가지 유효한 기호가 있습니다.
|
수 직벽|
수평 벽+
수직 및 수평 벽의 교차점.
경로의 최대 길이는 255 자입니다 (그러나 가능한 경우 자신을 제한하지 마십시오).
더 많은 테스트 사례 :
><><><><
+--+
| |
+--+
>^<v
+--+
| |
| |
+--+
나는 이제 모든 것이 분명하기를 바랍니다.
답변
자바 스크립트 (ES6), 261 254 243 바이트
s=>{v=Array(w=32);p=526;b=n=>v[n>>5]&(1<<(n&31));B=(n,i)=>b(p+n)|b(p-n)?i:0;[...0+s].map(c=>v[(p+=[0,1,-1,w,-w]['0><v^'.indexOf(c)])>>5]|=1<<(p&31));for(z='',p=0;p<w*w;z+=' |-+'[b(p)?0:B(1,1)|B(w,2)||B(31,3)|B(33,3)],p++%w||(z+=`
`));return z}
JSFiddle
답변
C, 246 바이트
n,y,*g,*p;main(c,v)char**v;{for(n=c*2+3,g=calloc(n*n,8),p=g+(n+1)*(c+1);c--;y=*v[c],p-=(y>70?n:1)*(y%5%4?-1:1))*p=1;for(y=n-1;--y;)for(c=n-1;c--;putchar(c?" |-++|-+"[*p?0:p[1]|p[-1]|(p[n]|p[-n])*2|(p[1+n]|p[1-n]|p[n-1]|p[-n-1])*4]:10))p=g+y*n+c;}
예를 들어 입력을 별도의 문자로 사용합니다.
./mapper '>' '>' '>' 'v' 'v' 'v' '<' '<' '<' '^' '^' '^'
또는 더 편리하게는 (의도적으로 인용되지 않은!) 형식입니다.
./mapper $(echo '>>>vvv<<<^^^' | fold -w1)
또는 (아주 비효율적 인) 임의 입력의 경우 :
./mapper $(LC_CTYPE=C tr -dc '0-3' < /dev/urandom | tr '0123' '<>^v' | head -c 10 | fold -w1)
마지막으로 awk
결과를 자르기 위해 사용 하면 훨씬 더 커질 수 있습니다.
./mapper $(LC_CTYPE=C tr -dc '0-3' < /dev/urandom | tr '0123' '<>^v' | head -c 500 | fold -w1) | awk '/[^ ]/{l=match($0,"\\+");if(l&&(l<L||!L))L=l;v[i++]=$0}END{for(;j<i;){l=v[j++];print substr(l,L,match(l," *$")-L)}}'
+-----+
| |
| +-+ +-----+
| |+-+ |
++ +| ++
| | |
| + +-+
+--+ |
+-+ +--+
| ++ |
+-+ +-++ +-+
++ |+--+ |
+-+ | | ++ |
++ | ++ + +--+ ++
| | +---| |
| | ++ +---+
++ |-+ | |
| | +--+-+ |
| + + |
| +--+
+--------+
stdout으로 출력합니다. 맵 주위에 패딩이 허용된다는 사실을 사용합니다 (가장자리 길이가 2 * n + 1 인 맵을 생성하여 최종 위치를 중간에 배치).
고장
이것은 인수를 역순으로 반복하고 역순으로 이동하여 작동합니다. 실제로 arg 0은 프로그램 이름이라는 사실을 사용합니다. 이름이 무엇이든 중요하지 않지만 특별한 처리가 필요없이 초기 및 마지막 셀 (및 그 사이의 모든 셀)을 모두 방문 할 수 있습니다.
n, // Size of internal grid
y, // Loop counter / current character
*g, // Internal grid memory
*p; // Current working pointer
main(c,v)char**v;{ // K&R style function declaration
for( // Step 1: identify visited cells
n=c*2+3, // Set output grid size
g=calloc(n*n,8), // Allocate map storage space
p=g+(n+1)*(c+1); // Start at centre
c--; // Loop over directions in reverse
y=*v[c], // Get current direction
p-=(y>70?n:1)*(y%5%4?-1:1) // Move in reverse
)*p=1; // Mark cell visited
for(y=n-1;--y;) // For each row (except edges)
for(c=n-1;c--; // For each column (except edges, +1 for \n)
putchar(c?" |-++|-+"[ // Print wall using lookup table
*p?0:p[1]|p[-1]|(p[n]|p[-n])*2|(p[1+n]|p[1-n]|p[n-1]|p[-n-1])*4
]:10) // Or newline
)p=g+y*n+c; // Set current cell (happens first)
}