Hộp biến hình


18

Tôi xác định bốn kiểu hộp:

+-----+   ooooooo    ^^^^^   *******
|  1  |   o  2  o   <  3  >  *  4  *
|     |   o     o   <     >  *     *
+-----+   ooooooo    vvvvv   *******

Viết chương trình hoặc hàm đã cho một số nguyên và một chuỗi sẽ tìm thấy một trong các hộp ở trên bên trong chuỗi và thay đổi kiểu của nó thành kiểu hộp do người dùng yêu cầu. Ví dụ:

1
This is a test document.
It ********* has
no *purpose* other than
dem*onstrat*ion.
   *********

Trở thành:

This is a test document.
It +-------+ has
no |purpose| other than
dem|onstrat|ion.
   +-------+

Bạn có thể giả sử rằng đầu vào chứa chính xác một hộp hợp lệ ít nhất là 3x3. Mã của bạn phải bỏ qua các hộp không đầy đủ / không chính xác:

ooooooooooooooooooooooooooooooooo
o This is not a box. o This is. o
ooooooooooo ooooo ooooooooooooooo

      ^^^^     ######
     <NOPE>    #NOPE#
      vVVv     ######

Mã ngắn nhất trong byte thắng.


Nói rõ hơn, trong ví dụ cuối cùng, hộp có 2 chữ hoa Vs không hợp lệ, nhưng nếu chúng được viết chữ thường, thì hộp có còn hiệu lực không? Ngoài ra, nếu có nhiều hộp, chúng ta chỉ cần thay đổi 1, đúng không?
Kade

@ Vioz- Đúng, hộp có chữ hoa Vs chỉ không hợp lệ vì viết hoa không khớp. Bạn có thể cho rằng sẽ không bao giờ có hai hoặc nhiều hộp hợp lệ - sẽ luôn có chính xác một hộp hợp lệ trong đầu vào.
orlp

Có phải phong cách 3 yêu cầu không gian trong các góc?
PurkkaKoodari

@ Pietu1998 Có.
orlp

1
Phải mất một chút thời gian để tìm hiểu lý do tại sao tôi nhận được một đầu ra kỳ lạ từ mã "tìm hộp" của tôi ... ví dụ của bạn về cái không phải là một hộp ở cuối có hai hộp hợp lệ trong đó: o This is. oo This is no(với dòng otrên và dưới, tất nhiên).
Glen O

Câu trả lời:


5

Julia, 995 818 713 613 byte

g=(s,n)->(w=map;f=t->(t[z=end];for i=1:z-2,j=eachmatch(r"([*o]|(\+)|(\ ))(?(2)-|(?(3)\^|\1))+\1",t[i],1>0),k=i+2:z N=j.match;N[M=end];p=N[1];J=j.offset;u=w(i->i[[J:J+M-1]∩[1:end]],t);try p%3<1?for l=matchall(r"^([*o])\1+\1",u[k]),q=3:endof(l) w(r->r[[1,q]],u[i:k])⊆["$p$p"]&&return(i,k,J,J+q-1)end:u[k]==replace(N,"^","v")&&w(r->r[[1,M]],u[i+1:k-1])⊆[p<33?"<>":"||"]&&return(i,k,J,M+J-1)end;end);o=ones(5)';T=split(s,'\n');(i,j,k,l)=f(T);u=w(collect,T);(a,u[i][r=k+1:l-1],u[j][r],b,c)=41+[2 4 4 83 83;70o;-9 53 77 19 21;o][n,:];u[i][I]=u[j][I=[k,l]]=a;w(e->(e[k]=b;e[l]=c),u[i+1:j-1]);join(w(join,u),'\n'));

Ung dung với lời giải thích:

function g(s,n)
  # First, we define function f(t), which finds the box
  function f(t)
    # determine the number of rows of text
    z=length(t)
    # Get an iterator of all of the matches to iterate over
    # Regex handles all four box styles
    temp=i->eachmatch(r"([*o]|(\+)|(\ ))(?(2)-|(?(3)\^|\1))+\1",t[i],1>0)
    # Iterate over rows up to third-last one (i)...
    # and over any possible box-tops on each of those rows (j)...
    # and all possible box-bottom rows for each possible box-top (k)
    for i=1:z-2,j=temp(i),k=i+2:z
      # N holds the matched box-top
      N=j.match
      # M stores the length of the match
      M=length(N)
      # p holds the first letter of the match, the corner character.
      p=N[1]
      # J holds the position of the first character of the match in row i
      J=j.offset
      # The intersection here allows truncation of each row to only those
      # parts that lie within the valid range of the box-top
      u=map(i->i[[J:J+M-1]∩[1:end]],t)
      # A try block is being used to skip if a BoundsError is encountered
      # this BoundsError will occur if a box cannot be formed due to
      # a row not being long enough to form both sides or to form bottom
      try
        # This distinguishes between simple boxes (types 2 and 4)
        # from fancy boxes (types 1 and 3), as code differs between them
        if p%3<1 # "then" for simple boxes
          # loop over l either doesn't run (if bottom won't form a match
          # from position 1 within u) or holds the unique match
          # then loop over q looks at all possible bottom-lengths
          for l=matchall(r"^([*o])\1+\1",u[k]),q=3:endof(l)
            # If box sides are found to match top and bottom...
            if map(r->r[[1,q]],u[i:k])⊆["$p$p"]
              # return the coordinates of the box
              return(i,k,J,J+q-1)
            end
          end
        else # "else" for fancy boxes
          # If the bottom matches the top (replace fixes for type 3)...
          if u[k]==replace(N,"^","v")
            # ... and the edges are also there...
            if map(r->r[[1,M]],u[i+1:k-1])⊆[p<33?"<>":"||"]
              # return the coordinates
              return(i,k,J,M+J-1)
            end
          end
        end
      end
    end
  end
  # That defines function f(t), now for the replacement part of the code
  # Input s is a single string with newlines, split into separate strings
  T=split(s,'\n')
  # Find the coordinates of the box using f(T)
  (i,j,k,l)=f(T)
  # u holds the same strings, but stored as char arrays
  u=map(collect,T)
  # Here, we have the appropriate replacement characters for each type
  # with n determining which character from each array is taken
  # Variable names are used here to make it clearer
  corners =  ['+';'o';' ';'*'][n]
  topedge =  ['-';'o';'^';'*'][n]
  bottomedge=['-';'o';'v';'*'][n]
  leftedge = ['|';'o';'<';'*'][n]
  rightedge= ['|';'o';'>';'*'][n]
  # Assign the appropriate characters in the appropriate places
  u[i][[k,l]]=corners
  u[j][[k,l]]=corners
  u[i][k+1:l-1]=topedge
  u[j][k+1:l-1]=bottomedge
  # Iteration is required here because it's an array of arrays
  for e=i+1:j-1
    u[e][k]=leftedge
    u[e][l]=rightedge
  end
  # All that's left to do is recombine to form a single string again
  # we join each internal char array into single-line strings...
  # then join the strings together with a newline delimiter, and return
  return join(map(join,u),'\n')
end

Trái với cách tôi tiếp cận lần đầu tiên, mã này sẽ chỉ hoạt động chính xác cho các số loại "hợp lệ" - 1, 2, 3 hoặc 4. Nó được chia thành hai phần - công cụ tìm hộp và trình thay thế hộp. Mã, hàm tìm hộp f(t), sử dụng regex để xác định vị trí các đỉnh và, đối với các hộp đơn giản hơn (loại 2 và 4), đáy.

Regex đầu tiên là cách đơn giản nhất mà tôi có thể tìm thấy để tìm các hộp đựng đồ. Đây là logic của nó:

r"([*o]|(\+)|(\ ))(?(2)-|(?(3)\^|\1))+\1"
  ([*o]|(\+)|(\ ))                        < This finds the first corner
        ( 2) ( 3)                         . if a + or space, conditionals
  (    1         )                        . kick in, so they're captured
                                          . separately
                  (?(2)-|           )     < If a +, top edge must be
                                          . at least one -
                         (?(3)\^|\1)      < Otherwise, if a space, top
                                          . edge must be at least one ^,
                                          . otherwise, repeat the corner
                                     +    < Allows more than one top-edge
                                          . character
                                      \1  < finish with the same corner
                                          . char found at the start

Mã được sử dụng như thế này:

julia> s="""This is a test document.
       It************* has
       no *purpose* other than
       dem*onstrat*ion.
        ************o""";

julia> print(s)
This is a test document.
It************* has
no *purpose* other than
dem*onstrat*ion.
 ************o
julia> print(g(s,1))
This is a test document.
It*+-------+*** has
no |purpose| other than
dem|onstrat|ion.
 **+-------+*o

In không được bao gồm trong chức năng, vì định dạng đầu ra không được chỉ định - Tôi chỉ cần trả về chuỗi, bạn có thể in nó sau đó như đã thấy ở trên.

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.