Biorąc pod uwagę stół, umieść na krzesłach

41

Wyzwanie

Otrzymasz tabelę jako dane wejściowe, narysowane za pomocą ASCII |i _. Twoim zadaniem jest ustawienie wokół niego krzeseł.

Przykład

Wejście:

 ____
|    |
|    |
|    |
|    |
|____|

Wynik:

 _^_^_
<     >
|     |
<     >
|     |
<_ _ _>
  v v

Te krzesła są wykonane z <>i v^.

Inny przykład:

Linia musi zawierać jak najwięcej krzeseł.

  _____
 |     |_____
 |           |
 |           |
 |           |
 |      _____|
 |_____|


  _^_^_
 <     |_^_^_
 |           >
 <           |
 |           |
 <      _ _ _>
 |_ _ _| v v
   v v

Między każdym krzesłem muszą być odstępy. I >_^_^_<jest nieważne, powinno być |_^_^_|.

  _____       _____
 |     |_____|     |
 |                 |
 |                 |
 |                 |
 |      ___________|
 |_____|


  _^_^_       _^_^_
 <     |_^_^_|     >
 |                 |
 <                 >
 |                 |
 <      _ _ _ _ _ _>
 |_ _ _| v v v v v
   v v

Wewnątrz „pączka” nie mogą znajdować się żadne krzesła.

  _________________
 |      _____      |
 |     |     |     |
 |     |     |     |
 |     |_____|     |
 |_________________|


  _^_^_^_^_^_^_^_^_
 <      _____      >
 |     |     |     |
 <     |     |     >
 |     |_____|     |
 <_ _ _ _ _ _ _ _ _>
   v v v v v v v v

^oraz vnadaj priorytety <i >. Żadne krzesło samo w sobie (musi mieć co najmniej jedno |lub _w rzędzie).

  _________________
 |      _____      |
 |     |     |     |
 |     |     |_____|
 |     |_____
 |___________|


  _^_^_^_^_^_^_^_^_
 <      _ _ _      >
 |     | v v |     |
 <     >     <_ _ _>
 |     |_^_^_  v v
 <_ _ _ _ _ _|
   v v v v v

To jest kod golfowy, więc wygrywa najkrótszy kod.

Tim
źródło
2
Jestem zdezorientowany, dlaczego krzesła są wbudowane w stół z boków?
Optymalizator
Jeśli dobrze pamiętam, twój oryginalny słupek piaskownicy miał odstęp między pionową linią stołu a linią krzesła. Tak jak między poziomymi liniami stołu a krzesłami jest trochę miejsca.
Optymalizator
1
wygląda na to, że krzesła są umieszczone w odległości 1 od siebie, ale otoczenia nie można podzielić przez 2. jak program powinien zacząć rozkładać krzesła. zgodnie z ruchem wskazówek zegara czy przeciwnie do ruchu wskazówek zegara? z prawego górnego rogu, lewego górnego rogu itp.?
1
również myślę, że jest problem w trzeciej próbce - istnieje dodatkowa przestrzeń między drugim a trzecim „górnym” krzesłem - a także w ostatnim przykładzie, prawym dolnym rogu
1
Pierwszy przypadek testowy wydaje się uszkodzony. Dane wejściowe mają tylko 4 szerokości, a dane wyjściowe to 5.
Wheat Wizard

Odpowiedzi:

34

Python 2, 1033 1007 924 879 829 787 713 699 692 691 688 687 672 670 664 659 654 648 643 642 630 625 623 620 570 560 554 545 518 514 513 510 505 492 476 454 451 443 bajtów

6 bajtów zapisanych dzięki Riley

6 bajtów zapisanych dzięki Adnan

Ponieważ to pytanie ma ponad rok i wciąż nie ma odpowiedzi, pomyślałem, że spróbuję.

n,i,o,u="\nI _";R=lambda x:range(1,x-1)
b=open(i).read()
s=b.split(n)
z=max(map(len,s))+3
a=[list(i+x.ljust(z,i))for x in[i]+s+[i]]
for x in R(len(a))*len(b):
 A=a[x];B=a[x+1];C=a[x-1]
 for y in R(z):
    D=A[y-1:y+2];k=B[y];j=A[y+1]
    if(i in[C[y],k]+D+(k==u)*B[y-1:y+2]or"V"==j)&(A[y]==o):A[y]=i
    if"|"==A[y]==C[y]:A[y]={i:"|",j:">",A[y-1]:"<"}[i]
    if[u]*3==D:A[y],B[y]={i:u+k,C[y]:"^"+k,k:" V"}[i]
print n.join(`y`[2::5]for y in a).replace(i,o)

Wypróbuj online!

Program odczytuje tabelę o nazwie pliku Ii drukuje tabelę z krzesłami do std::out. Nie byłam pewna co do kilku skrajnych przypadków, więc dokonałam najlepszej oceny (cokolwiek wymagało najmniejszego wysiłku), ale wydaje się, że zdała wszystkie testy. Niektóre wyjścia nie pasują dokładnie, ale wszystkie mają taką samą liczbę krzeseł.

Wyjaśnienie

Pierwszy wiersz po prostu ustanawia niektóre definicje, które pozwolą nam zaoszczędzić bajty w przyszłości:

(Rozpakuję te makra, aby były czytelne w przyszłych wierszach)

n,i,o="\nI ";R=lambda x:range(1,x-1)

Następnie otworzymy plik o nazwie, Iponieważ mamy już zmienną, która jest krótka, więc zapisuje kilka bajtów.

b=open("I").read().split("\n")

Dzielimy się wzdłuż nowego wiersza, aby utworzyć listę ciągów (wiersze obrazu)

s=b.split(n)

Następnie znajduję długość najdłuższej linii, aby móc dopełnić wszystkie linie do tej długości. (Dodaję również 3, ponieważ potrzebujemy trochę dodatkowego wypełnienia)

 z=max(map(len,s))+3

Następnie wykonujemy rzeczywiste wypełnienie i tworzymy ramkę Iznaków wokół krawędzi. Wynika to z tego, że później będziemy musieli odróżnić wnętrze od zewnętrznej strony kształtu. Zmienimy również typ danych z listy ciągów na listę znaków (długość 1 ciągów).

a=[list("I"+x.ljust(z,"I"))for x in["I"]+s+["I"]]

Następny wiersz to kolejna definicja zapisywania bajtów.

(Rozpakuję również ten)

B=R(len(a))

Teraz chcemy rozprowadzać Ipostacie wszędzie poza kształtem. Możemy to zrobić za pomocą automatu pseudokomórkowego. Każda Izostanie przeniesiona na dowolne sąsiednie postacie. Możemy zapętlać, dopóki automat się nie ustabilizuje, jednak nie może to zająć więcej iteracji niż znaków, więc po prostu zapętlamy każdy znak w b(oryginalne wejście)

for _ in b:

Dla każdej iteracji chcemy pominąć każdy znak na liście 2D (wyłączając najbardziej zewnętrzne dopełnienie)

 for x in range(1,len(a)-1):
    A=a[x]  #<--Another definition I will fill in for clarity
    for y in range(1,z-1):

Dla każdej pozycji uruchamiamy następujący kod:

if("I" in[a[x+1][y],a[x-1][y]]+a[x][y-1:y+2])&(a[x][y]==" "):a[x][y]=" "

Rozbijmy to.

Mamy if z dwoma warunkami oddzielonymi przez &(bitowe and)

Pierwszy sprawdza po prostu, czy jest Iw którejś z sąsiednich komórek, a drugi sprawdza, czy bieżąca komórka to " ". Jeśli spełnimy te warunki, ustawimy bieżącą komórkę na I.


Teraz, gdy ustaliliśmy zewnętrzną i wewnętrzną postać kształtu, możemy zacząć ustawiać krzesła wokół stołu.

Po raz kolejny przeglądamy wszystkie komórki (i ustawiamy więcej skrótów)

for x in range(1,len(a)-1):
 A=a[x]
 for y in range(1,z-1):
        k=a[x+1][y]

Oto moja ulubiona część. Jeśli przeszedłeś przez moje nudne, w większości oparte na definicji golfa, do tej pory nagrodzę cię przyjemnym smakiem sprytnego golfa (jeśli sam to powiem).

Małe tło w pythonie:

W Pythonie, jeśli spróbujesz dwukrotnie przypisać klucz słownika, przypisuje on ten drugi. Na przykład

>>> {1:"a",1:"b"}[1]
'b'

Wykorzystamy tę właściwość, aby przypisać bieżącą komórkę do określonej postaci.

Pierwszy warunek to

if["_"]*3==a[x][y-1:y+2]:a[x][y],a[x+1][y]={"I":"_"+a[x+1][y],a[x-1][y]:"^ ",a[x+1][y]:" V"}["I"]

Jeśli komórka znajduje się pośrodku krawędzi 3 _znaków, ponownie przypisamy bieżącą komórkę i komórkę poniżej niej. Przypiszemy go do wyniku indeksowania przeciążonego słownika według I. Najpierw ustawiamy nasze domyślne ustawienie na parę, "I":"_"+a[x+1][y]co oznacza, że ​​jeśli nie będzie żadnych zmian, przywrócimy pierwotne wartości obu komórek. Następnie dodajemy parę a[x-1][y]:"^ ". Nie zrobi to nic (ważnego), chyba że komórka powyżej bieżącego ( a[x-1][y]) zostanie wypełniona znakiem I. Jeśli ma Iw sobie, zastąpi domyślną, mówiącą nam, abyśmy ustawili krzesło w bieżącej komórce. Następnie przechodzimy do komórki poniżej bieżącej komórki, jeśli ta komórka Iponownie przeskakuje, aby ustawić krzesło skierowane w górę poniżej bieżącego miejsca.

Kolejny warunek jest odrobinę prostszy

if"|"==a[x][y]==a[x-1][y]:a[x][y]={"I":"|",A[y+1]:">",A[y-1]:"<"}["I"]   

Sprawdzamy, czy bieżąca komórka i komórka nad nią są jednocześnie |. Jeśli tak, tworzymy słownik.

Pierwsza para w słowniku "I":"|"ustawia wartość domyślną. Ponieważ uzyskamy dostęp do klucza, Ijeśli Inie zostanie on ponownie przypisany, domyślnie powróci do |(postać, którą już jest) i nic nie zrobi.

Dodajemy dwa klucze. A[y+1]:">",A[y-1]:"<"Jeśli którakolwiek z dwóch komórek po lewej i prawej stronie znajduje się, Iwówczas ponownie przypisze bieżącą komórkę do krzesła wskazującego w kierunku na zewnątrz.


Teraz musimy po prostu wyjść. Jednak nie możemy po prostu drukować, musimy najpierw zrobić kilka czynności porządkowych. Musimy przekonwertować z powrotem na ciąg i usunąć wszystkie Istworzone przez nas s. Odbywa się to w jednej linii.

print "\n".join(`y`[2::5]for y in a).replace("I"," ")
Kreator pszenicy
źródło
Czy nie możesz użyć spacji dla pierwszego poziomu wcięcia, tabulacji dla dwóch, tabulacji i spacji dla trzech? To pozwoli zaoszczędzić kilka bajtów.
Riley,
3
To może być najbardziej golfowa odpowiedź.
Magic Octopus Urn
2
Czy i,o="I "zamiast i="I";o=" "pracy?
Adnan
1
@ErikGolfer ー リ ッ ク ゴ ル フ ァ ーnKoszt 4 bajtów i oszczędza mi 6. Chociaż nie używam go często, oszczędza 2 bajty.
Kreator pszenicy,
1
@ Pietu1998 Dziękujemy za zwrócenie na to uwagi. Rozwiązałem problem
Wheat Wizard