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.