重叠线序


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 '16

Answers:


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,那么沿着s 可能确实有一条水平Bs 线,而不违反问题的任何假设(除了每种颜色只有一条线,我们没有检查)。为了解决这个问题,我们保证在最后的正则表达式,每行开始以字母(或数字或下划线,但这些都是不可能的),并依赖于一个事实,即平行线会被发现左到右,上-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

Python 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)

结果比我最初的预期要长得多。除了rindexI,我认为这是翻译成Pyth的很好的程序。

接受行列表并输出字符列表。该代码以递归方式生成排列,确保不应在当前行的顶部绘制任何绘制的行。

该代码滥用了许多Python的功能,例如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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.