Befunge, 344 byte
&v>>>#p_:63p:43g`\!+v>/*53g+\01g:2%2*1-\2/!*63g+\0\:v
40$ v++!\`g14:p35:\<^2\-1*2%2p10::%4+g00:\g36\g35-1_v
#11^$_83p73v >1+:41g`!#v_$,1+:43g`!#v_@>->2>+00p+141^_
<p1^ vp< ^,g+7g36:<<<<1+55p36:<<<< ^1?0^#7g36g35*
8&p|!++!%9#2g+7g10\*!-g38g10!-g37:g00!!*<>3^
443>:!#v_>>1-::3%1-:53g+00p\3/1-:63g+01p^
^>^>>$#<"#"53g63g7+p41g53g-43g63g-+!#^_
Hãy thử trực tuyến!
Như @flawr đã đề cập trong câu trả lời MATLAB của họ, điều này có thể mất một thời gian nếu kích thước trường là bất kỳ kích thước không tầm thường. Trên thực tế, thật dễ dàng để rơi vào một tình huống mà thực sự không đáng để cố gắng chờ đợi nó kết thúc, bởi vì bạn hoàn toàn có thể chờ đợi cho đến khi kết thúc thời gian.
Để hiểu lý do tại sao điều này xảy ra, thật hữu ích khi xem chương trình khi nó đang thực thi trong một trong nhiều "trình gỡ lỗi trực quan" của Befunge. Vì dữ liệu và mã là cùng một thứ trong Befunge, bạn sẽ có thể xem đường dẫn khi nó thay đổi theo thời gian. Ví dụ, đây là một hình ảnh động ngắn cho thấy một phần của hoạt động trên một con đường chậm có thể trông như thế nào.
Một khi thuật toán quyết định thực hiện bước ngoặt định mệnh đó sang bên trái ở dưới cùng của ranh giới trường, về cơ bản, nó đã tự kết án bản thân mình trong suốt cuộc đời lang thang vô mục đích. Từ thời điểm đó, nó phải đi theo từng con đường có thể trong khu vực có rào chắn đó trước khi nó có thể lùi ra và thử rẽ sang phải. Và số lượng các con đường tiềm năng trong những trường hợp này có thể dễ dàng trở thành thiên văn.
Điểm mấu chốt: Nếu có vẻ mất nhiều thời gian, có lẽ bạn nên hủy bỏ việc thực hiện và bắt đầu lại.
Giải trình
Về cơ bản, đây là một thuật toán đệ quy, thử mọi đường dẫn có thể đi qua trường và sau đó tháo gỡ các bước đã được thực hiện bất cứ khi nào nó bị kẹt. Vì Befunge không có khái niệm về các hàm, nên một hàm đệ quy sẽ không còn nữa, nhưng chúng ta có thể mô phỏng quá trình bằng cách theo dõi trạng thái trên ngăn xếp.
Điều này hoạt động bằng cách điền vào ngăn xếp với tọa độ tiềm năng mà chúng ta có thể muốn theo dõi. Sau đó, chúng tôi kéo một bộ từ ngăn xếp và kiểm tra xem nó có phù hợp không (nghĩa là trong phạm vi và không chồng lấp với một đường dẫn hiện có). Khi chúng tôi đã có một vị trí tốt, chúng tôi viết một#
sân chơi tại vị trí đó và thêm các chi tiết đó vào ngăn xếp trong trường hợp chúng tôi cần quay lại sau.
Sau đó, chúng tôi đẩy thêm bốn bộ tọa độ vào ngăn xếp (theo thứ tự ngẫu nhiên) cho biết các đường dẫn tiềm năng mà chúng tôi có thể đi từ vị trí mới này và quay lại điểm bắt đầu của vòng lặp. Nếu không có đường dẫn tiềm năng nào khả thi, chúng tôi sẽ đến điểm trên ngăn xếp nơi chúng tôi đã lưu vị trí của#
chúng ta đã viết, vì vậy chúng ta sẽ hoàn tác bước đó và tiếp tục thử tọa độ tiềm năng từ một bước trước.
Đây là những gì mã trông giống như với các phần thành phần khác nhau được tô sáng:
Đọc chiều rộng và chiều cao của trường và đẩy tọa độ bắt đầu cùng với 0
điểm đánh dấu loại để chỉ ra đường dẫn tiềm năng thay vì vị trí quay lui.
Kiểm tra các vị trí quay lui (được biểu thị bằng 1
loại đánh dấu) được hoàn nguyên bằng một p
lệnh đơn giản , vì chúng được lưu trữ ở định dạng chính xác cần thiết để ghi lại khoảng trống vào sân chơi.
Kiểm tra xem tọa độ có còn trong sân chơi không. Nếu chúng nằm ngoài phạm vi, thả chúng khỏi ngăn xếp và lặp lại để thử tọa độ tiềm năng tiếp theo.
Nếu chúng nằm trong phạm vi, hãy lấy hai giá trị tiếp theo từ ngăn xếp, đó là vị trí của bước trước đó (bắt buộc trong thử nghiệm theo sau điều này).
Kiểm tra xem tọa độ có tiếp xúc với một đoạn đường dẫn hiện có không. Vị trí của bước trước rõ ràng bị bỏ qua khỏi kiểm tra này.
Nếu tất cả thử nghiệm thành công, hãy viết một #
vào sân chơi và kiểm tra xem chúng tôi đã đến được vị trí đích chưa.
Nếu chúng ta có, viết ra đường dẫn cuối cùng và thoát.
Mặt khác, lưu tọa độ vào ngăn xếp với 1
điểm đánh dấu để quay lại sau.
Điều này bị gián đoạn với một phép tính số ngẫu nhiên mà chúng ta sẽ cần sớm.
Đẩy bốn điểm đến tiềm năng có thể đạt được từ vị trí hiện tại. Số ngẫu nhiên xác định thứ tự mà chúng được đẩy và do đó thứ tự chúng sẽ được tuân theo.
Quay trở lại điểm bắt đầu của vòng lặp chính và xử lý các giá trị tiếp theo trên ngăn xếp.