Avast, các bạn scallywags!


10

Blackbeard là một cướp biển tiếng Anh của những năm đầu 18 thứ thế kỷ. Mặc dù anh ta nổi tiếng với việc cướp bóc và lấy tàu, anh ta đã chỉ huy các tàu của mình với sự cho phép của thủy thủ đoàn. Không có tài khoản nào về việc anh ta làm hại hay giết người bị bắt.

Thử thách này là để vinh danh Blackbeard khét tiếng và được truyền cảm hứng từ International Talk Like a Pirate Day (19 tháng 9). Nó cũng là nghịch đảo của thách thức này của Pyrrha .


Các thách thức

Tạo một chương trình lấy bản đồ kho báu làm đầu vào (bao gồm các ký tự được liệt kê bên dưới) và xuất ra các hướng của nó.


Đầu vào

Tất cả các nguyên liệu đầu vào sẽ bao gồm v, >, <, ^, khoảng trắng, và một đĩa đơn X.

Bạn có thể giả sử như sau:

  • bản đồ sẽ không bao giờ lặp lại hoặc vượt qua chính nó

  • mũi tên bắt đầu sẽ luôn là ký tự cuối cùng trong cột ngoài cùng bên trái

  • sẽ luôn có một kho báu ( X)

Một đầu vào mẫu được hiển thị dưới đây.

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

Đầu ra

Đầu ra phải là một ", "chuỗi các hướng được phân định. Dưới đây là đầu ra chính xác từ bản đồ trên.

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

Một dòng mới duy nhất hoặc không gian được cho phép.


Ví dụ

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

Nói chuyện quốc tế vui vẻ như một ngày cướp biển!


Bạn có thể muốn bao gồm một ví dụ trong đó có nhiều hơn một mũi tên trỏ phải trong cột ngoài cùng bên trái, tức là nơi đường dẫn lặp lại vào cột đầu tiên. Trong trường hợp đó, hơi khó để xác định điểm bắt đầu của đường dẫn.
Reto Koradi

Tôi đã thêm một ví dụ theo yêu cầu của bạn. Tôi cũng đã thêm chi tiết rằng ký tự bắt đầu sẽ là điểm cuối cùng của cột. @RetoKoradi
Zach Gates

Vì tôi đã nêu ra một số lo ngại trong câu hỏi liên quan về độ dài của phân đoạn cuối cùng, tôi sẽ nhắc lại một lần nữa và nói rằng đây không chính xác là câu hỏi ngược ở đây. Ai đó đang cố lừa những tên cướp biển một lần nữa, tôi nghĩ vậy.
coredump

Sự khác biệt duy nhất là số bước của hướng cuối cùng. @coredump Ít nhất, theo như tôi có thể nói.
Zach Gates

1
@ZachGates Vâng, chính xác (và chỉ cần rõ ràng, tôi không nói rằng câu hỏi nên được sửa đổi, nó là tốt như hiện tại).
coredump

Câu trả lời:


3

CJam, 78 byte

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

Hãy thử trực tuyến .

Giải trình

Ý tưởng chính ở đây là tìm dòng dài nhất (chúng ta sẽ gọi độ dài này T), sau đó đệm tất cả các dòng có cùng độ dài và nối chúng (chuỗi mới này là U). Cách này chỉ cần một bộ đếm duy nhất để di chuyển trong bản đồ. Thêm / trừ 1có nghĩa là di chuyển sang phải / trái trong cùng một dòng, thêm / bớt Tcó nghĩa là di chuyển xuống / lên một dòng.

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

Bây giờ là lúc để thiết lập vòng lặp.

,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

Phần thân vòng lặp sử dụng bảng tra cứu và eval để chọn phải làm gì. Ở đầu mỗi lần lặp, phần tử ngăn xếp trên cùng là vị trí hiện tại. Bên dưới nó có tất cả các hướng xử lý của NSWE. Vào cuối vòng lặp, hướng mới được đặt bên dưới vị trí và một bản sao của nó được sử dụng làm điều kiện cho vòng lặp. Nhân vật khác không là sự thật. Khi gặp X, 0 được đẩy làm hướng, chấm dứt vòng lặp.

_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

Bây giờ ngăn xếp trông như thế này : [directions 0 position]. Hãy tạo đầu ra.

;;    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 byte

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

Dùng thử trực tuyến

Giải trình:

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

Javascript (ES6), 239 byte

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`, `"))

Giải trình:

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

JavaScript (ES6), 189

Kiểm tra chạy đoạn mã dưới đây trong trình duyệt tuân thủ 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>

Ít chơi gôn

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
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.