Topple một số domino!


22

Nhờ câu hỏi này cho một số cảm hứng

Trong thử thách này, chúng tôi sẽ đại diện cho một dòng domino như một chuỗi |, /\. Bạn sẽ được cung cấp một chuỗi domino làm đầu vào và bạn phải xác định chúng trông như thế nào khi chúng đã ổn định. Dưới đây là các quy tắc về cách domino rơi xuống

  • Một domino đứng |, bên trái của một domino rơi trái \, cũng sẽ trở thành một domino rơi trái.

  • Một domino đứng |, bên phải của một domino rơi phải /, cũng sẽ trở thành một domino rơi đúng.

  • Nếu một domino đứng giữa một domino rơi bên trái \và một /domino rơi bên phải , nó sẽ vẫn đứng.

Các quy tắc này được áp dụng nhiều lần cho đến khi sự sắp xếp không còn thay đổi.

Dưới đây là một ví dụ về cách một đầu vào có thể đi đến kết luận của nó

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

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

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

Nhiệm vụ của bạn là viết mã tìm và xuất kết quả cuối cùng của một đầu vào. Bạn có thể cho rằng đầu vào luôn hợp lệ và chứa ít nhất 2 ký tự.

Đây là vì vậy câu trả lời sẽ được tính bằng byte với ít byte hơn.

Các trường hợp thử nghiệm

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

6
Backslash thoát ahoy! (Chúng ta có thể sử dụng các biểu tượng khác không?)
Arnauld

1
@Arnauld Không bạn nên sử dụng dấu gạch chéo.
Phù thủy lúa mì

1
Tôi không thể ... tìm ra cái gì để trốn thoát và cái gì không.
hoàn toàn là

Đầu vào sẽ là chuỗi rỗng hay một ký tự đơn?
Doorknob

3
Nó làm phiền tôi nhiều hơn những thứ như `//////// | \ được coi là ổn định.
MooseBoys

Câu trả lời:


13

Võng mạc , 32 byte

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

Hãy thử trực tuyến!

Giải trình

Việc báo +cho Retina chạy thay thế trong một vòng lặp cho đến khi không thay đổi chuỗi. Mỗi thay thế tính toán một bước domino rơi. Bản thân sự thay thế thực sự là ba sự thay thế trong một, nhưng điều này đảm bảo rằng chúng xảy ra đồng thời:

(/.\\)...
$1

Điều này chỉ phù hợp /|\(cũng như /\\/\\, nhưng những điều đó không quan trọng) và lắp lại nó không thay đổi. Mục đích của việc này là để bỏ qua |với các quân domino rơi xuống ở cả hai bên, bởi vì điều này ngắn hơn việc loại trừ những trường hợp đó bằng cách nhìn riêng trong hai trường hợp còn lại.

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

Điều này phù hợp /|và biến nó thành //.

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

Điều này phù hợp |\và biến nó thành \\.


Không thể nói rằng tôi đã không thấy rằng sắp tới. Retina chắc chắn là một công cụ tốt cho công việc.
Phù thủy lúa mì

@WheatWizard Thật dễ để giải quyết, nhưng có lẽ vẫn còn quá dài dòng với tất cả các lối thoát và điều đó $1$2$2$3$3để đánh bại các ngôn ngữ chơi gôn.
Martin Ender

5

Python 2 , 115 114 111 108 98 95 byte

-1 byte nhờ vào lò nướng

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

Hãy thử trực tuyến!


114 byte sử dụng chuỗi r.
OVS

Bạn có thể loại bỏ b=0;và thay thế xuất hiện của bbằng cách idđể tiết kiệm hai byte!
Lynn

4

V , 23 byte

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

Hãy thử trực tuyến!

Thực sự, điều này rất giống với câu trả lời võng mạc, chỉ là nó trông xấu hơn. Sử dụng nén regex.

Hexdump:

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

Giải trình:

òbảo V chạy cho đến khi chuỗi không thay đổi. Phần còn lại là một regex nén. Hãy chuyển đổi nó thành tương đương 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

Hãy thử trực tuyến!

Tín dụng cho câu trả lời python của Rod cho ý tưởng cho điều kiện dừng với biến thứ hai để xem các thay đổi thay vì thử nghiệm 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

Hãy thử trực tuyến! Dòng đầu tiên xác định một chức năng ẩn danh.

Giải trình:

  • until=<<((==)=<<)$glà một chức năng điểm sửa chữa (xem tại đây phần giải thích ) áp dụng hàm này gcho chuỗi đầu vào cho đến khi kết quả không còn thay đổi.
  • zip3('|':s)s(tail s++"|")tạo cho mỗi domino, đó là ký tự trong chuỗi s, một bộ ba với domino trước và thành công, đệm với| các cạnh. Eg /\|trở thành [(|,/,\),(/,\,|),(\,|,|)](bỏ qua thoát).
  • Sau đó, hàm tđược áp dụng cho mỗi bộ ba để tính toán vị trí mới của phần trung tâm của bộ ba.


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

Hãy thử trực tuyến!

Chương trình này xác định một vị ngữ +/2 là đúng nếu đối số thứ hai là phiên bản đã giải quyết của đối số thứ nhất. Cả hai đối số là danh sách mã ký tự.

Giải trình

Giải pháp này sử dụng DCG để tìm ra bước tiếp theo là gì và sau đó liên tục tính toán bước tiếp theo cho đến bước tiếp theo giống như bước hiện tại.

DCG

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

Năm dòng mã này xác định quy tắc DCG (Definite Article Grammar) +được sử dụng trong chương trình để tính toán một bước duy nhất của việc lật đổ domino. Các DCG trong Prolog hoạt động bằng cách tìm trường hợp đầu tiên của quy tắc có phía bên phải khớp với chuỗi và xác định đối số của quy tắc ở phía bên trái thông qua quy trình đó. Nếu một trường hợp không khớp thì nó sẽ quay lại và thử một trường hợp sau.

+[]-->[].

Dòng này đại diện cho trường hợp cơ sở của +quy tắc. Nó chỉ đơn giản nói rằng nếu không có domino hiện tại thì trong bước tiếp theo vẫn sẽ không có domino.

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

Kể từ khi chương trình này đề độc quyền với danh sách các mã ký tự điều quan trọng cần lưu ý là các mã ký tự cho /, \|47, 92, và 124 tương ứng. Trường hợp này của +quy tắc xử lý /|\chuỗi.

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

Trường hợp này xử lý một domino rơi bên phải gõ vào domino bên phải của nó. Vì nó xuất hiện sau vụ kiện để xử lý /|\nên nó sẽ không được sử dụng cho khả năng đó.

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

Xử lý trường hợp cho một domino rơi trái quỳ xuống domino bên trái của nó.

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

Đây là trường hợp ký tự đại diện. Vì không có gì khác thay đổi ngoài những gì được mô tả ở trên, miễn là có văn bản còn lại trong chuỗi đầu vào, nó sẽ chỉ sao chép nó sang đầu ra miễn là nó không khớp với bất kỳ trường hợp nào ở trên.

Vị ngữ

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

Vị từ chính có hai đối số, đối số thứ nhất là thiết lập domino ban đầu, thứ hai là các domino đã giải quyết. Vì đây là Prolog nên thứ hai có thể không xác định và chương trình sẽ tính toán nó. Vị ngữ trong và bản thân nó khá đơn giản +(N,X,[])gọi DCG và tính toán bước tiếp theo của các domino lưu trữ nó N. (X=N,Y=N;N+Y)kiểm tra xem bước tiếp theo của domino có giống với hiện tại không và nếu nó được đặtY thành nó vì các domino phải giải quyết và nếu nó không tái diễn, hãy gọi cùng một vị từ với bước tiếp theo của domino Nthay vì X.



1

mặt , 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*>

Đưa đầu vào làm đối số dòng lệnh và xuất ra STDOUT. Điều này chỉ hoạt động trong cam kết 86494f6 và hơn thế nữa do lỗi trong cam kết đó.

Bao bọc cho thẩm mỹ:

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

Và không có ý kiến ​​/ nhận xét:

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

Có một vài thủ thuật tinh vi ở đây giúp loại bỏ thêm một vài byte, chẳng hạn như

  • việc đặt tên của các biến | và /, có giá trị ASCII được truy cập thông qua phần hướng nội sau này trong mã

  • các '|trên dòng đầu tiên của vòng lặp chính, được gọi là có thay vì trên dòng thứ hai để thiết lập các | con trỏ để sử dụng trong phần thứ hai của vòng lặp chính


1

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

-6 byte nhờ mik

Có lẽ không phải là tốt nhất có thể cho Perl, nhưng đó là những gì tôi có thể nghĩ ra.

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

Giải trình

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
)

Hãy thử trực tuyến!


-pthay vì -aloại bỏ nhu cầu print;; sử dụng whilelàm hậu tố cho biểu thức giả (ví dụ 0) sẽ tiết kiệm thêm 2 byte
mik

Cảm ơn bạn @mik, tôi không biết những mánh khóe đó. Tôi cũng nhận ra rằng tôi có thể phân định regex bằng một cái gì đó khác để lưu một số byte. Có thể có được điều đó sau.
Geoffrey H.

1

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

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

Hãy thử trực tuyến!

Giải trình

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

Hồng ngọc , 83 byte

Kỹ thuật gian lận với 9.times , hoặc thậm chí chỉ 999.timesnhưng tôi không cảm thấy rẻ tiền :)

Vẫn có tiềm năng chơi golf rất lớn. (Lưu ý: y while undonedài hơn x.size.times)

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

Hãy thử trực tuyến!



Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.