Đặt hàng chồng chéo


17

(Lấy cảm hứng trong khi vẽ trên bảng xóa khô)

Thử thách:

Đưa ra một chuỗi đầu vào có chứa các ký tự đại diện cho các màu khác nhau của các dấu xóa khô trên bảng trắng, xuất ra thứ tự mà chúng được vẽ, từ đầu đến cuối.

Đầu vào:

Một chuỗi chứa các màu đánh dấu xóa khô được biểu thị bằng các chữ cái (chữ cái trên khác với chữ thường, bạn có thể thay thế bất kỳ ký tự nào được sử dụng trong các ví dụ của tôi miễn là mỗi màu có một chữ cái riêng biệt). Phần còn lại của bảng trắng sẽ là khoảng trắng. Sẽ chỉ có một dòng của mỗi màu trên mỗi bảng. Sẽ không có đầu vào trong đó tất cả các dòng chồng lên nhau (Xem trường hợp thử nghiệm 4). Tất cả các dòng sẽ thẳng và ngang hoặc dọc.

Đầu ra:

Thứ tự mà các dòng được vẽ trên bảng, từ cái đầu tiên được vẽ đến cái cuối cùng. Nếu có nhiều giải pháp cho bất kỳ đầu vào nào, bạn có thể xuất bất kỳ một trong số chúng. Đầu ra có thể được định dạng bằng bất cứ cách nào bạn thích: một chuỗi ký tự hoặc được phân tách bằng dấu cách, dòng mới, v.v ... miễn là các ký tự được sử dụng khớp với các ký tự được sử dụng trong đầu vào của bạn.

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

Đầu vào 1:

  R
  R
BBRBB
  R

Đầu ra 1:

BR

Đầu vào 2:

    GY
    GY
RRRRGYRRR
    GY
    GY
BBBBBBBB
    GY
    GY

Đầu ra 2:

RGYB // or RYGB

Đầu vào 3:

    R    P
    R    P
AAAARAAAAPA
    R    P
    R    P
GGGGRGGG P
    R

Đầu ra 3:

AGPR // or APGR

Đầu vào 4:

 O Y
RRRYR
 O Y
GOGGG
 O Y

Đầu ra 4:

// Undefined, does not need to be handled by your program

Đầu vào 5:

YYYB
   B
   B

Đầu ra 5:

// YB or BY

Quy tắc:

Đây là , vì vậy mã ngắn nhất tính bằng byte thắng.


@StewieGriffin Có thể có nhiều ký tự ASCII có thể in được (33-127). Tôi đã sử dụng màu bình thường trong các trường hợp thử nghiệm của mình, nhưng vì chúng là các ký tự mà chúng không thực sự tương ứng với các màu thực tế (Đỏ, Xanh lục, Vàng, v.v.), chúng chỉ đại diện cho các màu độc đáo (R là một màu khác với G và Y) .
Yodle

1
À đúng rồi, tôi sẽ chỉ nói các ký tự chữ cái thôi (65-90 và 97-122).
Yodle

Tất cả các dòng sẽ là ngang hoặc dọc, phải không? Bạn có lẽ nên xác định rằng trong câu hỏi.

@ ais523 Có, đã chỉnh sửa nó.
Yodle

Chúng ta có thể giả sử rằng đầu vào được đệm bằng khoảng trắng thành hình chữ nhật không?
PurkkaKoodari

Câu trả lời:


5

Perl, 103 + 2 = 105 byte

s/$/$"x y===c/gem;$a=$_;$_.=$"while$a=~s/^./!($_.=$&)/gem;s/$1/-/g,$b="$&$b"while/\s(\w)(\1|-)+ /;say$b

Chạy với -n0 (hình phạt 2 byte).

Giải trình:

# -n0: read entire input into `$_` at start of program
# (technically speaking it reads to the first NUL byte, but there aren't any)

# We want to be able to extract columns from the input, so we need to add spaces
# to the ends of each line such that each column is complete. Adding too many
# space is OK, so to ensure we have enough, we add a number of spaces equal to the
# length of the input.
s/$/             # At the end of {something},
$" x             # append a number of spaces ($" is a space by default)
y===c            # obtained by counting the characters in $_
/gem;            # where {something} is each (g) line (m)

$a = $_;         # store a copy of the transformed input in $a

# The next step is to create a transposition of the input. To do that, we
# repeatedly extract the first column of $a and append it to $_. This will lead to
# a bunch of junk whitespace at the end of $_ (of varying lengths, because once a
# line is empty it's omitted from the extracted column), but we're OK with that.
# To transpose properly, we'd want to place newlines between the extracted
# columns; however, it happens that the rest of the program treats space the same
# way it would newline, and separating via spaces is shorter, so we do that.

while (          # keep looping as long as there are matches
  $a =~ s/^./    # replace the first character of {something related to $a}
  !(             # with the null string (NOT of something truthy)
    $_.=$&)      # but append that character ($&) to $_
  /gem) {        # {something} is each (g) line (m) of $a
  $_.=$"         # append a space ($", equivalent to newline here) to $_
}

# Finally, we repeatedly replace every character in the topmost line with the -
# character (treating a line as continuous through the - character but not through
# other characters), thus finding the lines from top to bottom. Because we
# appended the transpose of $_ to $_ above, each line appears twice: once
# horizontally, once vertically. We find only the horizontal copy, but replace
# both with hyphens.
# (Note: I rewrote the regex into a bit more readable of a form in this ungolfed
# version, because the original version wouldn't allow me room to write comments
# inside it. The two should be equivalent; I tested the golfed version.)
while (          # keep looping as long as there are matches
  /\s(\w)        # match a space or newline, $1 (a letter/digit/underscore),
    (\1|-)+      # any positive number of $1s and hyphens,
    \ /x) {      # and a space
  s/$1/-/g,      # changes all $1s to spaces; set $& to $1, $1 becomes invalid
  $b = "$&$b"    # prepend $& to $b
}

# We need to output the lines from first (i.e. bottom) to last (i.e. top).
# We found them in the opposite order, but reversed them via prepending
# (not appending) the partial results to $b.
say $b           # output $b

Một chút tinh tế ở đây đi kèm với đầu vào như thế này:

   ABC
DDDĐDĐD
   ABC
   ABC
   ABC

Nhìn vào dòng thứ tư ở đây. Nếu thứ tự của văn bản là BACBD, có thực sự có thể là một ngang dòng Bs cùng có mà không vi phạm bất kỳ của các giả định của vấn đề (trừ rằng chỉ có một dòng của mỗi màu sắc, một cái gì đó mà chúng ta không kiểm tra). Để giải quyết vấn đề này, chúng tôi đảm bảo trong regex cuối cùng rằng mỗi dòng bắt đầu bằng một chữ cái (hoặc chữ số hoặc gạch dưới, nhưng không thể) và dựa vào thực tế là các đường song song sẽ được tìm thấy từ trái sang phải và trên cùng -to-bottom (vì regex sẽ tìm thấy kết quả khớp đầu tiên trong chuỗi). Như vậy, ký tự đầu tiên của mỗi dòng mơ hồ ở đây sẽ bị ghi đè trước khi chính dòng đó được xem là khớp và điều đó ngăn cản kết hợp biểu thức chính quy.


Rất ấn tượng ... Tốt lắm! (Tôi ở mức 161 byte, với perl -n0E '/.*/;for$i(/(\S)(?=(?:(?:.{@{+}})?(?:\1| ))*(?!.*\1))/gs){/.*/;unless(/$i+[^$i\s]+$i/||/$i(.{@{+}}[^$i ])+.{@{+}}$i/s){$r="$i$r";s/$i/ /g;last}}/\S/?redo:say$r'(yêu cầu các dòng đầu vào phải được đệm đúng với các khoảng trắng có cùng độ dài))
Dada

2

Python 2, 199 byte

l=input()
w=len(l[0])
j="".join(l)
c=set(j)-{" "}
def f(s):
 for h in s:
  i=j.index(h);I=j.rindex(h);o=f(s-{h})
  if{0}>c-s&set(j[i:I:w**(i+w<=I)])and`o`>"Z":return[h]+o
 if{0}>s:return[]
print f(c)

Điều này đã kết thúc lâu hơn nhiều so với tôi nghĩ ban đầu. Ngoài ra rindextôi có thể thấy đây là một chương trình rất hay để dịch sang Pyth.

Đưa vào một danh sách các dòng và xuất ra một danh sách các ký tự. Mã tạo ra hoán vị đệ quy, đảm bảo rằng không có dòng nào được vẽ sẽ được vẽ trên đầu dòng hiện tại.

Mã lạm dụng rất nhiều tính năng của Python, ví dụ như sử dụng wsức mạnh của boolean, kiểm tra các tập hợp trống bằng cách kiểm tra các tập hợp con {0}(vì các tập hợp của tôi không bao giờ chứa các chuỗi không) và yêu thích của tôi, phân biệt bất kỳ danh sách nào Nonebằng cách kiểm tra xem đại diện lớn hơn Z.

Mã giải thích

lines = input()
width = len(lines[0])
joined = "".join(lines)
characters = set(joined) - {" "} # find unique characters except space in input

def solve(chars_left): # returns a solution for the given set of lines
    for try_char in chars_left: # try all lines left

        start_index = joined.index(try_char) # find start position of this line
        end_index = joined.rindex(try_char) # and end position

        step = width ** (start_index + width <= end_index) # take every width'th character if start
                                                           # and end indices differ by at least width

        used_chars = characters - chars_left # find all drawn lines

        line_chars = set(joined[start_index:end_index:step]) # find the characters inside the current line
        missed_chars = used_chars & line_chars # find all lines that are already drawn but should be on
                                               # top of this line

        solution = solve(chars_left - {try_char}) # find solutions if this line was drawn now

        if {0} > missed_chars and `solution` > "Z": # there should be no missed lines and a solution
                                                    # should exist
            return [try_char] + solution # solution found, prepend current character and return

    if {0} > chars_left: # if no lines are left
        return [] # solution found

print solve(characters) # solve for all lines
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.