Khử chuỗi


58

Một chuỗi thông thường trông như thế này:

Hello,IAmAStringSnake!

Và một con rắn dây trông giống như thế này:

Hel         
  l      rin
  o,IAmASt g
           S
       !ekan

Nhiệm vụ của bạn

Rắn chuỗi là nguy hiểm, vì vậy bạn phải tạo một chương trình lấy một chuỗi rắn làm đầu vào và xuất nó thành một chuỗi thông thường.

Thông số kỹ thuật

  • Đầu vào có thể là một chuỗi nhiều dòng hoặc một chuỗi các chuỗi.
  • Mỗi dòng của đầu vào sẽ được đệm bằng khoảng trắng để tạo thành một lưới hình chữ nhật.
  • Các nhân vật trong con rắn chỉ có thể kết nối với các nhân vật liền kề bên trên, bên dưới, bên trái hoặc bên phải của họ (giống như trong trò chơi Rắn). Họ không thể đi chéo.
  • Các nhân vật rắn sẽ không bao giờ liền kề với một phần khác của con rắn, chỉ có các nhân vật được kết nối.
  • Ký tự đầu tiên của chuỗi là ký tự kết thúc có khoảng cách Manhattan ngắn nhất từ góc trên bên trái của lưới đầu vào (nghĩa là số lần di chuyển tối thiểu mà con rắn sẽ đi trực tiếp từ ký tự cuối sang bên trái trên cùng góc). Cả hai đầu sẽ không bao giờ có cùng khoảng cách.
  • Chuỗi có thể chứa bất kỳ ký tự ASCII nào giữa các điểm mã 33 và 126 (không có khoảng trắng hoặc dòng mới).
  • Chuỗi sẽ dài từ 2 đến 100 ký tự.
  • Mã ngắn nhất trong byte thắng.

Các trường hợp thử nghiệm

(Lưới đầu vào, theo sau là chuỗi đầu ra)

Hel         
  l      rin
  o,IAmASt g
           S
       !ekan

Hello,IAmAStringSnake!

----------

Python

Python

----------

P  ngPu  Code 
r  i  z  d  G 
o  m  z  n  o 
gram  lesA  lf

ProgrammingPuzzlesAndCodeGolf

----------

   ~ zyx tsr XWVUTSR
   }|{ wvu q Y     Q
!          p Z `ab P
"#$ 6789:; o [ _ c O
  % 5    < n \]^ d N
('& 432  = m     e M
)     1  > lkjihgf L
*+,-./0  ?         K
         @ABCDEFGHIJ

!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~

----------

  tSyrep    
  r    p    
  in Sli    
   g    Sile
   Snakes  n
Ser      ylt
a eh   ilS  
fe w   t    
   emo h    
     Sre    

SlipperyStringSnakesSilentlySlitherSomewhereSafe

20
Sự thật thú vị: Theo bài viết trên Wikipedia được liên kết, khoảng cách Manhattan còn được gọi là khoảng cách rắn!
dùng81655

Liệu một đầu vào như hastebin.com/asugoropin.vbs có chính xác không?
FliiFe

@FliiFe Không, các bộ phận của con rắn không thể ở cạnh nhau vì không phải lúc nào con rắn cũng sẽ đi đâu khi điều này xảy ra (và nó sẽ khiến thử thách khó khăn hơn rất nhiều). Tôi đã thêm một dòng vào spec để giải thích điều này.
dùng81655

Đầu vào có thể là một mảng hai chiều (tức là mỗi ký tự là một phần tử) không?
FliiFe

29
Chắc chắn câu đố này cần một câu trả lời trong trăn?
abligh

Câu trả lời:


11

APL, 55 byte

{⍵[1↓(⊂0 0){1<⍴⍵:⍺,∆[⊃⍋+/¨|⍺-∆]∇∆←⍵~⍺⋄⍺}(,⍵≠' ')/,⍳⍴⍵]}

Hàm này lấy một ma trận ký tự có chuỗi con rắn trong đó.

Thí dụ:

      s1 s2 s3
┌────────────┬──────────────┬────────────────────┐
│Hel         │P  ngPu  Code │   ~ zyx tsr XWVUTSR│
│  l      rin│r  i  z  d  G │   }|{ wvu q Y     Q│
│  o,IAmAst g│o  m  z  n  o │!          p Z `ab P│
│           S│gram  lesA  lf│"#$ 6789;: o [ _ c O│
│       !ekan│              │  % 5    < n \]^ d N│
│            │              │('& 432  = m     e M│
│            │              │)     1  > lkjighf L│
│            │              │*+,-./0  ?         K│
│            │              │         @ABCDEFGHIJ│
└────────────┴──────────────┴────────────────────┘
      ↑ {⍵[1↓(⊂0 0){1<⍴⍵:⍺,∆[⊃⍋+/¨|⍺-∆]∇∆←⍵~⍺⋄⍺}(,⍵≠' ')/,⍳⍴⍵]} ¨ s1 s2 s3 
Hello,IAmAstringSnake!                                                                        
ProgrammingPuzzlesAndCodeGolf                                                                 
!"#$%&'()*+,-./0123456789;:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefhgijklmnopqrstuvwxyz{|}~

Giải trình:

  • (,⍵≠' ')/,⍳⍴⍵: lấy tọa độ của tất cả các khoảng trắng
  • (⊂0 0): bắt đầu từ (0,0) (là tọa độ không hợp lệ)
  • {... }: theo con rắn, vị trí nhất định và con rắn:
    • 1<⍴⍵:: nếu có nhiều hơn 1 phần tử còn lại:
      • ∆←⍵~⍺: loại bỏ vị trí hiện tại khỏi con rắn và lưu trữ nó trong .
      • +/¨|⍺-∆: tìm khoảng cách giữa vị trí hiện tại và từng điểm trong phần còn lại của con rắn
      • ∆[⊃⍋...] `: lấy điểm gần nhất trên con rắn
      • : chạy lại hàm, với điểm gần nhất là điểm hiện tại mới và con rắn rút ngắn là con rắn mới.
      • ⍺,: thêm vị trí hiện tại vào kết quả của điều đó
    • ⋄⍺: nếu không, chỉ cần trả lại vị trí hiện tại
  • 1↓: thả mục đầu tiên từ kết quả (là vị trí (0,0))
  • ⍵[... ]: lấy các phần tử đó từ ⍵, theo thứ tự đó

24

JavaScript (ES6) + SnakeEx , 176 byte

a=b=>snakeEx.run("s{A}:<+>([^ ]<P>)+",b).reduce((c,d)=>(e=c.marks.length-d.marks.length)>0?c:e?d:c.x+c.y>d.x+d.y?d:c).marks.reduce((c,d,e,f)=>e%2?c+b.split`\n`[d][f[e-1]]:c,"")

Ghi nhớ SnakeEx? Tốt, vì tôi cũng không! Gợi ý chơi golf chào mừng.


19

MATL , 80 byte

Cảm ơn @LevelRiverSt đã sửa

32>2#fJ*+X:4Mt1Y6Z+l=*2#fJ*+ttXjwYj+K#X<)wt!"tbb6#Yk2#)yw]xxvtXjwYjqGZy1)*+Gw)1e

Đầu vào là một mảng 2D của char, với các hàng được phân tách bằng ;. Các trường hợp thử nghiệm trong định dạng này là

['Hel         ';'  l      rin';'  o,IAmASt g';'           S';'       !ekan']
['Python']
['P  ngPu  Code ';'r  i  z  d  G ';'o  m  z  n  o ';'gram  lesA  lf']
['   ~ zyx tsr XWVUTSR';'   }|{ wvu q Y     Q';'!          p Z `ab P';'"#$ 6789:; o [ _ c O';'  % 5    < n \]^ d N';'(''& 432  = m     e M';')     1  > lkjihgf L';'*+,-./0  ?         K';'         @ABCDEFGHIJ']
['  tSyrep    ';'  r    p    ';'  in Sli    ';'   g    Sile';'   Snakes  n';'Ser      ylt';'a eh   ilS  ';'fe w   t    ';'   emo h    ';'     Sre    ']

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

Giải trình

Các tọa độ của mỗi ký tự không gian được biểu diễn bằng một số phức. Đối với mỗi ký tự hiện tại, ký tự tiếp theo được lấy là giá trị gần nhất (chênh lệch tuyệt đối tối thiểu của tọa độ phức tạp của chúng).

Để xác định char ban đầu, hai điểm cuối cần được tìm thấy. Điều này được thực hiện như sau. Một điểm cuối là một char không gian có chính xác một hàng xóm không gian. Số lượng lân cận thu được bằng tích chập 2D với mặt nạ phù hợp. Điểm ban đầu là điểm cuối có tọa độ phức tạp có tổng phần thực và phần ảo ít nhất; tức là gần nhất trong khoảng cách Manhattan với số phức 0, hoặc tương đương với 1 + 1j, là tọa độ phức tạp của góc trên bên trái.

32>      % Take input as 2D char array. Compute 2D array with true for nonspace,
         % false for space
2#f      % Arrays of row and column indices of nonspaces
J*+      % Convert to complex array. Real part is row, imaginary part is column
X:       % Convert to column array
4Mt      % Push arrays of zeros and ones again. Duplicate
1Y6      % Push array [0 1 0; 1 0 1; 0 1 0]. Used as convolution mask to detect
         % neighbours that are nonspace
Z+       % 2D convolution with same size as the input
1=       % True for chars that have only one neighbour (endpoints)
*        % Multiply (logical and): we want nonspaces that are endpoints
2#fJ*+   % Find complex coordinates (as before)
ttXjwYj  % Duplicate. Take real and imaginary parts
+        % Add: gives Manhattan distance to (0,0)
K#X<     % Arg min. Entry with minimum absolute value has least Manhattan
         % distance to (0,0), and thus to (1,1) (top left corner)
)        % Apply as an index, to yield complex coordinate of initial endpoint
wt!      % Swap, duplicate, transpose.
         % The stack contains, bottom to top: complex coordinates of initial
         % endpoint, column array with all complex coordinates, row array of all
         % coordinates. The latter is used (and consumed) by the next "for"
         % statement to generate that many iterations
"        % For loop. Number of iterations is number of nonspaces
  tbb    %   Duplicate, bubble up twice (rearrange is stack)
  6#Yk   %   Find which of the remaining points is closest to current point. This
         %   is the next char in the string
  2#)    %   Remove the point with that index from the array of complex
         %   coordinates. Push that point and the rest of the array
  yw     %   Duplicate extracted point, swap
]        % End for
xx       % Delete top two elements of the stack
v        % Concatenate all stack contents into a column array. This array
         % contains the complex coordinates of chars sorted to form the string
tXjwYj   % Extract real part and imaginary part
GZy1)    % Number of rows of input. Needed to convert to linear index
*+       % Convert rows and columns to linear index
Gw       % Push input below that
)        % Index to get the original chars with the computed order
1e       % Force the result to be a row array (string). Implicitly display

Tôi sẽ giả sử một lời giải thích sắp tới?
Matt

@Matt Chắc chắn ... vào cuối ngày :-)
Luis Mendo

Giải thích được thêm @Matt
Luis Mendo

The initial point is the endpoint whose complex coordinate has the least absolute valueCẩn thận: Khoảng cách Euclide! = Khoảng cách Manhattan. ví dụ, điểm 7 + 7j có khoảng cách Euclide 9.8994 và khoảng cách Manhattan 14. 10j xa hơn bởi khoảng cách Euclide nhưng gần hơn đáng kể bởi khoảng cách Manhattan. Khác hơn thế, khái niệm tuyệt vời!
Cấp sông St

@LevelRiverSt Cảm ơn bạn! Đã sửa
Luis Mendo

14

C 198 190 179 180 181 byte

Chỉnh sửa: Đã sử dụng mẹo của user81655 và xóa dấu ngoặc đơn trong toán tử ternary, cảm ơn! Tôi cũng đã thay đổi bài kiểm tra rườm rà (S & 1) về độ đồng đều để phù hợp hơn (và ngắn hơn!) S% 2.

Edit2: Sử dụng rất nhiều kiểu * địa chỉ, khiến tôi mù quáng trước những tối ưu hóa rõ ràng trong định nghĩa của S, tức là thay thế * (a + m) bằng [m], v.v. Sau đó, tôi đã thay thế S bằng T, về cơ bản là một nửa những gì S làm. Mã bây giờ cũng tận dụng giá trị trả về của putar.

Chỉnh sửa 3: Đã sửa lỗi xuất hiện từ đầu, tiêu chí dừng tìm kiếm Manhattan a <b + m chỉ đúng nếu lỗi đã bị giảm. Điều này thêm 2 byte, nhưng một được lấy lại bằng cách định nghĩa m toàn cầu.

Edit4: Chơi golf của tôi đã vượt qua mức tối thiểu và hiện đang đi sai hướng. Một sửa lỗi khác liên quan đến tìm kiếm Manhattan. Ban đầu tôi đã có các kiểm tra ràng buộc tại chỗ và không có các kiểm tra đó tiếp tục cho các mảng đầu vào lớn (ở đâu đó quanh 50x50) ngoài mảng b. Do đó mảng đó phải được mở rộng đến ít nhất gấp đôi kích thước trước đó, thêm một byte nữa.

#define T(x)+x*((a[x]>32)-(a[-x]>32))
m=103;main(){char b[m<<8],*e=b,*a=e+m;while(gets(e+=m));for(e=a;(T(1)T(m))%2**a<33;a=a<b+m?e+=m:a)a-=m-1;for(;*a;a+=T(1)T(m))*a-=putchar(*a);}

Ungolfed và giải thích:

/* T(1)T(m) (formerly S) is used in two ways (we implicitly assume that each cell has
   one or two neighbors to begin with):
   1. (in the first for-loop) T(1)T(m) returns an odd (even) number if cell a has one (two)
      neighbors with ASCII value > 32. For this to work m must be odd.
   2. (in the second for-loop) at this stage each cell a in the array at which T(1)T(m) is
      evaluated has at most one neighboring cell with ASCII value > 32. T(1)T(m) returns the
      offset in memory to reach this cell from a or 0 if there is no such cell.
      Putting the + in front of x here saves one byte (one + here replaces two
      + in the main part)

#define T(x)+x*((a[x]>32)-(a[-x]>32))

  /* A snake of length 100 together with the newlines (replaced by 0:s in memory) fits
     an array of size 100x101, but to avoid having to perform out-of-bounds checks we
     want to have an empty line above and the array width amount of empty lines below
     the input array. Hence an array of size 202x101 would suffice. However, we save
     a (few) bytes if we express the array size as m<<8, and since m must be odd
     (see 1. above), we put m = 103. Here b and e point to the beginning of the (now)
     256x103 array and a points to the beginning of the input array therein */

m=103;
main()
{

  char b[m<<8],*e=b,*a=e+m;

  /* This reads the input array into the 256x103 array */

  while(gets(e+=m));

  /* Here we traverse the cells in the input array one
     constant-Manhattan-distance-from-top-left diagonal at a time starting at the top-left
     singleton. Each diagonal is traversed from bottom-left to top-right since the starting point
     (memory location e) is easily obtained by moving one line downwards for each diagonal
     (+m) and the stopping point is found by comparing the present location a to the input array
     starting position (b+m). The traversal is continued as long as the cell has either
     an ASCII value < 33 or it has two neighbors with ASCII value > 32 each (T(1)T(m)
     is even so that (T(1)T(m))%2=0).
     Note that the pointer e will for wide input arrays stray way outside (below) the
     input array itself, so that for a 100 cell wide (the maximum width) input array
     with only two occupied cells in the bottom-right corner, the starting cell
     will be discovered 98 lines below the bottom line of the input array.
     Note also that in these cases the traversal of the diagonals will pass through the
     right-hand side of the 103-wide array and enter on the left-hand side. This, however,
     is not a problem since the cells that the traversal then passes have a lower
     Manhattan distance and have thereby already been analyzed and found not to contain
     the starting cell. */

  for(e=a;(T(1)T(m))%2**a<33;a=a<b+m?e+=m:a)a-=m-1;

  /* We traverse the snake and output each character as we find them, beginning at the
     previously found starting point. Here we utilize the function T(1)T(m), which
     gives the offset to the next cell in the snake (or 0 if none), provided that
     the current cell has at most one neighbor. This is automatically true for the
     first cell in the snake, and to ensure it for the rest of the cells we put the
     ASCII value of the current cell to 0 (*a-=putchar(*a)), where we use the fact
     that putchar returns its argument. The value 0 is convenient, since it makes the
     stopping condition (offset = 0, we stay in place) easy to test for (*a == 0). */

  for(;*a;a+=T(1)T(m))
    *a-=putchar(*a);
}

1
Câu trả lời này là tuyệt vời.
abligh

+1 Điều này thật tuyệt. Tôi muốn thêm một lời giải thích cho câu trả lời của tôi cho thấy nơi tôi đã thắt lưng byte so với giải pháp của bạn, điều đó có ổn không?
mIllIbyte

mIllIbyte - hãy thoải mái thêm ý kiến, đó là con đường hướng tới những ý tưởng mới.
Zunga

user81655 - cảm ơn vì tiền boa, nó đã loại bỏ 6 byte. Trên thực tế, tôi đã thử rằng ngày hôm qua cũng như sử dụng S% 2 thay vì (S & 1), đã loại bỏ 2 byte khác, để kiểm tra tính đồng đều, nhưng vì một số lý do (mã của tôi bị lỗi ở một nơi khác) sau đó không hoạt động thích hợp. Bây giờ, tuy nhiên, tất cả có vẻ ổn.
Zunga

Rất đẹp. Tiết kiệm nhiều hơn với a[1], a[-m]vv, và làm cho mtoàn cầu - m=103;main().
ugoren

9

C, 272 byte

#define E j+(p/2*i+1)*(p%2*2-1)
#define X(Y) a[Y]&&a[Y]-32
char A[999],*a=A+99;j,p,t;i;main(c){for(;gets(++j+a);j+=i)i=strlen(a+j);for(c=j;j--;){for(t=p=4;p--;)t-=X(E);t==3&&X(j)?c=c%i+c/i<j%i+j/i?c:j:0;}for(j=c;c;){putchar(a[j]),a[j]=0;for(c=0,p=4;!c*p--;)X(E)?c=j=E:0;}}

Nhìn vào nguồn của @ Zunga. Bây giờ hãy nhìn vào tôi. Bạn muốn biết làm thế nào tôi có thêm 91 byte?
Ung dung:

#define E j+(p/2*i+1)*(p%2*2-1)
#define X(Y) a[Y]&&a[Y]-32  //can be more concise, see @Zunga's
  //and then doesn't need the define
char A[999],*a=A+99;j,p,t;i;
main(c){for(;gets(++j+a);j+=i)
i=strlen(a+j); //we don't need to know the length of a line
  //in @Zunga's solution, lines are spaced a constant distance apart
for(c=j;j--;){
for(t=p=4;p--;)t-=X(E);  //a ton of bytes can be saved with determining 
  //the neighbors, see @Zunga's source
t==3&&X(j)?
c=c%i+c/i<j%i+j/i?c:j:0;}  //we search for ends of the snake, 
  //and compute the Manhattan distance
for(j=c;c;){putchar(a[j]),a[j]=0;
for(c=0,p=4;!c*p--;)  //determining the neighbors again
X(E)?c=j=E:0;}}

5

Python (2 và 3), 640 624 604 583 575 561 546 538 byte

Tôi vẫn là một golf thủ n00b nên cái này hơi lớn.

Chỉnh sửa: Cảm ơn @porglezomp về các đề xuất! Tôi đã không xóa tất cả các toán tử 'và' vì điều đó sẽ phá vỡ Python 3.

Edit2: Cảm ơn @Aleksi Torhamo về nhận xét về isspace (). Việc giảm kết quả bù đắp cho lỗi tôi đặt vào. Cũng nhờ ẩn danh cho cú pháp tô sáng!

Edit3: Cảm ơn @ mbomb007 cho một vài byte bổ sung.

import sys;s=sys.stdin.read().split('\n');m={};q=[];o=len;j=o(s);r=range;g='!'
for y in r(j):
 v=s[y];f=o(v);d=y+1
 for x in r(f):
  n=[];a=n.append;U=s[y-1]
  if v[x]>=g:j>=y>0==(U[x]<g)<=x<o(U)and a((x,y-1));j>y>=0==(v[x-1]<g)<x<=f and a((x-1,y));j>y>-1<x+1<f>(v[x+1]<g)<1and a((x+1,y));j>d>-1<x<o(s[d])>(s[d][x]<g)<1and a((x,d));m[x,y]=[v[x],n];o(n)-1or q.append((x,y))
t=min(q,key=sum);w=sys.stdout.write;w(m[t][0]);c=m[t][1][0]
while o(m[c][1])>1:
 b=m[c][1];w(m[c][0])
 for k in r(o(b)):
  if b[k]!=t:t=c;c=b[k];break
print(m[c][0])

Và đây là phiên bản trước khi chơi golf của tôi

import sys

lines = sys.stdin.read().split('\n')
startend = []
mydict = {}
for y in range( 0, len(lines)):
  for x in range( 0, len(lines[y])):
    if not lines[y][x].isspace():
      neighbors = []
      if x>=0 and x<len(lines[y-1]) and y-1>=0 and y-1<len(lines):
        if not lines[y-1][x].isspace():
          neighbors.append( (x,y-1) )
      if x-1>=0 and x-1<len(lines[y]) and y>=0 and y<len(lines):
        if not lines[y][x-1].isspace():
          neighbors.append( (x-1,y) )
      if x+1>=0 and x+1<len(lines[y]) and y>=0 and y<len(lines):
        if not lines[y][x+1].isspace():
          neighbors.append( (x+1,y) )
      if x>=0 and x<len(lines[y+1]) and y+1>=0 and y+1<len(lines):
        if not lines[y+1][x].isspace():
          neighbors.append( (x,y+1) )
      mydict[(x,y)] = [ lines[y][x], neighbors ]

      if len( neighbors ) == 1:
        startend.append( (x,y) )

startend.sort( key=lambda x : x[0]*x[0] + x[1]*x[1] )

last = startend[0]
sys.stdout.write( mydict[ last ][0] )
current = mydict[last][1][0]
while len( mydict[current][1] ) > 1:
  sys.stdout.write( mydict[current][0] )
  for k in range( 0, len( mydict[current][1] ) ):
    if mydict[current][1][k] != last:
      last = current
      current = mydict[current][1][k]
      break

print(mydict[current][0])

1
Tôi đã lưu 12 byte bằng cách giới thiệu S=lambda s:s.isspace()và sau đó thực hiện S(s)thay vì s.isspace().
porglezomp

1
Tôi nghĩ rằng bạn cũng có thể thay đổi tất cả and thành <, vì f() < g() < h()giống như g = g(); f() < g and g < h()về mặt tác dụng phụ (ngắn mạch chuỗi so sánh) và dù sao bạn cũng bỏ qua kết quả so sánh.
porglezomp

1
m[(x,y)]=cũng giống như ngắn hơnm[x,y]=
porglezomp

2
@porglezomp: thậm chí còn ngắn hơn để nóiS=str.isspace
Aleksi Torhamo

1
Loại bỏ Svà thay vào đó sử dụng <'!'trong mọi lần xuất hiện có thể có cùng độ dài, có thể mở ra một cơ hội để tiết kiệm nhiều hơn. Thay đổi if 1-S(v[x]):thành if(v[x]<'!')<1:, ví dụ. Và có lẽ bạn có thể loại bỏ một số dấu ngoặc đơn trong các so sánh sau bằng cách thực hiện theo cách đó.
mbomb007

4

JavaScript (ES6), 195

Xem giải thích bên trong đoạn kiểm tra

s=>[...s].map((c,i)=>{if(c>' '&([n=-1,1,o=-~s.search('\n'),-o].map(d=>n+=s[i+d]>' '&&!!(e=d)),n<1)&m>(w=i/o+i%o|0))for(m=w,r=c,p=i+e;r+=s[i=p],[e,o/e,-o/e].some(d=>s[p=i+(e=d)]>' '););},m=1/0)&&r

Kiểm tra

f=s=>[...s].map((c,i)=>{if(c>' '&([n=-1,1,o=-~s.search('\n'),-o].map(d=>n+=s[i+d]>' '&&!!(e=d)),n<1)&m>(w=i/o+i%o|0))for(m=w,r=c,p=i+e;r+=s[i=p],[e,o/e,-o/e].some(d=>s[p=i+(e=d)]>' '););},m=1/0)&&r

// Less golfed

u=s=>(
  o = -~s.search('\n'), // offset between lines
  m = 1/0, // current min manhattan distance, init at infinity
  // scan input looking for the 2 ends of the string
  [...s].map((c,i)=>{ // for each char c at position i
     if(c > ' ' // check if part of the string
        & ( [-1,1,o,-o] // scan in 4 directions and count neighbors
             .map(d=> n+=s[i+d]>' '&&!!(e=d), n=0), // remember direction in e
          n < 2) // if at end of string will have exactly 1 neighbor
        & (w = i/o + i%o |0) < m) // manhattan distance in w, must be less than current min
       // found one of the ends, follow the path and build the string in r
       for(m = w, r = c, p = i+e; 
           r += s[i=p], 
           [e,o/e,-o/e] // check 3 directions, avoiding to go back
           .some(d=>s[p=i+(e=d)]>' '); // save candidate position and direction in p and e
          ); // empty for body, all the work is inside the condition
  }),
  r
)  

console.log=x=>O.textContent+=x+'\n'

;[`Hel         
  l      rin
  o,IAmASt g
           S
       !ekan`,
 `   ~ zyx tsr XWVUTSR
   }|{ wvu q Y     Q
!          p Z \`ab P
"#$ 6789:; o [ _ c O
  % 5    < n \\]^ d N
('& 432  = m     e M
)     1  > lkjihgf L
*+,-./0  ?         K
         @ABCDEFGHIJ`].forEach(t=>{
  console.log(t+'\n\n'+f(t)+'\n')
  })
<pre id=O></pre>


Là dấu chấm phẩy ););}cần thiết?
Cees Timmerman

1
@CeesTimmerman có. Đầu tiên là bên trong fortiêu đề, nơi cần có 2 dấu hai chấm. Thứ hai là đồng hồ đo cho forcơ thể
edc65

3

Lua, 562 535 529 513 507 504 466 458 byte

Cho đến nay, môn golf khổng lồ nhất của tôi vào lúc này, tôi nghĩ rằng tôi vẫn có thể cắt được 100 byte, điều mà tôi sẽ làm, nhưng đăng nó như một câu trả lời vì nó đã mất một thời gian :). Tôi đã đúng, tôi đã cắt giảm hơn 100 byte! Tôi không nghĩ có nhiều chỗ để cải thiện.

hàm này phải được gọi với một mảng 2D chứa một ký tự cho mỗi ô.

Đã lưu 40 byte khi làm việc với @KennyLau , nhờ anh ấy!

Woohoo! Dưới 500!

function f(m)t=2u=1i=1j=1s=" "::a::if s~=m[i][j]and(i<#m and m[i+1][j]~=s)~=(j<#m[i]and m[i][j+1]~=s)~=(i>1 and m[i-1][j]~=s)~=(j>1 and m[i][j-1]~=s)then goto b end
i,t=i%t+1,#m>t and t==i and t+1or t j=j>1 and j-1or u u=u<#m[1]and j==1 and u+1or u goto a::b::io.write(m[i][j])m[i][j]=s
i,j=i<#m and s~=m[i+1][j]and i+1or i>1 and s~=m[i-1][j]and i-1or i,j<#m[i]and s~=m[i][j+1]and j+1or j>1 and s~=m[i][j-1]and j-1or j
if s==m[i][j]then return end goto b end

Ung dung

Giải thích sẽ đến sau khi tôi chơi golf xong, hiện tại, tôi sẽ cho bạn mượn phiên bản có thể đọc được của mã nguồn này: D Đây là phần giải thích!

Chỉnh sửa: không cập nhật với sửa đổi mới nhất, vẫn chơi golf trước khi cập nhật. Giải thích tương tự

function f(m)                    -- declare the function f which takes a matrix of characters
  t=2                            -- initialise the treshold for i
                                 -- when looking for the first end of the snake
  u=1                            -- same thing for j
  i,j=1,1                        -- initialise i and j,our position in the matrix
  s=" "                          -- shorthand for a space
  ::a::                          -- label a, start of an infinite loop
    if m[i][j]~=s                -- check if the current character isn't a space
      and(i<#m                   -- and weither it is surrounded by exactly
          and m[i+1][j]~=s)      -- 3 spaces or not
      ~=(j<#m[i]
          and m[i][j+1]~=s)      -- (more explanations below)
      ~=(i>1 
          and m[i-1][j]~=s)
      ~=(j>1
          and m[i][j-1]~=s)
      then goto b end            -- if it is, go to the label b, we found the head
    i,t=                         -- at the same time
      i%t+1,                     -- increment i
      #m>t and t==i and t+1or t  -- if we checked all chars in the current range, t++
    j=j>1 and j-1or u            -- decrement j
    u=u>#m[1]and j==1 and u+1or u-- if we checked all chars in the current range, u++
  goto a                         -- loop back to label a

  ::b::                          -- label b, start of infinite loop
  io.write(m[i][j])                    -- output the current char
    m[i][j]=s                    -- and set it to a space
    i,j=i<#m                     -- change i and j to find the next character in the snake
          and m[i+1][j]~=s       -- this nested ternary is also explained below
            and i+1              -- as it takes a lot of lines in comment ^^'
          or i>1 
            and m[i-1][j]~=s
            and i-1
          or i,
       j<#m[i] 
         and m[i][j+1]~=s
           and j+1
         or j>1 
           and m[i][j-1]~=s 
           and j-1
         or j
    if m[i][j]==s                -- if the new char is a space
    then                         -- it means we finished
      return                  -- exit properly to avoid infinite
    end                          -- printing of spaces
  goto b                         -- else, loop back to label b
end

Vì vậy, đây là một số giải thích chi tiết về cách thức hoạt động của chương trình này.

Trước hết, hãy xem xét vòng lặp có nhãn a, nó cho phép chúng ta tìm điểm cuối gần nhất với góc trên cùng bên trái. Nó sẽ lặp lại mãi mãi nếu không có kết thúc, nhưng đó không phải là vấn đề: D.

Trên lưới 4 x 4, đây là khoảng cách con rắn (trái) và thứ tự chúng được nhìn (phải)

1  2  3  4    |     1  2  4  7
2  3  4  5    |     3  5  8 11
3  4  5  6    |     6  9 12 14
4  5  6  7    |    10 13 15 16

Đối với mỗi nhân vật này, để kết thúc, nó phải kiểm tra hai điều kiện: - Không phải là khoảng trắng - Được bao quanh bởi chính xác 3 khoảng trắng (hoặc chính xác là 1 khoảng trắng)

Những điều kiện này được kiểm tra đoạn mã sau

r=m[i][j]~=s
    and(i<#m and m[i+1][j]~=s)
    ==not(j<#m[i] and m[i][j+1]~=s)
    ==not(i-1>0 and m[i-1][j]~=s)
    ==not(j-1>0 and m[i][j-1]~=s)
    and m[i][j]
    or r
  -- special note: "==not" is used as an equivalent to xor
  -- as Lua doesn't know what is a xor...

Kiểm tra nếu char không phải là một khoảng trắng đạt được bằng biểu thức m[i][j]~=s.

Kiểm tra xem có bị bao quanh bởi 1 không gian không gian hay không bằng cách sử dụng các điều kiện trên cho xung quanh chúng ta, điều này có thể được viết là

m[i+1][j]~=" "  m[i][j+1]~=" "  m[i-1][j]~=" "  m[i][j-1]~=" "

Và cuối cùng, nếu tất cả những điều trên được đánh giá là đúng, thì chim nhạn sẽ trả lại những gì cuối cùng and-> m[i][j]. Khác, chúng ta hãy rbỏ chọn :)

Bây giờ chúng ta có đầu của con rắn, chúng ta hãy đi hết đầu kia! Lặp lại con rắn chủ yếu đạt được bởi các chim nhạn lồng nhau sau đây:

i,j=i<#m and m[i+1][j]~=s and i+1or i-1>0 and m[i-1][j]~=s and i-1or i,
    j<#m[i]and m[i][j+1]~=s and j+1or j-1>0 and m[i][j-1]~=s and j-1or j

Chúng tôi thiết lập lại ijđồng thời để tránh cần người giả lưu trữ các giá trị cũ Cả hai đều có cùng cấu trúc và sử dụng các điều kiện đơn giản, vì vậy tôi sẽ trình bày chúng ở dạng lồng nhau if, nó sẽ cho phép bạn đọc chúng dễ dàng hơn. :)

i=i<#m and m[i+1][j]~=s and i+1or i-1>0 and m[i-1][j]~=s and i-1or i

Có thể được dịch thành:

if(i<#m)
then
  if(m[i+1][j]~=" ")
  then
    i=i+1
  end
elseif(i-1>0)
then
  if(m[i-1][j]~=" ")
  then
    i=i-1
  end
end

Kiểm tra nó!

Đây là mã tôi sử dụng để chạy mã này, bạn có thể kiểm tra mã trực tuyến bằng cách sao chép mã.

function f(m)t=2u=1i=1j=1s=" "::a::if s~=m[i][j]and(i<#m and m[i+1][j]~=s)~=(j<#m[i]and m[i][j+1]~=s)~=(i>1 and m[i-1][j]~=s)~=(j>1 and m[i][j-1]~=s)then goto b end
i,t=i%t+1,#m>t and t==i and t+1or t j=j>1 and j-1or u u=u<#m[1]and j==1 and u+1or u goto a::b::io.write(m[i][j])m[i][j]=s
i,j=i<#m and s~=m[i+1][j]and i+1or i>1 and s~=m[i-1][j]and i-1or i,j<#m[i]and s~=m[i][j+1]and j+1or j>1 and s~=m[i][j-1]and j-1or j
if s==m[i][j]then return end goto b end


test1={}
s1={
"  tSyrep    ",
"  r    p    ",
"  in Sli    ",
"   g    Sile",
"   Snakes  n",
"Ser      ylt",
"a eh   ilS  ",
"fe w   t    ",
"   emo h    ",
"     Sre    ",
     }
for i=1,#s1
do
  test1[i]={}
  s1[i]:gsub(".",function(c)test1[i][#test1[i]+1]=c end)
end
f(test1)

1
Một điểm mềm cho các câu trả lời dài hơn mà bây giờ ít lựa chọn vì lựa chọn ngôn ngữ.
Matt

@Matt cảm ơn rất nhiều vì đã hỗ trợ! Thật ra, tôi vẫn đang tìm cách để đánh golf xuống, nhưng nó càng ngày càng khó hơn!
Katenkyo

2

Lua, 267 byte

Lua 5.3 là bắt buộc.

e=" "w=#arg[1]+1i=1/0q=0s=table.concat(arg,e)s=e:rep(#s)..s
m,n=i,{}for p in s:gmatch"()%g"do u=-1
for _,d in ipairs{-1,1,-w,w}do u=u+(s:find("^%S",d+p)or 0)end
n[p]=u+1m=math.min(m,p*i^(u//#s)+(p%w*w+p)*#s)end
p=m%#s repeat q,p=p,n[p]-q io.write(s:sub(q,q))until p<1

Sử dụng:

$ lua desnakify.lua \
>    "  tSyrep    " \
>    "  r    p    " \
>    "  in Sli    " \
>    "   g    Sile" \
>    "   Snakes  n" \
>    "Ser      ylt" \
>    "a eh   ilS  " \
>    "fe w   t    " \
>    "   emo h    " \
>    "     Sre    "
SlipperyStringSnakesSilentlySlitherSomewhereSafe

2

Con trăn 3 245 243 241 236 byte

slà chuỗi đầu vào, nlà đầu ra được in ra thiết bị xuất chuẩn:

f=s.find
w,l=f('\n')+1,len(s)
t=1,w,-1,-w
y=z=f(s.strip()[0]);n=s[y];v={y}
for i in range(l*l):
 i%=l;c=s[i]
 if c>' 'and i not in v:
  if i-y in t:y=i;n=c+n;v|={i}
  elif i-z in t:z=i;n+=c;v|={i}
if y%w+y//w>z%w+z//w:n=n[::-1]
print(n)

Chỉnh sửa: Cảm ơn @Cees Timmerman đã lưu 5 byte!


c>' 'andprint ntrong Python 2.
Cees Timmerman

Bạn không thể làm ifthay vì elif?
clismique

@ Qwerp-Derp không may, tôi đã thử nó trước đây, nhưng nó in, ví dụ "! EkanSgnirtSAmAI, olleHello, IAmAStringSnake!" và "SlipperyStSyreppilS".
pgks

Định dạng đầu vào là gì?
clismique

@ Qwerp - Biến Derp slà một chuỗi nhiều dòng; ký tự cuối cùng của chuỗi phải là một dòng mới (điều này là cần thiết để vượt qua Pythontrường hợp thử nghiệm)
pgks

1

Con trăn, 537

Giải pháp ban đầu của tôi:

from itertools import chain, product, ifilter
from operator import add
moves = ((1,0),(0,1),(-1,0),(0,-1))
h = dict(ifilter(lambda (p,v):not v.isspace(),chain(*map(lambda (i,r):map(lambda (j,c):((i,j),c),enumerate(r)),enumerate(s)))))
n = defaultdict(list)
for m,p in product(moves, h):
    np = tuple(map(add,m,p))
    if np in h:
        n[p].append(np)
def pr(nx):
    return(lambda l:(h[l[0]], h.pop(l[0]))[0] + pr(l[0]) if l else '')([x for x in n[nx] if x in h])
(lambda y: h[y]+ pr(y))(next(x for x in n if len(n[x])==1))

Nén một chút, nhưng để lại như một phương pháp:

from itertools import chain, product
from operator import add
def unsnake(s):
    (h,n) = (dict(filter(lambda (p,v):not v.isspace(),chain(*map(lambda (i,r):map(lambda (j,c):((i,j),c),enumerate(r)),enumerate(s))))),defaultdict(list))
    for m,p in product(((1,0),(0,1),(-1,0),(0,-1)), h):(lambda np: n[p].append(np) if np in h else 0)(tuple(map(add,m,p)))
    def pr(nx):return(lambda l:(h[l[0]], h.pop(l[0]))[0] + pr(l[0]) if l else '')([x for x in n[nx] if x in h])
    return(lambda y: h[y]+ pr(y))(next(x for x in n if len(n[x])==1))

1

Java 7, 927 924 923 byte

import java.util.*;int l,k;char[][]z;Set p=new HashSet();String c(String[]a){int x=0,y=0,n,t,u,v,w=t=u=v=-1;l=a.length;k=a[0].length();z=new char[l][k];for(String s:a){for(char c:s.toCharArray())z[x][y++]=c;}x++;y=0;}for(x=0;x<l;x++)for(y=0;y<k;y++){n=0;if(z[x][y]>32){if(x<1|(x>0&&z[x-1][y]<33))n++;if(y<1|(y>0&&z[x][y-1]<33))n++;if(x>l-2|(x<l-1&&z[x+1][y]<33))n++;if(y>k-2|(y<k-1&&z[x][y+1]<33))n++;}if(n>2&t<0){t=x;u=y;}if(n>2&t>v){v=x;w=y;}}if(v+w>t+u){p(t,u);return n(""+z[t][u],t,u);}p(v,w);return n(""+z[v][w],v,w);}String n(String r,int x,int y){int a,b;if(x>0&&z[a=x-1][b=y]>32&q(a,b)){p(a,b);return n(r+z[a][b],a,b);}if(y>0&&z[a=x][b=y-1]>32&q(a,b)){p(a,b);return n(r+z[a][b],a,b);}if(x<l-1&&z[a=x+1][b=y]>32&q(a,b)){p(a,b);return n(r+z[a][b],a,b);}if(y<k-1&&z[a=x][b=y+1]>32&q(a,b)){p(a,b);return n(r+z[a][b],a,b);}return r;}boolean q(int x,int y){return!p.contains(x+","+y);}void p(int x,int y){p.add(x+","+y);}

Ok, mất một lúc .. Trong một số ngôn ngữ lập trình, không có vấn đề gì nếu mảng x và y của bạn nằm ngoài ranh giới của mảng 2D, nhưng với Java, nó sẽ bị ném ArrayIndexOutOfBoundsExceptions, vì vậy mọi thứ phải được kiểm tra ..

Trước tiên tôi xác định điểm bắt đầu và sau đó sử dụng phương thức đệ quy để xây dựng chuỗi từ đó. Ngoài ra, tôi sử dụng một danh sách để theo dõi các phối hợp mà tôi đã gặp, vì vậy nó sẽ không đi vào vòng lặp qua lại (dẫn đến StackOverflowException).

Đây có lẽ là câu trả lời dài nhất mà tôi đã đăng cho đến nay, nhưng mặc dù một số phần có thể được đánh gôn, tôi không nghĩ thử thách này có thể ngắn hơn nhiều trong Java. Java chỉ không phù hợp để đi theo một đường dẫn trong lưới .. Tuy nhiên, đó là một thách thức thú vị để tìm ra. :)

Các trường hợp bất ngờ & thử nghiệm:

Hãy thử nó ở đây.

import java.util.*;
class M{
  static int l,
             k;
  static char[][] z;
  static Set p = new HashSet();

  static String c(String[] a){
    int x=0,
        y=0,
        n,
        t,
        u,
        v,
        w = t = u = v = -1;
    l = a.length;
    k = a[0].length();
    z = new char[l][k];
    for(String s:a){
      for(char c:s.toCharArray()){
        z[x][y++] = c;
      }
      x++;
      y = 0;
    }
    for(x=0; x<l; x++){
      for(y=0; y<k; y++){
        n = 0;
        if(z[x][y] > 32){ // [x,y] is not a space
          if(x < 1 | (x > 0 && z[x-1][y] < 33)){
            n++;
          }
          if(y < 1 | (y > 0 && z[x][y-1] < 33)){
            n++;
          }
          if(x > l-2 | (x < l-1 && z[x+1][y] < 33)){
            n++;
          }
          if(y > k-2 | (y < k-1 && z[x][y+1] < 33)){
            n++;
          }
        }
        if(n > 2 & t < 0){
          t = x;
          u = y;
        }
        if(n > 2 & t > v){
          v = x;
          w = y;
        }
      }
    }
    if(v+w > t+u){
      p(t, u);
      return n(""+z[t][u], t, u);
    }
    p(v, w);
    return n(""+z[v][w], v, w);
  }

  static String n(String r, int x, int y){
    int a,b;
    if(x > 0 && z[a=x-1][b=y] > 32 & q(a,b)){
      p(a, b);
      return n(r+z[a][b], a, b);
    }
    if(y > 0 && z[a=x][b=y-1] > 32 & q(a,b)){
      p(a, b);
      return n(r+z[a][b], a, b);
    }
    if(x < l-1 && z[a=x+1][b=y] > 32 & q(a,b)){
      p(a, b);
      return n(r+z[a][b], a, b);
    }
    if(y < k-1 && z[a=x][b=y+1] > 32 & q(a, b)){
      p(a, b);
      return n(r+z[a][b], a, b);
    }
    return r;
  }

  static boolean q(int x, int y){
    return !p.contains(x+","+y);
  }

  static void p(int x, int y){
    p.add(x+","+y);
  }

  public static void main(String[] a){
    System.out.println(c(new String[]{ "Hel         ",
      "  l      rin",
      "  o,IAmASt g",
      "           S",
      "       !ekan" }));
    p = new HashSet();
    System.out.println(c(new String[]{ "Python" }));
    p = new HashSet();
    System.out.println(c(new String[]{ "P  ngPu  Code ",
      "r  i  z  d  G",
      "o  m  z  n  o",
      "gram  lesA  lf" }));
    p = new HashSet();
    System.out.println(c(new String[]{ "   ~ zyx tsr XWVUTSR",
      "   }|{ wvu q Y     Q",
      "!          p Z `ab P",
      "\"#$ 6789:; o [ _ c O",
      "  % 5    < n \\]^ d N",
      "('& 432  = m     e M",
      ")     1  > lkjihgf L",
      "*+,-./0  ?         K",
      "         @ABCDEFGHIJ" }));
    p = new HashSet();
    System.out.println(c(new String[]{ "  tSyrep    ",
      "  r    p   ",
      "  in Sli   ",
      "   g    Sile",
      "   Snakes  n",
      "Ser      ylt",
      "a eh   ilS ",
      "fe w   t   ",
      "   emo h   ",
      "     Sre    " }));
  }
}

Đầu ra:

Hello,IAmAStringSnake!
Python
ProgrammingPuzzlesAndCodeGolf
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
SlipperyStringSnakesSilentlySlitherSomewhereSafe

924 byte, jesus christ ... lol
Shaun Wild

@Bas VềAlanTuring Hehe. Tôi chỉ đơn giản thực hiện thử thách, đánh mã nó và sau đó nhìn vào số đếm byte. Thực sự cao hơn rất nhiều so với dự kiến, nhưng ah, ít nhất là dưới 1k ... Nếu bạn thấy bất cứ điều gì cần cải thiện hãy cho tôi biết, và nếu bạn có một cách tiếp cận khác với (rất nhiều) ít byte hơn, hãy tách riêng ra bài đăng; Tôi rất muốn thấy nó. PS: Bây giờ là 923 byte. XD
Kevin Cruijssen

Không cần phải kiểm tra everythig , chỉ cần thêm một số phần đệm vào chuỗi của bạn. Có lẽ sử dụng một chuỗi multiline duy nhất làm cho điều đó dễ dàng hơn. Hãy xem câu trả lời C # của tôi được chuyển từ javascript
edc65

1

PHP, 199 184 182 byte

vẫn có thể có một chút tiềm năng chơi gôn

for($w=strpos($i=$argv[1],"
");;)for($y=++$n;$y--;)if($i[$p=$y*$w+$n-1]>" ")break 2;for($p-=$d=$w++;$d&&print$i[$p+=$e=$d];)foreach([-$w,-1,1,$w,0]as$d)if($d+$e&&" "<$i[$d+$p])break;

lấy đầu vào dưới dạng chuỗi đa dòng từ dòng lệnh, mong đợi các ngắt dòng kiểu linux.
Chạy php -r '<code>' '<string>'; thoát khỏi phá vỡ dòng.

phá vỡ

for(
    // find width
    $w=strpos($i=$argv[1],"\n")
    ;
    // find first character: initialize $p(osition)
    ;
)
    for($y=++$n             // increase distance
        ;$y--;)             // loop $y from (old)$n to 0
        if(" "<$i[$p=$y*$w+$n   // if character at $y*($width+1)+$x(=$d-$y) is no space
            -1                  // (adjust for the premature increment)
        ])
            break 2;                    // break loops

for(
    $p-=            // b) reverse the increment that follows in the pre-condition
    $d=             // a) initialize $d to anything!=0 to enable the first iteration
    $w++;           // c) increase $w for easier directions
    $d              // loop while direction is not 0 (cursor has moved)
    &&
    print$i[$p+=$e=$d]              // remember direction, move cursor, print character
    ;
)
    foreach([-$w,-1,1,$w,0]as$d)// loop through directions
        if($d+$e                    // if not opposite previous direction
            &&" "<$i[$d+$p]         // and character in that direction is not space
        )break;                     // break this loop

1

C #, 310

(Chỉnh sửa: sửa lỗi)

Một hàm với tham số chuỗi đa dòng, trả về một chuỗi.

Bao gồm các yêu cầu usingtrong số byte.

Đây là một câu trả lời javascript của tôi.

using System.Linq;
string f(string s){int o=-~s.IndexOf('\n'),m=99;var r=new string(' ',o);(s=r+s+r).Select((c,i)=>{int n=2,e=0,p,w=i%o+i/o;if(c>' '&w<m&&new[]{-1,1,o,-o}.All(d=>(s[i+d]>' '?(e=d)*--n:n)>0))for(m=w,r=""+c+s[p=i+e];new[]{e,o/e,-o/e}.Any(d=>s[p+(e=d)]>' ');)r+=s[p+=e];return i;}).Max();return r;}

Kiểm tra trên ideone

Với không gian

    string f(string s)
    {
        int o = -~s.IndexOf('\n');
        var r = new string(' ', o);
        var m = 99;
        (s = r + s + r).Select((c, i) =>
        {
            int n = 2, e = 0, p, w = i % o + i / o;
            if (c > ' ' & w < m & new[] { -1, 1, o, -o }.All(d => (s[i + d] > ' ' ? (e = d) * --n : n) > 0))
                for (m = w, r = "" + c + s[p = i + e]; 
                     new[] { e, o / e, -o / e }.Any(d => s[p + (e = d)] > ' '); 
                     ) 
                   r += s[p += e];
            return i;
        }
        ).Max();
        return r;
    }

1

Python 2, 251 byte

w=s.find('\n')+1;q=' ';p=q*w+'\n';s=list(p+s+p);d=-w,1,w,-1
def r(x):c=s[x];s[x]=q;v=[c+r(x+o)for o in d if s[x+o]>q];return v[0]if v else c
e=[x for x in range(len(s))if s[x]>q and sum([s[x+o]>q for o in d])<2]
print r(e[e[0]/w+e[0]%w>e[1]/w+e[1]%w])

Hoặc, nếu bạn muốn các dòng mới hàng đầu trong các bản thử nghiệm của mình, thì có 256 byte:

w=s.find('\n',1);q=' ';p=q*-~w+'\n';s=list(p+s[1:]+p);d=-w,1,w,-1
def r(x):c=s[x];s[x]=q;v=[c+r(x+o)for o in d if s[x+o]>q];return v[0]if v else c
e=[x for x in range(len(s))if s[x]>q and sum([s[x+o]>q for o in d])<2]
print r(e[e[0]/w+e[0]%w>e[1]/w+e[1]%w])

Vượt qua tất cả các thử nghiệm.

s="""
  tSyrep    
  r    p    
  in Sli    
   g    Sile
   Snakes  n
Ser      ylt
a eh   ilS  
fe w   t    
   emo h    
     Sre    
"""

Kết quả trong:

SlipperyStringSnakesSilentlySlitherSomewhereSafe

3
Tôi nghĩ bạn có thể thay thế b.append(...)bằng b+=[...]def n(x,y):return ...bằngn=lambda x,y:...
acrolith

1
Tạo một biến cho ' '.
pacholik

1
và sử dụng ~-xthay vì x-1, bạn sẽ không phải sử dụng dấu ngoặc đơn.
pacholik

0

Japt -P , 106 byte

K=U·ÌÊÄ ç iU ¬mx T=[-KJ1K]
ËÊ*Tm+E è@gX
[]V£YÃf@gXÃrQ@WpQ Tm+Q kW fZ Ì}V£[XYuK YzK]ÃkÈv ÉÃñx v rÈ+Y*K
W£gX

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

Đó là ... ừm ... một sự gớm ghiếc.

Giải nén & Cách thức hoạt động

K=UqR gJ l +1 ç iU q mx
  UqR gJ l +1            Split the input by newline, take last item's length +1
K=                       Assign to K
              ç iU       Generate a string of K spaces, and append to U
                   q mx  Split into chars, and trim whitespaces on each item
                         Implicit assign to U

T=[-KJ1K]  Assign an array [-K, -1, 1, K] to T (this represents 4-way movement)
           I could use implicit assignment, but then 4-argument function below is broken

UmDEF{Dl *Tm+E èXYZ{UgX
UmDEF{                   Map over the list of one- or zero-length strings...
      Dl *                 If the length is zero, return zero
          Tm+E             Add the index to each element of T
               èXYZ{UgX    Count truthy elements at these indices
                         The result is an array of 0(space/newline), 1(start/end), or 2(body)
                         Implicit assign to V

[]  Implicit assign to W

VmXYZ{Y} fXYZ{UgX} rQXYZ{WpQ Tm+Q kW fZ gJ }
VmXYZ{Y}                                      Map V into indices
         fXYZ{UgX}                            Filter the indices by truthiness of U's element
                   rQXYZ{                     Reduce on the indices... (Q=last item, Z=array)
                         WpQ                    Push Q to W
                             Tm+Q               Take 4-way movements from Q
                                  kW fZ gJ }    Exclude visited ones, take last one in Z

VmXYZ{[XYuK YzK]} kXYZ{Xv -1} ñx v rXYZ{X+Y*K  Starting point of reduce
VmXYZ{[XYuK YzK]}                              Convert elements of V to [elem, col, row]
                  kXYZ{Xv -1}                  Take the ones where elem(popped)=1
                              ñx v             Sort by row+col and take first one
                                   rXYZ{X+Y*K  Convert [row,col] back to the index

WmXYZ{UgX  Map indices back to chars

-P  Join with empty string

Một điểm đáng chú ý là tôi đã sử dụng quyền ưu tiên của toán tử giữa các toán tử gán và dấu phẩy trong JS, để đóng gói một số dòng và giữ phím tắt @( XYZ{) có thể sử dụng được.

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.