Perl 5 , -p0
105 101 96 93 90 89 byte
Sử dụng b
thay vì 1
trong đầu vào.
Đảm bảo ma trận trên STDIN được kết thúc bằng một dòng mới
#!/usr/bin/perl -p0
s%b%$_="$`z$'";s:|.:/
/>s#(\pL)(.{@{-}}|)(?!\1)(\pL)#$&|a.$2.a#se&&y/{c/z />0:seg&/\B/%eg
Hãy thử trực tuyến!
Sử dụng 3 cấp độ thay thế!
Phiên bản 87 byte này có cả định dạng đầu vào và đầu ra dễ hiểu hơn, nhưng không cạnh tranh vì nó sử dụng 3 ký tự khác nhau trong đầu ra:
#!/usr/bin/perl -0p
s%b%$_="$`z$'";s:|.:/
/>s#(\w)(.{@{-}}|)(?!\1)(\w)#$&|a.$2.a#se&&y/{c/z />0:seg&/\B/%eg
Hãy thử trực tuyến!
Thật dễ dàng để lưu một byte khác (công cụ s
sửa đổi biểu thức chính) trong cả hai phiên bản bằng cách sử dụng một số ký tự khác nhau (không phải chữ và số) làm dấu kết thúc hàng (thay vì dòng mới), nhưng điều đó làm cho đầu vào khá khó đọc trở lại.
Làm thế nào nó hoạt động
Hãy xem xét sự thay thế
s#(\w)(.{columns}|)(?!1)(\w)#c$2c#s
Điều này sẽ tìm thấy hai chữ cái khác nhau và nằm cạnh nhau theo chiều ngang hoặc chiều dọc và thay thế chúng bằng c
. Trong một mê cung có đường dẫn hoàn toàn là chữ cái b
sẽ không có gì xảy ra vì các chữ cái giống nhau, nhưng ngay khi một trong các chữ cái được thay thế bằng một chữ cái khác (ví dụ z
) chữ cái đó và hàng xóm sẽ được thay thế c
và ứng dụng lặp đi lặp lại là một lấp đầy các thành phần được kết nối với c
từ hạt giốngz
.
Trong trường hợp này, tuy nhiên tôi không muốn lấp đầy hoàn toàn. Tôi muốn chỉ lấp đầy một trong những cánh tay lân cận z
, vì vậy sau bước đầu tiên tôi muốn z
đi. Điều đó đã hoạt động với sự c$2c
thay thế, nhưng sau đó tôi muốn khởi động lại một vùng lũ dọc theo một nhánh khác bắt đầu từ cùng một điểm và tôi không biết cái nào c
ban đầu z
nữa. Vì vậy, thay vì tôi sử dụng
s#(\w)(.{columns}|)(?!\1)(\w)#$&|a.$2.a#se
b | a
là c
, b | c
là c
và z | a
là {
. Vì vậy, trong một mê cung với những con đường được tạo thành b
và một hạt giống z
trong bước đầu tiên b
sẽ được thay thế c
và z
sẽ được thay thế bởi {
đó không phải là một chữ cái và không khớp \w
và do đó sẽ không gây ra thêm. Các c
tuy nhiên sẽ giữ thêm lũ điền đi và một cánh tay người hàng xóm của hạt giống được lấp đầy. Ví dụ: bắt đầu từ
b c
b c
bbzbb becomes bb{bb
b b
b b
Sau đó tôi có thể thay thế tất cả c bởi một số phi chữ cái (ví dụ -
) và thay thế {
bằng z
một lần nữa để khởi động lại lũ điền:
- -
- -
bbzbb becomes cc{bb
b b
b b
và lặp lại quá trình này cho đến khi tất cả các hàng xóm của hạt giống đã được chuyển đổi. Nếu tôi sau đó một lần nữa thay thế {
bởi z
lũ điền:
- -
- -
--z-- stays --z--
- -
- -
Phần z
còn lại phía sau ở cuối vì không có hàng xóm để thực hiện chuyển đổi. Điều đó làm rõ những gì xảy ra trong đoạn mã sau:
/\n/ >
Tìm dòng mới đầu tiên. Phần bù bắt đầu hiện tại@-
s#(\w)(.{@{-}}|)(?!\1)(\w)#$&|a.$2.a#se
Regex đã thảo luận ở trên với @{-}
số lượng cột (vì đơn giản là @-
nhầm lẫn trình phân tích cú pháp perl và không thay thế đúng cách)
&&
Các /\n/
luôn thành công và sự thay thế là đúng miễn là chúng ta vẫn có thể lũ điền. Vì vậy, phần sau &&
được thực hiện nếu việc lấp đầy một cánh tay được thực hiện. Nếu không bên trái ước tính thành một chuỗi rỗng
y/{c/z / > 0
Khởi động lại vùng lũ và trả lại 1 nếu lần lũ trước đó làm bất cứ điều gì. Khác trả lại chuỗi trống. Toàn bộ đoạn mã này được bọc bên trong
s:|.: code :seg
Vì vậy, nếu điều này được thực thi trên chuỗi bắt đầu $_
với z
vị trí hạt giống, đoạn mã bên trong sẽ được thực thi nhiều lần, hầu như không trả về gì ngoài 1
mỗi lần cánh tay hàng xóm bị ngập nước. Hiệu quả $_
bị phá hủy và thay thế bởi nhiều 1
s như có các thành phần được kết nối với z
. Lưu ý rằng vòng lặp cần được thực hiện tối đa bằng kích thước thành phần + số lần sử dụng vũ khí nhưng điều đó không sao vì nó sẽ "số lượng ký tự bao gồm cả dòng mới * 2 + 1" lần.
Mê cung bị ngắt kết nối nếu không có 1
(chuỗi trống, đỉnh bị cô lập) hoặc nếu có nhiều hơn 1 nhánh (hơn 2 1
giây). Điều này có thể được kiểm tra bằng regex /\B/
(cái này 0
thay vì 1
trên các phiên bản perl cũ hơn. Người ta cho rằng cái nào sai). Thật không may nếu nó không khớp, điều này sẽ cung cấp một chuỗi trống thay vì 0
. Tuy nhiên, s:|.: code :seg
được thiết kế để luôn trả về một số lẻ, vì vậy bằng cách thực hiện &
với /\B/
điều này sẽ cho 0
hoặc 1
.
Tất cả những gì còn lại là đi bộ toàn bộ mảng đầu vào và tại mỗi hạt giống vị trí có thể đi bộ với z
và đếm các cánh tay được kết nối. Điều đó dễ dàng thực hiện với:
s%b%$_="$`z$'"; code %eg
Vấn đề duy nhất là ở các vị trí không thể đi bộ, giá trị cũ được giữ lại. Vì chúng ta cần 0
có nghĩa là mảng đầu vào ban đầu phải có 0
ở các vị trí không thể đi bộ và 0
khớp với vị trí \w
thay thế ban đầu và sẽ kích hoạt lấp đầy lũ. Đó là lý do tại sao tôi sử dụng \pL
thay thế (chỉ khớp các chữ cái).