Ordre des lignes superposées


17

(Inspiré en dessinant sur un tableau effaçable à sec)

Défi:

Étant donné une chaîne d'entrée contenant des caractères qui représentent différentes couleurs de marqueurs effaçables à sec sur un tableau blanc, affichez l'ordre dans lequel ils ont été dessinés, du premier au dernier.

Contribution:

Une chaîne qui contient des couleurs de marqueur effaçables à sec qui sont représentées par des lettres alphabétiques (les lettres supérieures sont différentes des lettres minuscules, vous pouvez remplacer tous les caractères utilisés dans mes exemples tant que chaque couleur a une lettre distincte). Le reste du tableau blanc sera un espace blanc. Il n'y aura qu'une seule ligne de chaque couleur par planche. Il n'y aura pas d'entrées où toutes les lignes se chevauchent (voir cas de test 4). Toutes les lignes seront droites et horizontales ou verticales.

Production:

L'ordre dans lequel les lignes ont été tracées sur le tableau, du premier tracé au dernier. S'il existe plusieurs solutions pour n'importe quelle entrée, vous pouvez sortir n'importe laquelle d'entre elles. La sortie peut être formatée comme vous le souhaitez: une seule chaîne de caractères ou séparée par des espaces, des retours à la ligne, etc. tant que les caractères utilisés correspondent à ceux utilisés dans votre entrée.

Cas de test:

Entrée 1:

  R
  R
BBRBB
  R

Sortie 1:

BR

Entrée 2:

    GY
    GY
RRRRGYRRR
    GY
    GY
BBBBBBBB
    GY
    GY

Sortie 2:

RGYB // or RYGB

Entrée 3:

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

Sortie 3:

AGPR // or APGR

Entrée 4:

 O Y
RRRYR
 O Y
GOGGG
 O Y

Sortie 4:

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

Entrée 5:

YYYB
   B
   B

Résultat 5:

// YB or BY

Règles:

C'est le , donc le code le plus court en octets l'emporte.


@StewieGriffin Il peut y avoir autant de caractères ASCII imprimables (33-127). J'ai utilisé des couleurs normales dans mes cas de test, mais comme ce sont des caractères qui ne correspondent pas réellement aux couleurs réelles (rouge, vert, jaune, etc.), ils représentent simplement des couleurs uniques (R est une couleur différente de G et Y) .
Yodle

1
Eh ouais bon point, je ne dirai que des caractères alphabétiques (65-90 et 97-122).
Yodle

Toutes les lignes seront horizontales ou verticales, non? Vous devriez probablement préciser cela dans la question.

@ ais523 Oui, édité dedans.
Yodle

Pouvons-nous supposer que l'entrée est complétée par des espaces dans un rectangle?
PurkkaKoodari

Réponses:


5

Perl, 103 + 2 = 105 octets

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

Exécuter avec -n0(pénalité de 2 octets).

Explication:

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

Une légère subtilité vient ici avec une entrée comme celle-ci:

   abc
DDDDDDDDD
   abc
   abc
   abc

Regardez la quatrième ligne ici. Si l'ordre d'écriture était BACBD, il pourrait y avoir véritablement une ligne horizontale de Bs sans violer aucune des hypothèses du problème (à part cela, il n'y a qu'une seule ligne de chaque couleur, ce que nous ne vérifions pas). Afin de contourner cela, nous nous assurons dans la dernière expression régulière que chaque ligne commence par une lettre (ou un chiffre ou un trait de soulignement, mais ceux-ci sont impossibles), et nous comptons sur le fait que les lignes parallèles se trouveront de gauche à droite et en haut -en bas (parce que l'expression régulière trouvera la première correspondance dans la chaîne). En tant que tel, le premier caractère de chaque ligne ambiguë est écrasé avant que la ligne elle-même ne soit considérée comme une correspondance, ce qui empêche la correspondance d'expression régulière.


Très impressionnant ... Bravo! (J'étais à 161 octets, avec 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'(ce qui nécessite que les lignes d'entrée soient remplies à droite avec des espaces de même longueur))
Dada

2

Python 2, 199 octets

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)

Cela a fini beaucoup plus longtemps que je ne le pensais au départ. En dehors de cela, rindexje pouvais voir cela comme un très bon programme à traduire en Pyth.

Prend une liste de lignes et sort une liste de caractères. Le code génère des permutations récursivement, en s'assurant qu'aucune des lignes tracées n'est censée être tracée au-dessus de la ligne actuelle.

Le code abuse de nombreuses fonctionnalités de Python, par exemple en prenant wla puissance d'un booléen, en testant les ensembles vides en vérifiant les sous-ensembles de {0}(puisque mes ensembles ne contiennent jamais de non-chaînes), et mon préféré, en distinguant toute liste Noneen vérifiant si son la représentation est supérieure à Z.

Code expliqué

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.