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
Тут є одна незначна тонкоща з таким вкладом:
ABC
DDDDDDDDD
ABC
ABC
ABC
Подивіться тут четвертий рядок. Якби порядок написання був BACBD, там справді може бути горизонтальна лінія Bs, не порушуючи жодного з припущень проблеми (крім того, що є лише один рядок кожного кольору, те, що ми не перевіряємо). Для того, щоб обійти це, ми гарантуємо, що в останньому зворотному виразі кожен рядок починається з літери (або цифри або підкреслення, але це неможливо), і спираємось на те, що паралельні рядки знайдуться зліва направо і вгорі -донизу (тому що регулярний вираз знайде першу відповідність у рядку). Таким чином, перший символ кожного неоднозначного рядка тут перезаписується перед тим, як сам рядок розглядається як збіг, і це перешкоджає збігу регулярних виразів.