Avast, scallywags!


10

블랙 비어드는 초기 18의 영어 해적이었다 번째 세기. 배를 약탈하고 배를 타는 것으로 알려졌지만 선원들의 허락을 받아 배를 지휘했다. 그의 포로들을 해치거나 살해 한 적이 없다고하는 기록은 없다.

이 도전은 악명 높은 Blackbeard를 기리기 위한 것이며 해적의 날과 같은 International Talk (9 월 19 일)에서 영감을 얻었습니다 . 또한,의 역인 이러한 과제 에 의해 피라 (Pyrrha) .


도전

보물지도를 입력 (아래 나열된 문자로 구성)으로 가져 와서 방향을 출력하는 프로그램을 작성하십시오.


입력

모든 입력은 다음과 같이 구성한다 v, >, <, ^, 공백, 단일 X.

다음을 가정 할 수 있습니다.

  • 지도는 절대 반복되거나 교차하지 않습니다

  • 시작 화살표는 항상 가장 왼쪽 열의 맨 아래 문자입니다

  • 항상 보물이있을 것입니다 ( X)

샘플 입력은 다음과 같습니다.

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

산출

출력은- ", "방향으로 구분 된 문자열 이어야합니다 . 아래는 위의지도에서 올바른 결과입니다.

E2, N6, E2, S4, E4, N4, E6, S2, W2, S2, E2

하나의 후행 줄 바꿈 또는 공백이 허용됩니다.


In:
>>>>>>>>>>>>>>>v
               v
               v
               >>>>X

Out:
E15, S3, E4

In:
>>>>>>v
^     v
^     >>>>X

Out:
N2, E6, S2, E4

In:
X
^
^
^

Out:
N3

In:
>>>>>>v
^     v
^     v
      v
      >>>>>>X

Out:
N2, E6, S4, E6

In:
 X
 ^
 ^
>^

Out:
E1, N3

In:
>X

Out:
E1

In:
v<<<<<
vX<<<^
>>>>^^
>>>>>^

Out:
E5, N3, W5, S2, E4, N1, W3

해적의 날처럼 행복한 국제 대화!


가장 왼쪽 열에 둘 이상의 오른쪽 화살표가있는 예를 들어 경로가 첫 번째 열로 다시 반복되는 예를 포함 할 수 있습니다. 이 경우 경로의 시작을 식별하는 것이 약간 까다 롭습니다.
Reto Koradi

귀하의 요청에 따라 예를 추가했습니다. 또한 시작 문자가 열의 가장 아래쪽에 있다는 세부 사항을 추가했습니다. @RetoKoradi
Zach Gates

나는 때문에 약간의 문제 제기 마지막 세그먼트의 길이에 대한 관련 문제를 다시 한번 nitpick이 정확히 여기에 반대 질문이 아니라고 말할 것이다. 누군가가 다시 한번 해적을 속이려하고 있다고 생각합니다.
coredump

유일한 차이점은 마지막 방향의 걸음 수입니다. @coredump 적어도 내가 알 수있는 한.
Zach Gates

1
@ZachGates 예, 정확히 (그리고 분명하게 말하면, 질문을 수정해야한다고 말하는 것이 아닙니다. 현재와 같이 좋습니다).
coredump

답변:


3

CJam, 78 바이트

qN/_:,$W=:Tf{Se]}s:U,T-{_U="><^vX"#"1+'E1-'WT-'NT+'S0"4/=~_@\}g;;]e`{(+}%", "*

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

설명

여기서 가장 중요한 아이디어는 가장 긴 줄을 찾은 다음 (이 길이라고 함 T) 모든 줄을 같은 길이로 채우고 연결합니다 (이 새로운 문자열은 U). 이런 식으로 맵에서 이동하려면 단일 카운터 만 필요합니다. 더하기 / 빼기 1는 같은 줄에서 오른쪽 / 왼쪽으로 이동하는 것을 의미하고, 더하기 / 빼기 T는 한 줄 아래로 / 위로 이동하는 것을 의미합니다.

qN/    e# Split the input on newlines
_:,    e# Push a list of the line lengths
$W=:T  e# Grab the maximum length and assign to T
f{Se]} e# Right-pad each line with spaces to length T
s:U    e# Concatenate lines and assign to U

이제 루프를 설정할 차례입니다.

,T-    e# Push len(U) - T
       e# i.e. position of first char of the last line
{...}g e# Do-while loop
       e# Pops condition at the end of each iteration

루프 본문은 조회 테이블과 평가를 사용하여 수행 할 작업을 선택합니다. 각 반복이 시작될 때 맨 위 스택 요소가 현재 위치입니다. 그 아래에는 처리 된 모든 NSWE 지침이 있습니다. 반복이 끝나면 새 방향이 위치 아래에 배치되고 사본의 사본이 루프 조건으로 사용됩니다. 0이 아닌 문자는 진실입니다. X가 발생하면 방향으로 0이 밀려 루프가 종료됩니다.

_U=      e# Push the character in the current position
"><^vx"# e# Find the index in "><^Vx"
"..."4/  e# Push the string and split every 4 chars
         e# This pushes the following list:
         e# [0] (index '>'): "1+'E" pos + 1, push 'E'
         e# [1] (index '<'): "1-'W" pos - 1, push 'W'
         e# [2] (index '^'): "T-'N" pos - T, push 'N'
         e# [3] (index 'v'): "T+'S" pos + T, push 'S'
         e# [4] (index 'X'): "0"    push 0
=~       e# Get element at index and eval
_@\      e# From stack: [old_directions position new_direction]
         e# To stack: [old_directions new_direction position new_direction]
         e# (You could also use \1$)
         e# new_direction becomes the while condition and is popped off

이제 스택은 다음과 같습니다 [directions 0 position]. 출력을 생성합시다.

;;    e# Pop position and 0 off the stack
]     e# Wrap directions in a list
e`    e# Run length encode directions
      e# Each element is [num_repetitions character]
{     e# For each element:
 (+   e#   Swap num_repetitions and character
}%    e# End of map (wraps in list)
", "* e# Join by comma and space

3

CJam, 86 바이트

qN/_,{1$=cS-},W=0{_3$3$==_'X-}{"^v<>"#_"NSWE"=L\+:L;"\(\ \)\ ( )"S/=~}w];Le`{(+}%", "*

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

설명:

qN/     Get input and split into rows.
_,      Calculate number of rows.
{       Loop over row indices.
  1$=     Get row at the index.
  c       Get first character.
  S-      Compare with space.
},      End of filter. The result is a list of row indices that do not start with space.
W=      Get last one. This is the row index of the start character.
0       Column number of start position. Ready to start tracing now.
{       Start of condition in main tracing loop.
  _3$3$   Copy map and current position.
  ==      Extract character at current position.
  _'X-    Check if it's the end character `X.
}       End of loop condition.
{       Start of loop body. Move to next character.
  "^v<>"  List of directions.
  #       Find character at current position in list of directions.
  _       Copy direction index.
  "NSWE"  Matching direction letters.
  =       Look up direction letter.
  L\+:L;  Append it to directions stored in variable L.
  "\(\ \)\ ( )"
          Space separated list of commands needed to move to next position for each of
          the 4 possible directions.
  S/      Split it at spaces.
  =       Extract the commands for the current direction.
  ~       Evaluate it.
}w      End of while loop for tracking.
];      Discard stack content. The path was stored in variable L.
Le`     Get list of directions in variable L, and RLE it.
{       Loop over the RLE entries.
  (+      Swap from [length character] to [character length].
}%      End of loop over RLE entries.
", "*   Join them with commas.

2

자바 스크립트 (ES6), 239 바이트

a=>(b=a.split`
`,b.reverse().some((c,d)=>c[0]!=' '&&((e=d)||1)),j=[],eval("for(g=b[e][f=0];b[e][f]!='X';g=b[e][f],j.push('NSEW'['^v><'.indexOf(i)]+h))for(h=0;g==b[e][f];e+=((i=b[e][f])=='^')-(i=='v'),f+=(i=='>')-(i=='<'),h++);j.join`, `"))

설명:

a=>(
    b = a.split('\n'),
    // loops through list from bottom to find arrow
    b.reverse().some(
        (c, d)=>
            // if the leftmost character is not a space, saves the index and exit
            // the loop
            // in case d == 0, the ||1 makes sure the loop is exited
            c[0] != ' ' && ((e = d) || 1)
    ),
    j = [], // array that will hold the instructions
    eval("  // uses eval to allow a for loop in a lambda without 'return' and {}

        // loops through all sequences of the same character
        // e is the first coordinate of the current character being analyzed
        // f is the second coordinate
        // defines g as the character repeated in the sequence
        // operates on reversed b to avoid using a second reverse
        // flips ^ and v to compensate

        for(g = b[e][f = 0];
            b[e][f] != 'X'; // keep finding sequences until it finds the X
            g = b[e][f],    // update the sequence character when it hits the start of a
                            // new sequence
            j.push('NSEW'['^v><'.indexOf(i)] + h)) // find the direction the sequence is
                                                   // pointing to and add the
                                                   // instruction to j

            // loops through a single sequence until it hits the next one
            // counts the length in h
            for(h = 0;
                g == b[e][f]; // loops until there is a character that isn't part of
                              // the sequence
                // updates e and f based on which direction the sequence is pointing
                // sets them so that b[e][f] is now the character being pointed toward
                e += ((i = b[e][f]) == '^') - (i == 'v'),
                f += (i == '>') - (i == '<'),
                // increments the length counter h for each character of the sequence
                h++);

            // return a comma separated string of the instructions
            j.join`, `
    ")
)

0

자바 스크립트 (ES6), 189

EcmaScript 6 호환 브라우저에서 아래 스 니펫을 테스트하십시오.

f=m=>{(m=m.split`
`).map((r,i)=>r[0]>' '?y=i:0);for(x=o=l=k=p=0;p!='X';++l,y+=(k==1)-(k<1),x+=(k>2)-(k==2))c=m[y][x],c!=p?(o+=', '+'NSWE'[k]+l,l=0):0,k='^v<>'.search(p=c);alert(o.slice(7))}

// Testable version, no output but return (same size)
f=m=>{(m=m.split`
`).map((r,i)=>r[0]>' '?y=i:0);for(x=o=l=k=p=0;p!='X';++l,y+=(k==1)-(k<1),x+=(k>2)-(k==2))c=m[y][x],c!=p?(o+=', '+'NSWE'[k]+l,l=0):0,k='^v<>'.search(p=c);return o.slice(7)}


// TEST
out = x => O.innerHTML += x+'\n';

test = 
[[`>>>>>>>>>>>>>>>v
               v
               v
               >>>>X`,'E15, S3, E4']
,[`>>>>>>v
^     v
^     >>>>X`,'N2, E6, S2, E4']
,[`X
^
^
^`,'N3']
,[`>>>>>>v
^     v
^     v
      v
      >>>>>>X`,'N2, E6, S4, E6']
,[` X
 ^
 ^
>^`,'E1, N3']
,[`>X`,'E1']
,[`v<<<<<
vX<<<^
>>>>^^
>>>>>^`,'E5, N3, W5, S2, E4, N1, W3']];

test.forEach(t=>{
  var k = t[1];
  var r = f(t[0]);
  out('Test ' + (k==r ? 'OK' : 'Fail')
      +'\n'+t[0]+'\nResult: '+r
      +'\nCheck:  '+k+'\n');
})
<pre id=O></pre>

덜 골프

f=m=>{
  m=m.split('\n'); // split in rows

  x = 0; // Starting column is 0
  m.forEach( (r,i) => r[0]>' '? y=i : 0); // find starting row

  o = 0; // output string
  p = 0; // preceding character
  l = 0; //  sequence length (this starting value is useless as will be cutted at last step)
  k = 0; //  direction (this starting value is useless as will be cutted at last step)
  while(p != 'X') // loop until X found
  {
    c = m[y][x]; // current character in c
    if (c != p) // changing direction
    {  
      o +=', '+'NSWE'[k]+l; // add current direction and length to output
      l = 0 // reset length
    );
    p = c;
    k = '^v<>'.search(c); // get new current direction
    // (the special character ^ is purposedly in first position)
    ++l; // increase sequence length
    y += (k==1)-(k<1); // change y depending on direction
    x += (k>2)-(k==2); // change x depending on direction
  }
  alert(o.slice(7)); // output o, cutting the useless first part
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.