Obal domino!

22

Dzięki temu pytaniu o inspirację

W tym starciu będziemy reprezentować linię domina jako ciąg |, /a \. Otrzymasz ciąg domino jako dane wejściowe i musisz określić, jak będą wyglądać, gdy się osiedlą. Oto zasady upadku domina

  • Domino stojące |, na lewo od domina upadłego po lewej \, stanie się również domino upadłym po lewej stronie.

  • Domino stojące |, na prawo od domina upadłego /, również stanie się domino upadłym.

  • Jeśli domino stojące znajduje się między lewą, \a prawą, /domino, pozostanie w pozycji stojącej.

Reguły te są stosowane wielokrotnie, dopóki układ się nie zmieni.

Oto przykład, w jaki sposób jedno wejście może dojść do wniosku

|||||||\/|||||||\||\|||/||||||\|||||

||||||\\//|||||\\|\\|||//||||\\|||||
|||||\\\///|||\\\\\\|||///||\\\|||||
||||\\\\////|\\\\\\\|||////\\\\|||||
|||\\\\\////|\\\\\\\|||////\\\\|||||
||\\\\\\////|\\\\\\\|||////\\\\|||||
|\\\\\\\////|\\\\\\\|||////\\\\|||||

\\\\\\\\////|\\\\\\\|||////\\\\|||||

Twoim zadaniem jest napisanie kodu, który znajdzie i wyprowadzi końcowy wynik danych wejściowych. Możesz założyć, że dane wejściowe są zawsze prawidłowe i zawierają co najmniej 2 znaki.

To jest więc odpowiedzi będą liczone w bajtach, przy czym mniej bajtów będzie lepszych.

Przypadki testowe

|||/||||  -> |||/////
|||\||||  -> \\\\||||
|/||||\|  -> |///\\\|
||/|||\|  -> ||//|\\|
||\|||/|  -> \\\|||//
Kreator pszenicy
źródło
6
Ukośnik ucieka ahoy! (Czy możemy użyć innych symboli?)
Arnauld
1
@Arnauld Nie, powinieneś używać ukośników.
Wheat Wizard
1
Nie mogę ... dowiedzieć się, co uciec, a czego nie.
całkowicieludzki
Czy wejście będzie kiedykolwiek pustym łańcuchem lub pojedynczym znakiem?
Klamka
3
Niepokoi mnie bardziej niż to, że rzeczy takie jak `//////// | \ są uważane za stabilne.
MooseBoys

Odpowiedzi:

13

Siatkówka , 32 bajty

+`(/.\\)|(/)\||\|(\\)
$1$2$2$3$3

Wypróbuj online!

Wyjaśnienie

+Mówi Retina uruchomić wymianę w pętli, dopóki nie uda się zmienić ciąg. Każda wymiana oblicza jeden krok spadających domino. Sam zamiennik to tak naprawdę trzy zamienniki w jednym, ale zapewnia to, że są one wykonywane jednocześnie:

(/.\\)...
$1

To po prostu pasuje /|\(jak /\\i /\\, ale te nie mają znaczenia) i ponownie wprowadza je bez zmian. Ma to na celu ominięcie |upadłych domino po obu stronach, ponieważ jest to krótsze niż wykluczenie tych przypadków z osobnymi opisami w pozostałych dwóch przypadkach.

...(/)\|...
$2$2

To pasuje /|i zamienia to w //.

...\|(\\)
$3$3

To pasuje |\i zamienia to w \\.

Martin Ender
źródło
Nie mogę powiedzieć, że tego nie widziałem. Siatkówka jest z pewnością dobrym narzędziem do pracy.
Wheat Wizard
@WheatWizard Jest łatwy do rozwiązania, ale prawdopodobnie wciąż zbyt gadatliwy wobec wszystkich uciekinierów i $1$2$2$3$3aby pokonać języki gry w golfa.
Martin Ender,
5

Python 2 , 115 114 111 108 98 95 bajtów

-1 bajt dzięki ovs

a=input()
for i in range(4)*len(a):a=a.replace('//|x||\ \\'[i::4],'/\/x|\/ \\'[3-i::4])
print a

Wypróbuj online!

Pręt
źródło
114 bajtów przy użyciu ciągów-r.
ovs
Możesz usunąć b=0;i zastąpić wystąpienia bby, idaby zapisać dwa bajty!
Lynn
4

V , 23 bajty

òÓ¯À<!|¨Ü©ü¨¯©|ÜÀ!/±±²²

Wypróbuj online!

Naprawdę jest to bardzo podobne do odpowiedzi na siatkówkę, tylko że wygląda brzydiej. Wykorzystuje kompresję wyrażeń regularnych.

Hexdump:

00000000: f2d3 afc0 3c21 7ca8 dca9 fca8 afa9 7cdc  ....<!|.......|.
00000010: c021 2fb1 b1b2 b2                        .!/....

Wyjaśnienie:

òkaże V działać, dopóki łańcuch się nie zmieni. Reszta to skompresowane wyrażenie regularne. Przekształćmy go w ekwiwalent vima ...

:s/\v\/@<!\|(\\)|(\/)\|\\@!/\1\1\2\2/g

:s/                                     " Substitute...
   \v                                   " Turn on magic (use less escaping)
          \|                            " A bar
            (\\)                        " Followed by a captured backslash
       @<!                              " That is not preceded by
     \/                                 " A forward slash
                |                       " OR...
                 (\/)                   " A captured forward slash
                     \|                 " Followed by a bar
                       \\@!             " That is not followed by a backslash
                           /            " Replace this with
                            \1\1        " Pattern 1 twice (will be empty if we matched the second path)
                                \2\2    " Pattern 2 twice (will be empty if we matched the first path)
                                    /g  " Replace every match on this line
DJMcMayhem
źródło
4

SNOBOL4 (CSNOBOL4) , 117 115 112 111 bajtów

	D =INPUT
S	D '/|\' ='_'	:S(S)
	E =D
	D '/|' ='//'
	D '|\' ='\\'
	D E	:F(S)
R	D '_' ='/|\'	:S(R)
	OUTPUT =D
END

Wypróbuj online!

Kredyt dla Roda Pythona odpowiedź na pomysł na zatrzymanie stanie z drugiej zmiennej, aby zobaczyć zmiany, zamiast testów D '/|' | '|\'.

	D =INPUT		;* read input
S	D '/|\' ='_'	:S(S)	;* replace '/|\' with '_', recursively
	E =D			;* set E to D, this is the while loop
	D '/|' ='//'		;* topple right
	D '|\' ='\\'		;* topple left
	D E	:F(S)		;* if D doesn't match E, goto S
R	D '_' ='/|\'	:S(R)	;* replace '_' with '/|\' (inverse of statement S)
	OUTPUT =D		;* output
END
Giuseppe
źródło
3

Haskell , 114 107 bajtów

until=<<((==)=<<)$g
g s=t<$>zip3('|':s)s(tail s++"|")
t(l,'|',r)|l<'0',r/='\\'=l|r=='\\',l>'/'=r
t(_,e,_)=e

Wypróbuj online!Pierwszy wiersz definiuje anonimową funkcję.

Wyjaśnienie:

  • until=<<((==)=<<)$gjest funkcją punkt fix (patrz tutaj o wyjaśnienie), który stosuje się funkcję gdo ciągu wejściowego aż wynik nie zmienia już.
  • zip3('|':s)s(tail s++"|")tworzy dla każdego domina, czyli znaku w ciągu s, trzykrotnie z domino przed i po nim, wypełnienie |na krawędziach. Np. /\|Staje się [(|,/,\),(/,\,|),(\,|,|)](ignorując ucieczkę).
  • Następnie funkcja tjest stosowana do każdej z trzech potrójnych w celu obliczenia nowej pozycji środkowego elementu potrójnego.
Laikoni
źródło
2

Perl 5 , 39 + 1 ( -p) = 40 bajtów

s%(?<!/)\|(\\)|(/)\|(?!\\)%$+$+%g&&redo

Wypróbuj online!

Xcali
źródło
2

Prolog (SWI) , 132 bajty

+[]-->[].
+[47,124,92|T]-->"/|\\",+T.
+[47,47|T]-->"/|",+T.
+[92,92|T]-->"|\\",+T.
+[X|T]-->[X],+T.
X+Y:- +(N,X,[]),!,(X=N,Y=N;N+Y).

Wypróbuj online!

Ten program określa predykat, +/2który jest prawdziwy, jeśli drugi argument jest ustaloną wersją pierwszego. Oba argumenty są listami kodów znaków.

Wyjaśnienie

To rozwiązanie wykorzystuje DCG, aby dowiedzieć się, jaki jest następny krok, a następnie wielokrotnie oblicza następny krok, aż następny krok będzie taki sam jak bieżący krok.

DCG

+[]-->[].
+[47,124,92|T]-->"/|\\",+T.
+[47,47|T]-->"/|",+T.
+[92,92|T]-->"|\\",+T.
+[X|T]-->[X],+T.

Te pięć wierszy kodu definiuje regułę DCG (gramatyka klauzuli określonej), +która jest używana w programie do obliczania pojedynczego kroku obalenia domina. DCG w Prologu pracują, znajdując pierwszy przypadek reguły, której prawa strona pasuje do ciągu i określając argument reguły po lewej stronie w tym procesie. Jeśli sprawa się nie zgadza, cofnie się i spróbuje później.

+[]-->[].

Ta linia reprezentuje podstawowy przypadek +reguły. Po prostu stwierdza, że ​​jeśli obecnie nie ma domino, w następnym kroku nadal nie będzie domino.

+[47,124,92|T]-->"/|\\",+T.

Ponieważ program ten dotyczy wyłącznie listami kodów znakowych ważne jest, aby pamiętać, że kody dla znaków /, \i |są 47, 92, i 124 odpowiednio. Ten przypadek +reguły obsługuje /|\ciąg znaków.

+[47,47|T]-->"/|",+T.

Ta obudowa obsługuje przewrócone domino przewracające domino po jego prawej stronie. Ponieważ pojawia się po skrzynce do obsługi /|\, nie zostanie wykorzystana do tej możliwości.

+[92,92|T]-->"|\\",+T.

Obsługuje skrzynkę domina przewracającego się po lewej stronie, przewracając domino po jego lewej stronie.

+[X|T]-->[X],+T.

To jest przypadek wieloznaczny. Ponieważ nic innego się nie zmienia poza tym, co opisano powyżej, dopóki tekst pozostanie w ciągu wejściowym, po prostu skopiuje go na wyjście, o ile nie pasuje do żadnego z powyższych przypadków.

Predykat

X+Y:- +(N,X,[]),!,(X=N,Y=N;N+Y).

Główny predykat przyjmuje dwa argumenty, pierwszy to wstępna konfiguracja domina, drugi to ustalone domino. Ponieważ jest to Prolog, nie można ustalić drugiego, a program go obliczy. Predykat sam w sobie jest dość prosty, +(N,X,[])wywołuje DCG i oblicza następny etap przechowywania w domino N. (X=N,Y=N;N+Y)sprawdza, czy następny krok domina jest taki sam jak bieżący i czy jest Yustawiony, ponieważ domina musiała się ustabilizować, a jeśli nie, to powtarza się, wywołując ten sam predykat z następnym krokiem domino Nzamiast X.

0 '
źródło
1

twarz , 166 bajtów

\|/,cm_/o>AvI[IIcP/+PP|m_/m*/Sl*Im1/11:~-_I|'|?_1-_P|?_1`I-III_|+II|'I.C:1-_I|?_C'|-_P|?_C_|'I-_I|`I?_!'I.C:!'|'|-III+II|'I:C_|-PPP+PPI'I?I~_I-PPP+PP|-**1?*~Sl*Iw*I*>

Pobiera dane wejściowe jako argument wiersza poleceń i wysyła do STDOUT. Działa to tylko w zatwierdzeniu 86494f6 i późniejszych z powodu poprawki błędu w tym zatwierdzeniu.

Opakowane dla estetyki:

\|/,cm_/o>AvI[IIcP/+PP|m_/m*/Sl*Im1/11:~-_I|'|?_1-_P|?_1`I
-III_|+II|'I.C:1-_I|?_C'|-_P|?_C_|'I-_I|`I?_!'I.C:!'|'|-III
+II|'I:C_|-PPP+PPI'I?I~_I-PPP+PP|-**1?*~Sl*Iw*I*>

I nieprzyznany / skomentował:

\|/,cm_/o>              ( setup )

AvI[II                  ( store input into I )
cP/+PP|m_/              ( store 92, ascii for \, into P, meaning prev char )
m*/Sl*Im1/11            ( store length of input into counter variable * )

( main loop: )
:~

    -_I|'|?_1           ( branch to 1 if the character is not \ )
    -_P|?_1             ( also branch to 1 if the previous character wasn't | )
    `I-III_|+II|'I      ( we have a sequence |\ so prev needs to be toppled )
    .C                  ( jump to C, the "continue" label at end of loop )

    :1
    -_I|?_C             ( branch to C if the character is not | )
    '|-_P|?_C           ( also branch to C if the previous character wasn't / )
    _|'I-_I|`I?_!       ( branch to ! if the next character isn't \ )
    'I.C:!              ( otherwise, skip the next \ and branch to continue )
    '|'|-III+II|'I      ( if all conditions hold we have /|| or /|/ so topple )

    :C
    _|                  ( reset pointer to source )
    -PPP+PPI            ( update prev variable )
    'I                  ( step through data )

?I~

_I-PPP+PP|-**1          ( reset input/prev and decrement counter )
?*~                     ( repeat main loop as many times as there are chars )

Sl*Iw*I*>               ( output final string to stdout )

Jest tu kilka subtelnych sztuczek, które usuwają kilka dodatkowych bajtów, takich jak

  • nazewnictwo zmiennych | i /, do których wartości ASCII są dostępne poprzez introspekcję w dalszej części kodu

  • w '|pierwszym wierszu głównej pętli, który jest tam wywoływany zamiast w drugim wierszu w celu ustawienia | wskaźnik do użycia w drugiej części głównej pętli

Klamka
źródło
1

Perl 5 , 52 + 1 (-p) = 53 bajty

-6 bajtów dzięki mik

Prawdopodobnie nie najlepszy z możliwych dla Perla, ale to właśnie mogłem wymyślić.

0while(s/(?<!\/)\|(?=(\\))|(?<=(\/))\|(?!\\)/$1$2/g)

Wyjaśnienie

while(
  s/
    (?<!\/)\|(?=(//)) # If there's a | that precedes a \ but doesn't follow a /, capture /
      | # Or
    (?<=(\/))\|(?!//)/ # If there's a | that follows a / doesn't precede a \, capture /
  /$1$2/ # Replace all | with capture group 1 or 2, as one of the two will always be empty
  g # Repeat as much as possible for this string
)

Wypróbuj online!

Geoffrey H.
źródło
-pzamiast -aeliminuje potrzebę print;; użycie whilesufiksu do wyrażenia fikcyjnego (np. 0) pozwoli zaoszczędzić kolejne 2 bajty
mik
Dziękuję @mik, nie znałem tych sztuczek. Zdaję sobie również sprawę, że mogę ograniczyć wyrażenie regularne czymś innym, aby zaoszczędzić trochę bajtów. Może do tego dojdzie później.
Geoffrey H.
1

Perl 5 , 44 (kod) + 1 ( -p) = 45 bajtów

1while s,(/)\|(?!\\)|(?<!/)\|(\\),$1$1$2$2,g

Wypróbuj online!

Wyjaśnienie

1while s,                        ,        ,g   while anything found substitute globally
         (/)\|(?!\\)              $1$1         /| that is not followed by \ to //
                    |                          or
                     (?<!/)\|(\\)     $2$2     |\ that is not preceded by / to \\
mik
źródło
1

Czysty , 98 bajtów

import StdEnv
$['/|':t]=['//': $t]
$['|\\':t]=['\\\\': $t]
$[h:t]=[h: $t]
$e=e
f=until(\e=e== $e)$

Wypróbuj online!

Obrzydliwe
źródło
0

Rubinowy , 83 bajty

Technicznie do oszukania 9.times, a nawet po prostu, 999.timesale nie mam ochoty być tani :)

Nadal ma ogromny potencjał golfowy. (Uwaga: y while undonejest znacznie dłuższy niż x.size.times)

->x{x.size.times{x.gsub! /\/\|\\?|\|\\/,'/|\\'=>'/|\\','/|'=>'//','|\\'=>'\\\\'}
x}

Wypróbuj online!

Unihedron
źródło
0

R , 114 bajtów

function(d){g=gsub
for(i in 1:nchar(d))d=g("/|","//",g("|\\","\\\\",g("/|\\","_",d,f=T),f=T),f=T)
g("_","/|\\",d)}

Wypróbuj online!

Zwraca łańcuch znaków ucieczki.

Giuseppe
źródło
0

C (gcc) , 183 bajtów

D,i;f(char*S){char*s=malloc(-~strlen(S));for(D=1;D--;strcpy(S,s))for(strcpy(s,S),i=0;s[i];i++)s[i]>92&&(S[-~i]==92&&S[~-i]!=47&&(s[i]=92,D=1)||S[~-i]==47&&S[-~i]!=92&&(s[i]=47,D=1));}

Wypróbuj online!

Jonathan Frech
źródło