겹치는 라인 주문


17

(드라이 지우기 보드에 그릴 때 영감을 얻음)

도전:

화이트 보드에 서로 다른 색상의 드라이 소거 마커를 나타내는 문자가 포함 된 입력 문자열이 주어지면 처음부터 끝까지 그려진 순서를 출력합니다.

입력:

알파벳 문자로 표시되는 드라이 소거 마커 색상을 포함하는 문자열 화이트 보드의 나머지 부분은 공백입니다. 보드 당 각 색상의 한 줄만 있습니다. 모든 선이 서로 겹치는 입력은 없습니다 (테스트 사례 참조 4). 모든 선은 직선이며 가로 또는 세로입니다.

산출:

보드에서 선이 그려진 순서, 첫 번째 선부터 마지막 ​​선까지. 입력에 대해 여러 솔루션이있는 경우 그 중 하나를 출력 할 수 있습니다. 사용 된 문자가 입력에 사용 된 문자와 일치하는 한 단일 문자열 또는 공백, 줄 바꿈 등으로 구분하여 원하는대로 출력 형식을 지정할 수 있습니다.

테스트 사례 :

입력 1 :

  R
  R
BBRBB
  R

출력 1 :

BR

입력 2 :

    GY
    GY
RRRRGYRRR
    GY
    GY
BBBBBBBB
    GY
    GY

출력 2 :

RGYB // or RYGB

입력 3 :

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

출력 3 :

AGPR // or APGR

입력 4 :

 O Y
RRRYR
 O Y
GOGGG
 O Y

출력 4 :

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

입력 5 :

YYYB
   B
   B

출력 5 :

// YB or BY

규칙 :

이것은 이므로 바이트 단위의 가장 짧은 코드가 이깁니다.


@StewieGriffin 인쇄 가능한 ASCII 문자 (33-127)까지 가능합니다. 테스트 사례에서 일반 색상을 사용했지만 문자이기 때문에 실제 색상 (빨간색, 녹색, 노란색 등)과 실제로 일치하지 않으므로 고유 한 색상 만 나타냅니다 (R은 G 및 Y와 다른 색상). .
Yodle

1
예, 좋은 점은 알파벳 문자 (65-90 및 97-122) 만 말할 것입니다.
Yodle

모든 선이 가로 또는 세로로 표시됩니다. 아마도 질문에서 그것을 지정해야합니다.

@ ais523 예, 편집했습니다.
Yodle

입력이 사각형에 공백으로 채워져 있다고 가정 할 수 있습니까?
PurkkaKoodari

답변:


5

Perl, 103 + 2 = 105 바이트

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

-n0(2 바이트 페널티)로 실행하십시오 .

설명:

# -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

여기에 약간의 미묘함이 다음과 같은 입력으로 제공됩니다.

   알파벳
DDDDDDDDD
   알파벳
   알파벳
   알파벳

여기 네 번째 줄을보십시오. 서면 순서가 BACBD라면 문제의 가정을 위반하지 않고 실제로 가로 줄 이 생길 수 있습니다 B(각 색상의 한 줄만, 우리가 확인하지 않는 것 제외). 이 문제를 해결하기 위해 마지막 정규 표현식에서 각 줄 문자 (또는 숫자 또는 밑줄로 시작하지만 불가능합니다)를 보장하고 평행선이 왼쪽에서 오른쪽으로, 위쪽에서 발견된다는 사실에 의존합니다. -to-bottom (정규 표현식이 문자열 내에서 첫 번째 일치 항목을 찾기 때문에). 따라서 여기에서 각 모호한 줄의 첫 문자는 줄 자체가 일치하는 것으로 표시되기 전에 덮어 쓰기되어 정규식 일치를 방지합니다.


매우 인상적입니다 ... 잘하셨습니다! (나는 161 바이트에 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'(입력 라인은 모두 같은 길이의 공백으로 오른쪽 채워 져야 함))
Dada

2

파이썬 2, 199 바이트

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)

이것은 처음에 생각했던 것보다 훨씬 길었습니다. rindex나는 이것을 제외하고는 이것을 Pyth로 번역하기에 매우 좋은 프로그램으로 볼 수있었습니다.

행 목록을 받아서 문자 목록을 출력합니다. 이 코드는 순열을 재귀 적으로 생성하여 현재 선 위에 그려진 선이 그려지지 않도록합니다.

이 코드는 많은 파이썬 기능을 악용합니다. 예를 들어 w부울의 힘을 취하고 하위 세트 {0}(문자열에 문자열이 포함되어 있지 않기 때문에)의 하위 세트를 확인하여 빈 세트를 테스트 하고 즐겨 찾는 항목 None이 있는지 여부를 확인 하여 목록을 구별합니다. 표현이보다 큽니다 Z.

설명 된 코드

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.