Tumbangkan beberapa kartu domino!


22

Berkat pertanyaan ini untuk inspirasi

Dalam tantangan ini kami akan mewakili garis domino sebagai string |, /dan \. Anda akan diberikan serangkaian kartu domino sebagai input dan Anda harus menentukan seperti apa bentuknya ketika sudah selesai. Berikut adalah aturan bagaimana domino jatuh

  • Domino berdiri |, kiri dari domino jatuh kiri \, juga akan menjadi domino jatuh kiri.

  • Domino berdiri |,, hak domino jatuh kanan /, juga akan menjadi domino jatuh kanan.

  • Jika domino berdiri berada di antara jatuh kiri \dan /domino jatuh kanan , itu akan tetap berdiri.

Aturan-aturan ini diterapkan berulang kali hingga pengaturannya tidak lagi berubah.

Berikut adalah contoh bagaimana satu input mungkin sampai pada kesimpulannya

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

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

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

Tugas Anda adalah menulis kode yang menemukan dan mengeluarkan hasil akhir dari suatu input. Anda dapat mengasumsikan bahwa input selalu valid dan mengandung setidaknya 2 karakter.

Ini adalah sehingga jawaban akan dicetak dalam byte dengan lebih sedikit byte yang lebih baik.

Uji kasus

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

6
Backslash lolos ahoy! (Bolehkah kita menggunakan simbol lain?)
Arnauld

1
@Arnauld Tidak, Anda harus menggunakan garis miring.
Wheat Wizard

1
Saya tidak bisa ... mencari tahu apa yang harus dihindari dan apa yang tidak.
manusiawi

Apakah input akan berupa string kosong atau karakter tunggal?
Gagang Pintu

3
Itu menggangguku lebih daripada seharusnya hal-hal seperti `//////// | \ dianggap stabil.
MooseBoys

Jawaban:


13

Retina , 32 byte

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

Cobalah online!

Penjelasan

The +memberitahu Retina untuk menjalankan penggantian dalam satu lingkaran sampai gagal mengubah string. Setiap penggantian menghitung satu langkah domino yang jatuh. Penggantian itu sendiri sebenarnya adalah tiga penggantian dalam satu, tetapi ini memastikan bahwa mereka terjadi secara bersamaan:

(/.\\)...
$1

Hanya pertandingan ini /|\(serta /\\dan /\\, tetapi mereka tidak peduli) dan reinserts itu tidak berubah. Tujuan dari ini adalah untuk melompati |dengan domino yang jatuh di kedua sisi, karena ini lebih pendek daripada mengesampingkan kasus-kasus dengan lookaround terpisah dalam dua kasus lainnya.

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

Ini cocok /|dan mengubahnya menjadi //.

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

Ini cocok |\dan mengubahnya menjadi \\.


Tidak bisa mengatakan saya tidak melihat itu datang. Retina tentu saja merupakan alat yang baik untuk pekerjaan itu.
Wheat Wizard

@WheatWizard Sangat mudah untuk dipecahkan, tetapi mungkin masih terlalu bertele-tele dengan semua pelarian dan $1$2$2$3$3untuk mengalahkan bahasa-bahasa golf.
Martin Ender

5

Python 2 , 115 114 111 108 98 95 byte

-1 byte berkat ovs

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

Cobalah online!


114 byte menggunakan r-string.
Ov

Anda dapat menghapus b=0;dan mengganti kemunculan boleh iduntuk menghemat dua byte!
Lynn

4

V , 23 byte

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

Cobalah online!

Sungguh, ini sangat mirip dengan jawaban retina, hanya saja tampilannya lebih jelek. Menggunakan kompresi regex.

Hexdump:

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

Penjelasan:

òmemberitahu V untuk menjalankan sampai string tidak berubah. Sisanya adalah regex terkompresi. Mari kita mengonversinya menjadi setara dengan 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

Cobalah online!

Kredit untuk jawaban python Rod untuk ide untuk kondisi berhenti dengan variabel kedua untuk melihat perubahan daripada pengujian 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

Cobalah online! Baris pertama mendefinisikan fungsi anonim.

Penjelasan:

  • until=<<((==)=<<)$gadalah fungsi titik perbaikan (lihat di sini untuk penjelasan) yang menerapkan fungsi gke string input hingga hasilnya tidak lagi berubah.
  • zip3('|':s)s(tail s++"|")menciptakan untuk setiap domino, yaitu karakter dalam string s, triple dengan domino pra dan sukses, padding dengan |di tepi. Misalnya /\|menjadi [(|,/,\),(/,\,|),(\,|,|)](mengabaikan melarikan diri).
  • Kemudian fungsi tditerapkan ke masing-masing tiga kali lipat untuk menghitung posisi baru bagian tengah rangkap tiga.


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).

Cobalah online!

Program ini mendefinisikan predikat +/2yang benar jika argumen kedua adalah versi menetap dari yang pertama. Kedua argumen adalah daftar kode karakter.

Penjelasan

Solusi ini menggunakan DCG untuk mencari tahu apa langkah selanjutnya dan kemudian berulang kali menghitung langkah berikutnya sampai langkah selanjutnya sama dengan langkah saat ini.

DCG

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

Kelima baris kode ini mendefinisikan aturan DCG (Definite Clause Grammar) +yang digunakan dalam program untuk menghitung satu langkah pengguluhan domino. DCG dalam Prolog bekerja dengan menemukan kasus pertama dari aturan yang sisi kanannya cocok dengan string dan menentukan argumen aturan di sisi kiri melalui proses itu. Jika suatu kasus gagal untuk mencocokkan maka ia akan mundur dan mencoba kasus berikutnya.

+[]-->[].

Baris ini mewakili kasus dasar +aturan. Ini hanya menyatakan bahwa jika tidak ada domino saat ini maka pada langkah berikutnya masih akan ada domino.

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

Sejak program ini berurusan secara eksklusif dengan daftar kode karakter penting untuk dicatat bahwa kode karakter untuk /, \, dan |adalah 47, 92, dan 124 masing-masing. Kasus +aturan ini menangani /|\string.

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

Kasing ini menangani kartu domino yang jatuh tepat di atas kartu domino. Karena itu datang setelah kasus untuk penanganan /|\itu tidak akan digunakan untuk kemungkinan itu.

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

Menangani kasing untuk domino jatuh yang jatuh yang menabrak domino di sebelah kiri itu.

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

Ini adalah kasus wildcard. Karena tidak ada yang berubah selain apa yang dijelaskan di atas, selama ada teks yang tersisa di string input, maka hanya akan menyalinnya ke output selama tidak cocok dengan kasus-kasus di atas.

Predikatnya

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

Predikat utama mengambil dua argumen, yang pertama adalah pengaturan domino awal, yang kedua adalah domino menetap. Karena ini adalah Prolog yang kedua dapat ditentukan dan program akan menghitungnya. Predikat di dalam dan dari dirinya sendiri adalah +(N,X,[])panggilan yang cukup sederhana DCG dan menghitung langkah selanjutnya dari domino yang menyimpannya N. (X=N,Y=N;N+Y)memeriksa apakah langkah berikutnya dari kartu domino adalah sama dengan arus dan jika diset Yuntuk itu karena kartu domino pasti telah menetap dan jika tidak berulang, panggil predikat yang sama dengan langkah selanjutnya dari kartu domino Nalih-alih X.



1

wajah , 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*>

Mengambil input sebagai argumen baris perintah dan output ke STDOUT. Ini hanya berfungsi di commit 86494f6 dan seterusnya karena perbaikan bug di komit itu.

Dibungkus untuk estetika:

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

Dan ungolfed / berkomentar:

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

Ada beberapa trik halus di sini yang mengurangi beberapa byte tambahan, seperti

  • penamaan variabel | dan /, yang nilai ASCII-nya diakses melalui introspeksi kemudian dalam kode

  • yang '|pada baris pertama dari loop utama, yang disebut sana bukannya pada baris kedua untuk mengatur | pointer untuk digunakan di bagian kedua dari loop utama


1

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

-6 byte terima kasih kepada mik

Mungkin bukan yang terbaik untuk Perl, tapi itulah yang bisa saya lakukan.

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

Penjelasan

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
)

Cobalah online!


-pbukannya -amenghilangkan kebutuhan untuk print;; menggunakan whilesebagai akhiran ke ekspresi dummy (mis. 0) akan menghemat 2 byte lagi
mik

Terima kasih @mik, saya tidak tahu trik itu. Saya juga menyadari bahwa saya dapat membatasi regex dengan sesuatu yang lain untuk menghemat beberapa byte. Mungkin sampai nanti.
Geoffrey H.

1

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

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

Cobalah online!

Penjelasan

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 byte

Secara teknis curang dengan 9.times, atau bahkan hanya 999.timestetapi saya tidak merasa seperti murah :)

Masih memiliki potensi bermain golf yang sangat besar. (Catatan: y while undonejauh lebih lama dari x.size.times)

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

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

Cobalah online!

Mengembalikan string yang lolos.


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

Cobalah online!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.