Rovescia un po 'di domino!


22

Grazie a questa domanda per qualche ispirazione

In questa sfida rappresenteremo una linea di domino come una stringa di |, /e \. Ti verrà data una serie di domino come input e dovrai determinare come appaiono quando si sono sistemati. Ecco le regole su come cadono i domino

  • Un domino in piedi |, a sinistra di un domino caduto a sinistra \, diventerà anche un domino caduto a sinistra.

  • Un domino in piedi |, a destra di un domino caduto a destra /, diventerà anche un domino caduto a destra.

  • Se un domino in piedi si trova tra un domino caduto a sinistra \e uno caduto a destra /, rimarrà in piedi.

Queste regole vengono applicate ripetutamente fino a quando l'accordo non cambia più.

Ecco un esempio di come un singolo input potrebbe arrivare alla sua conclusione

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

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

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

Il tuo compito è quello di scrivere il codice che trova e genera il risultato finale di un input. Si può presumere che l'input sia sempre valido e contenga almeno 2 caratteri.

Si tratta di quindi le risposte verranno classificate in byte con un numero inferiore di byte migliori.

Casi test

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

6
Backslash in fuga ahoy! (Possiamo usare altri simboli?)
Arnauld

1
@Arnauld No, dovresti usare le barre.
Wheat Wizard

1
Non riesco ... a capire cosa scappare e cosa no.
totalmente umano il

L'input sarà mai la stringa vuota o un singolo carattere?
Maniglia della porta

3
Mi dà più fastidio di quanto dovrebbe essere considerato stabile come "//////// | \
MooseBoys,

Risposte:


13

Retina , 32 byte

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

Provalo online!

Spiegazione

Il +dice a Retina di eseguire la sostituzione in un ciclo fino a quando non riesce a cambiare la stringa. Ogni sostituzione calcola un passo i domino in caduta. La sostituzione stessa è in realtà tre sostituzioni in una, ma ciò garantisce che avvengano simultaneamente:

(/.\\)...
$1

Questo corrisponde solo /|\(così come /\\e /\\, ma quelli non contano) e lo reinserisce invariato. Lo scopo di questo è di saltare |con i domino caduti su entrambi i lati, perché questo è più breve che escludere quei casi con lookaround separati negli altri due casi.

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

Questo corrisponde /|e lo trasforma in //.

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

Questo corrisponde |\e lo trasforma in \\.


Non posso dire di non averlo visto arrivare. Retina è sicuramente un buon strumento per il lavoro.
Wheat Wizard

@WheatWizard È facile da risolvere, ma probabilmente ancora troppo dettagliato con tutte le fughe e che $1$2$2$3$3per battere le lingue del golf.
Martin Ender,

5

Python 2 , 115 114 111 108 98 95 byte

-1 byte grazie a ovs

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

Provalo online!


114 byte usando le stringhe r.
Ovs,

È possibile rimuovere b=0;e sostituire le occorrenze di bby idper salvare due byte!
Lynn,

4

V , 23 byte

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

Provalo online!

Davvero, questo è molto simile alla risposta della retina, solo che sembra più brutta. Utilizza la compressione regex.

hexdump:

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

Spiegazione:

òdice a V di funzionare fino a quando la stringa non cambia. Il resto è una regex compressa. Convertiamolo in equivalente vim ...

: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 byte

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

Provalo online!

Ringraziamo la risposta del pitone di Rod per l'idea della condizione di arresto con una seconda variabile per vedere i cambiamenti anziché testare 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 byte

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

Provalo online! La prima riga definisce una funzione anonima.

Spiegazione:

  • until=<<((==)=<<)$gè una funzione del punto fisso (vedere qui per una spiegazione) che applica la funzione galla stringa di input fino a quando il risultato non cambia più.
  • zip3('|':s)s(tail s++"|")crea per ogni domino, ovvero carattere nella stringa s, una tripla con il domino precedente e successivo, imbottitura con |ai bordi. Ad esempio /\|diventa [(|,/,\),(/,\,|),(\,|,|)](ignorando la fuga).
  • Quindi la funzione tviene applicata a ciascuna delle triple per calcolare la nuova posizione del pezzo centrale del triplo.


2

Prolog (SWI) , 132 byte

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

Provalo online!

Questo programma definisce un predicato +/2vero se il secondo argomento è la versione stabile del primo. Entrambi gli argomenti sono elenchi di codici carattere.

Spiegazione

Questa soluzione utilizza un DCG per capire qual è il passaggio successivo e quindi calcola ripetutamente il passaggio successivo fino a quando il passaggio successivo è lo stesso del passaggio corrente.

Il DCG

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

Queste cinque righe di codice definiscono una regola DCG (Definite Clause Grammar) +che viene utilizzata nel programma per calcolare un singolo passaggio di rovesciamento di domino. I DCG in Prolog funzionano trovando il primo caso della regola il cui lato destro corrisponde alla stringa e determinando l'argomento della regola sul lato sinistro attraverso quel processo. Se un caso non riesce a corrispondere, tornerà indietro e proverà un caso successivo.

+[]-->[].

Questa riga rappresenta il caso base della +regola. Afferma semplicemente che se non ci sono domino attualmente, nel passaggio successivo non ci saranno ancora domino.

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

Dal momento che questo programma si occupa esclusivamente di liste di codici di carattere, è importante notare che i codici di carattere per /, \e |sono rispettivamente 47, 92 e 124. Questo caso della +regola gestisce la /|\stringa.

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

Questo caso gestisce un domino che cade a destra, rovesciando il domino alla sua destra. Dal momento che viene dopo il caso per la gestione /|\, non verrà utilizzato per tale possibilità.

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

Gestisce il caso di un domino che cade a sinistra rovesciando il domino alla sua sinistra.

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

Questo è il caso jolly. Dal momento che nient'altro cambia oltre a quanto descritto sopra, fintanto che nella stringa di input è rimasto del testo, lo copierà sull'output solo se non corrisponde a nessuno dei casi precedenti.

Il predicato

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

Il predicato principale accetta due argomenti, il primo è la configurazione iniziale del domino, il secondo è il domino risolto. Poiché questo è Prolog, il secondo può essere indeterminato e il programma lo calcolerà. Il predicato in sé e per sé è abbastanza semplice e +(N,X,[])chiama il DCG e calcola il passaggio successivo dei domino in cui è memorizzato N. (X=N,Y=N;N+Y)controlla se il passaggio successivo dei domino è uguale a quello attuale e se è impostato Ysu di esso poiché i domino devono essersi sistemati e se non lo è, ricorre, chiamando lo stesso predicato con il passaggio successivo dei domini Ninvece di X.



1

faccia , 166 byte

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

Prende l'input come argomento della riga di comando e l'output su STDOUT. Funziona solo con commit 86494f6 e oltre a causa di una correzione di bug in quel commit.

Avvolto per l'estetica:

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

E ungolf / commentato:

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

Ci sono alcuni trucchi sottili qui che radono alcuni byte extra, come ad esempio

  • la denominazione delle variabili | e /, i cui valori ASCII sono accessibili tramite introspezione più avanti nel codice

  • il '|sulla prima riga del ciclo principale, che si chiama lì invece che sulla seconda riga per impostare il | puntatore per l'uso nella seconda sezione del ciclo principale


1

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

-6 byte grazie a mik

Probabilmente non è il migliore possibile per Perl, ma è quello che ho potuto inventare.

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

Spiegazione

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
)

Provalo online!


-pinvece di -aeliminare la necessità di print;; l'utilizzo whilecome suffisso di un'espressione fittizia (ad es. 0) salverà altri 2 byte
mik

Grazie @mik, non conoscevo quei trucchi. Mi rendo anche conto che potrei delimitare la regex con qualcos'altro per salvare alcuni byte. Potrei arrivare più tardi.
Geoffrey H.

1

Perl 5 , 44 (codice) + 1 ( -p) = 45 byte

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

Provalo online!

Spiegazione

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

Rubino , 83 byte

Tecnicamente economico con 9.times , o anche solo, 999.timesma non mi sento di essere economico :)

Ha ancora un enorme potenziale di golf. (Nota: y while undoneè molto più lungo di x.size.times)

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

Provalo online!


0

R , 114 byte

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

Provalo online!

Restituisce una stringa con escape.


0

C (gcc) , 183 byte

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));}

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.