Çakışan Çizgi Siparişi


17

(Kuru silme tahtasında çizim yaparken esinlenir)

Meydan okuma:

Beyaz tahtada farklı renkteki kuru silme işaretleyicilerini temsil eden karakterler içeren bir giriş dizesi verildiğinde, ilk sıradan son çizildikleri sırayla çıktılar.

Giriş:

Alfabetik harflerle temsil edilen kuru silme işaretleyici renklerini içeren bir dize (büyük olanlar küçük harflerden farklıdır, her bir rengin farklı bir harfi olduğu sürece örneklerimde kullanılan karakterleri değiştirebilirsiniz). Beyaz tahtanın geri kalanı beyaz boşluk olacaktır. Kart başına her rengin yalnızca bir satırı olacaktır. Tüm çizgilerin üst üste geldiği girişler olmayacaktır (Test durumuna bakın 4). Tüm çizgiler düz ve yatay veya dikey olacaktır.

Çıktı:

İlkinden sonuncusuna kadar çizgilerin tahtaya çizildiği sıra. Herhangi bir giriş için birden fazla çözüm varsa, bunlardan herhangi birini çıktı alabilirsiniz. Çıktı istediğiniz şekilde biçimlendirilebilir: tek karakter dizisi veya boşluklar, yeni satırlar, vb. İle ayrılır; kullanılan karakterler girişinizde kullanılan karakterlerle eşleştiği sürece.

Test Durumları:

Giriş 1:

  R
  R
BBRBB
  R

Çıkış 1:

BR

Giriş 2:

    GY
    GY
RRRRGYRRR
    GY
    GY
BBBBBBBB
    GY
    GY

Çıkış 2:

RGYB // or RYGB

Giriş 3:

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

Çıkış 3:

AGPR // or APGR

Giriş 4:

 O Y
RRRYR
 O Y
GOGGG
 O Y

Çıkış 4:

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

Giriş 5:

YYYB
   B
   B

Çıktı 5:

// YB or BY

Kurallar:

Bu , bayt en kısa kod kazanır.


@StewieGriffin Yazdırılabilir ASCII karakterleri (33-127) kadar olabilir. Test durumlarımda normal renkler kullandım, ancak karakter oldukları için gerçek renklere (Kırmızı, Yeşil, Sarı, vb.) Karşılık gelmiyorlar, sadece benzersiz renkleri temsil ediyorlar (R, G ve Y'den farklı bir renk) .
Yodle

1
Eh evet iyi bir nokta, sadece alfabetik karakterler söyleyeceğim (65-90 ve 97-122).
Yodle

Tüm çizgiler yatay veya dikey olacak, değil mi? Bunu muhtemelen soruda belirtmelisiniz.

@ ais523 Evet, düzenledi.
Yodle

Girdinin bir dikdörtgene boşluklarla doldurulduğunu varsayabilir miyiz?
PurkkaKoodari

Yanıtlar:


5

Perl, 103 + 2 = 105 bayt

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

İle koş -n0(2 bayt ceza).

Açıklama:

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

Buradaki hafif bir incelik şu şekilde gelir:

   ABC
DDDDDDDDD
   ABC
   ABC
   ABC

Buradaki dördüncü satıra bak. Yazma sırası BACBD olsaydı, gerçekten bir olabileceğini yatay çizgisi B(yani her rengin tek satırda, biz kontrol etmiyoruz o şey var hariç) sorunun varsayımlardan herhangi birini ihlal etmeden orada boyunca s. Bunun üstesinden gelmek için, son regex'te her satırın bir harfle (veya rakam veya alt çizgi ile başlamasını sağlıyoruz , ancak bunlar imkansız) ve paralel çizgilerin soldan sağa ve üstte bulunacağına güveniyoruz -to-bottom (çünkü normal ifade dize içindeki ilk eşleşmeyi bulur). Bu nedenle, buradaki her belirsiz çizginin ilk karakteri, çizginin kendisi bir eşleşme olarak görülmeden önce üzerine yazılır ve bu da normal ifade eşleşmesini önler.


Çok etkileyici ... Aferin! (161 bayttaydım 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'(giriş satırlarının boşlukların aynı uzunlukta olması için sağ tarafa doldurulmasını gerektirir))
Dada

2

Python 2, 199 bayt

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)

Bu başlangıçta düşündüğümden çok daha uzun sürdü. Bunun dışında rindexbunu Pyth'e çevirmek için çok iyi bir program olarak görebiliyordum.

Satırların bir listesini alır ve karakterlerin bir listesini çıkarır. Kod, çizilen çizgilerin hiçbirinin geçerli çizginin üstüne çizilmemesi gerektiğinden emin olarak yinelemeli permütasyonlar üretir.

Kod w, bir Boole'nin gücünü almak, alt kümelerini kontrol ederek {0}(kümelerim hiçbir zaman dizgisiz olmadığı için) ve favorilerimi listeden ayırarak boş kümeleri test etmek için birçok Python özelliğini kötüye kullanırNone olup olmadığını kontrol ederek temsil daha büyüktür Z.

Açıklanan kod

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.