Stürze ein paar Dominosteine!


22

Dank dieser Frage für einige Inspiration

In dieser Herausforderung werden wir eine Reihe von Dominosteinen als eine Kette von darstellen |, /und \. Sie erhalten eine Reihe von Dominosteinen als Eingabe und müssen bestimmen, wie sie aussehen, wenn sie sich eingelebt haben. Hier sind die Regeln, wie Dominosteine ​​umfallen

  • Ein stehender Domino, |links von einem linken gefallenen Domino \, wird ebenfalls zu einem linken gefallenen Domino.

  • Ein stehender Domino, |rechts von einem rechts gefallenen Domino /, wird ebenfalls zu einem rechts gefallenen Domino.

  • Befindet sich ein stehender Domino zwischen einem links \und einem rechts gefallenen /Domino, bleibt er stehen.

Diese Regeln werden so oft angewendet, bis sich die Anordnung nicht mehr ändert.

Hier ist ein Beispiel, wie eine einzelne Eingabe zu ihrem Abschluss gelangen kann

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

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

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

Ihre Aufgabe ist es, Code zu schreiben, der das Endergebnis einer Eingabe findet und ausgibt. Sie können davon ausgehen, dass die Eingabe immer gültig ist und mindestens 2 Zeichen enthält.

Dies ist daher werden die Antworten in Bytes bewertet, wobei weniger Bytes besser sind.

Testfälle

|||/||||  -> |||/////
|||\||||  -> \\\\||||
|/||||\|  -> |///\\\|
||/|||\|  -> ||//|\\|
||\|||/|  -> \\\|||//

6
Backslash entgeht ahoi! (Dürfen wir andere Symbole verwenden?)
Arnauld

1
@Arnauld Nein, du solltest die Schrägstriche verwenden.
Wheat Wizard

1
Ich kann nicht ... herausfinden, was ich entkommen soll und was nicht.
totalhuman

Wird die Eingabe jemals eine leere Zeichenfolge oder ein einzelnes Zeichen sein?
Türklinke

3
Es stört mich mehr als es sollte, dass Dinge wie "//////// |" als stabil gelten.
MooseBoys

Antworten:


13

Retina , 32 Bytes

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

Probieren Sie es online!

Erläuterung

Das +weist Retina an, die Ersetzung in einer Schleife auszuführen, bis die Zeichenfolge nicht mehr geändert werden kann. Jeder Ersatz berechnet einen Schritt die fallenden Dominosteine. Die Ersetzung selbst besteht eigentlich aus drei Ersetzungen in einer, dies stellt jedoch sicher, dass sie gleichzeitig erfolgen:

(/.\\)...
$1

Dies stimmt einfach überein /|\(ebenso wie /\\und /\\, aber diese spielen keine Rolle) und fügt es unverändert wieder ein. Der Zweck ist, |mit gefallenen Dominosteinen auf beiden Seiten zu überspringen , da dies kürzer ist, als diese Fälle mit separaten Lookarounds in den anderen beiden Fällen auszuschließen.

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

Das passt /|und macht es zu //.

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

Das passt |\und macht es zu \\.


Ich kann nicht sagen, dass ich das nicht kommen sah. Retina ist sicherlich ein gutes Werkzeug für den Job.
Wheat Wizard

@ WheatWizard Es ist leicht zu lösen, aber wahrscheinlich immer noch zu wortreich mit all dem Entkommen und dem $1$2$2$3$3, um die Golfsprachen zu schlagen.
Martin Ender


4

V , 23 Bytes

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

Probieren Sie es online!

Wirklich, das ist der Retina-Antwort sehr ähnlich, nur dass es hässlicher aussieht. Verwendet Regex-Komprimierung.

Hexdump:

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

Erläuterung:

òWeist V an, so lange zu laufen, bis sich die Zeichenfolge nicht mehr ändert. Der Rest ist ein komprimierter regulärer Ausdruck. Lassen Sie es uns in das VIM-Äquivalent umwandeln ...

: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

4

SNOBOL4 (CSNOBOL4) , 117 115 112 111 Bytes

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

Probieren Sie es online!

Dank an Rods Python-Antwort für die Idee, die Stoppbedingung mit einer zweiten Variablen zu versehen, um Änderungen zu erkennen, anstatt sie zu testen 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

3

Haskell , 114 107 Bytes

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

Probieren Sie es online! Die erste Zeile definiert eine anonyme Funktion.

Erläuterung:

  • until=<<((==)=<<)$gist eine Fixpunktfunktion (siehe hier für eine Erklärung), die die Funktion gauf die Eingabezeichenfolge anwendet, bis sich das Ergebnis nicht mehr ändert.
  • zip3('|':s)s(tail s++"|")Erstellt für jedes Domino, dh Zeichen in der Zeichenfolge s, ein Triple mit dem vor- und nachgeordneten Domino, das |an den Rändern mit Auffüllelementen versehen ist. ZB /\|wird [(|,/,\),(/,\,|),(\,|,|)](Flucht ignorieren).
  • Dann wird die Funktion tauf jedes der Tripel angewendet, um die neue Position des Mittelstücks des Tripels zu berechnen.


2

Prolog (SWI) , 132 Bytes

+[]-->[].
+[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).

Probieren Sie es online!

Dieses Programm definiert ein Prädikat +/2, das wahr ist, wenn das zweite Argument die festgelegte Version des ersten ist. Beide Argumente sind Listen von Zeichencodes.

Erläuterung

Diese Lösung verwendet ein DCG, um herauszufinden, was der nächste Schritt ist, und berechnet dann wiederholt den nächsten Schritt, bis der nächste Schritt mit dem aktuellen Schritt identisch ist.

Das DCG

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

Diese fünf Codezeilen definieren eine DCG-Regel (Definite Clause Grammar) +, die im Programm zum Berechnen eines einzelnen Domino-Sturzschritts verwendet wird. DCGs in Prolog arbeiten, indem sie den ersten Fall der Regel finden, dessen rechte Seite mit der Zeichenfolge übereinstimmt, und das Argument der Regel auf der linken Seite durch diesen Prozess bestimmen. Wenn ein Fall nicht übereinstimmt, wird er zurückverfolgt und es mit einem späteren Fall versucht.

+[]-->[].

Diese Linie stellt den Basisfall der +Regel dar. Es wird lediglich angegeben, dass im nächsten Schritt, wenn derzeit keine Dominosteine ​​vorhanden sind, immer noch keine Dominosteine ​​vorhanden sind.

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

Da dieses Programm ausschließlich mit Listen von Zeichencodes befasst , ist es wichtig , die Zeichencodes für zu beachten , dass /, \und |sind 47, 92 und 124 jeweils. Dieser Fall der +Regel behandelt die /|\Zeichenfolge.

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

Dieser Fall behandelt einen rechts fallenden Domino, der rechts über den Domino stößt. Da es nach dem Fall für die Handhabung kommt /|\, wird es für diese Möglichkeit nicht verwendet.

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

Behandelt den Fall eines links fallenden Dominos, der über den Domino links davon stößt.

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

Dies ist der Wildcard-Fall. Da sich nichts anderes ändert als das, was oben beschrieben wurde, wird der Text, solange er in der Eingabezeichenfolge verbleibt, nur in die Ausgabe kopiert, solange er keinem der oben genannten Fälle entspricht.

Das Prädikat

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

Das Hauptprädikat benötigt zwei Argumente, das erste ist das anfängliche Domino-Setup, das zweite sind die erledigten Dominos. Da dies ein Prolog ist, kann der zweite unbestimmt sein, und das Programm berechnet ihn. Das Prädikat an und für sich ist ziemlich einfach, +(N,X,[])ruft das DCG auf und berechnet den nächsten Schritt der Dominosteine, in denen es gespeichert wird N. (X=N,Y=N;N+Y)prüft, ob der nächste Schritt der Dominosteine ​​mit dem aktuellen Schritt identisch ist und ob er auf diesen eingestellt ist Y, da sich die Dominosteine ​​abgesetzt haben müssen. Wenn dies nicht der Fall ist, wird das gleiche Prädikat beim nächsten Schritt der Dominosteine Nanstelle von aufgerufen X.



1

Gesicht , 166 Bytes

\|/,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*>

Nimmt Eingaben als Befehlszeilenargument und gibt sie an STDOUT aus. Dies funktioniert nur in Commit 86494f6 und höher, da ein Fehler in diesem Commit behoben wurde.

Eingewickelt für die Ästhetik:

\|/,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*>

Und ungolfed / kommentiert:

\|/,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 )

Es gibt ein paar subtile Tricks, die ein paar zusätzliche Bytes abschneiden, wie z

  • die Benennung der Variablen | und /, auf deren ASCII-Werte später im Code per Introspection zugegriffen wird

  • die '|in der ersten Zeile der Hauptschleife, die dort statt in der zweiten Zeile aufgerufen wird, um die | einzustellen Zeiger zur Verwendung im zweiten Abschnitt der Hauptschleife


1

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

-6 bytes dank mik

Wahrscheinlich nicht das bestmögliche für Perl, aber es ist das, was ich mir einfallen lassen könnte.

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

Erläuterung

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
)

Probieren Sie es online!


-panstatt -aunnötig zu machen print;; durch die Verwendung whileeines Dummy-Ausdrucks als Suffix (z. B. 0) werden weitere 2 Byte
gespeichert

Danke @mik, ich kannte diese Tricks nicht. Mir ist auch klar, dass ich den regulären Ausdruck mit etwas anderem eingrenzen könnte, um einige Bytes zu sparen. Könnte später dazu kommen.
Geoffrey H.

1

Perl 5 , 44 (Code) + 1 ( -p) = 45 Bytes

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

Probieren Sie es online!

Erläuterung

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


0

Ruby , 83 Bytes

Technisch schummelbar mit 9.times, oder auch nur, 999.timesaber ich fühle mich nicht billig :)

Hat noch riesiges Golfpotential. (Hinweis: y while undoneist weit länger als x.size.times)

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

Probieren Sie es online!


0

R , 114 Bytes

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

Probieren Sie es online!

Gibt eine mit Escapezeichen versehene Zeichenfolge zurück.


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.