Làm thế nào khác nhau là khóa học trở ngại của tôi?


21

Lý lịch

Tôi đã xây dựng một khóa học vượt chướng ngại vật đơn giản bằng cách đặt các hộp trong một căn phòng hình chữ nhật. Bây giờ tôi muốn đếm số lượng các cách cơ bản khác nhau để giải quyết nó. Tôi cần bạn viết cho tôi một chương trình cho điều đó.

Đầu vào

Đầu vào của bạn là một mảng hình chữ nhật không trống của các ký tự .#. Các chấm .là không gian trống, và #là những trở ngại.

Một con đường xuyên qua chướng ngại vật bắt đầu ở góc trên bên trái và kết thúc ở góc dưới bên phải, và chỉ đi bên phải hoặc xuống. Ngoài ra, một con đường hợp lệ không thể đi qua một chướng ngại vật. Dưới đây là một số ví dụ được vẽ bằng +ký tự:

Valid path  Invalid path  Invalid path  Invalid path
++........   ++........    +++++.....    ..+.......
.++++++#..   .+.....#..    ....+++#++    ..++...#..
......+#..   .+.++++#..    .......#.+    ...+++.#..
....#.++++   .+++#.++++    ....#....+    ....#+....

Hai đường dẫn về cơ bản giống nhau 1 nếu một đường có thể biến thành đường kia bằng cách di chuyển từng +đường một. Các đường dẫn trung gian cũng phải hợp lệ, vì vậy bạn không thể uốn một đường dẫn qua chướng ngại vật. Ví dụ, hai đường dẫn đầu tiên ở đây về cơ bản là tương tự nhau, nhưng đường dẫn thứ ba về cơ bản khác với chúng, vì nó không thể bị lung lay qua hai chướng ngại vật:

++........   +.........   +++++++++.
.+++++.#..   ++.....#..   .......#+.
.....+.#..   .++++++#..   .......#++
....#+++++   ....#.++++   ....#....+

Đầu ra

Đầu ra của bạn là số lượng các con đường cơ bản khác nhau thông qua các khóa học vượt chướng ngại vật. Nói cách khác, nếu tất cả các đường dẫn hợp lệ được chia thành các lớp của các đường dẫn cơ bản tương tự nhau, thì đầu ra là số lượng các lớp. Lưu ý rằng số này có thể là 0, nếu không có đường dẫn hợp lệ.

Quy tắc và tính điểm

Bạn có thể viết một chương trình đầy đủ hoặc một chức năng. Số byte thấp nhất sẽ thắng và các sơ hở tiêu chuẩn không được phép. Không có giới hạn thời gian, ngoại trừ việc bạn nên đánh giá chương trình của mình trên mọi trường hợp thử nghiệm trước khi gửi nó.

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

....
....
.... => 1

...#
....
...# => 0

#..#
..#.
.... => 0

......
......
..##..
......
...... => 2

......
...#..
......
..#...
#..... => 3

......
..#...
......
....#.
#..... => 4

.......
##.....
....###
...#...
..##.#.
#....#.
..#.... => 0

......#.
..##....
...#....
.......#
....#...
.##...#.
....#...
##...... => 7

.........
.#.#.#.#.
.........
#.#...#.#
.........
.#.#.#.#.
......... => 17

..........
.#........
..........
.....#....
#.........
........#.
......#...
.......... => 10

.........
.#.......
.........
...#.....
.........
.....#...
.........
.......#.
......... => 16

1 Thuật ngữ kỹ thuật chính xác là "homotopic" .


1
Bạn có ý nghĩa gì khi " di chuyển +một lúc "? Có phải điều này ngụ ý rằng các đường dẫn cơ bản tương tự phải có cùng độ dài?
Peter Taylor

3
@PeterTaylor Tất cả các đường dẫn có cùng độ dài, vì chúng chỉ có thể đi xuống và sang phải. Bằng cách "di chuyển một +" tôi thực chất có nghĩa là một góc của con đường bị đảo ngược sang một góc của hướng ngược lại.
Zgarb

1
@Peter: Vì bạn chỉ có thể đi đúng hoặc xuống, nên tất cả các đường dẫn đều có cùng độ dài.
Deusovi

Câu trả lời:


8

Ốc sên , 53 49 byte

A^
\.+d!{.l\.+a3(.|~c!~}\.+r!(.u\.+e(.|~},\.,=~d~

Lần đầu tiên, tôi không phải sử dụng t, hướng dẫn dịch chuyển tức thời. Do đó, các trường hợp thử nghiệm kết thúc ngay lập tức thay vì lấy các aeon.

Ung dung:

A^
r\.+
{
    d\.+
    !{ r\.u \.+ a3 (.|~)}
    r\.+
    !{ d\.l \.+ a3 (.|~)}
},
d\.,
!(dr .)

Các tùy chọn A^có nghĩa là bắt đầu ở góc trên bên trái và đếm tất cả các đường dẫn phù hợp. Ý tưởng chính là kiểm tra một điều kiện canonic cho các đường dẫn. Tôi thực sự không mong đợi nó hoạt động, nhưng nó đóng đinh các trường hợp thử nghiệm, vì vậy .... Điều mà nó cố gắng kiểm tra là, trong con đường hiện tại, con đường tham lam nhất đã được chọn, tức là đi đúng nhiều lần nhất có thể , xuống càng nhiều lần càng tốt, vv mà không vượt qua bất kỳ trở ngại. Điều này được thực hiện bằng cách kiểm tra, sau khi di chuyển sang phải 1 hoặc nhiều lần rồi giảm 1 lần trở lên, không thể đạt được ô vuông tiếp theo (phải ở bên phải) bằng cách đi đúng một lần nữa trong phân đoạn bên phải trước đó. Tình trạng tương tự cũng được kiểm tra sau khi di chuyển sang phải rồi xuống.


nói về ngôn ngữ phù hợp cho công việc!
Không phải là Charles

10

Con trăn 2 170 131 112 byte

def f(C,t=1):i="#".join(C).find("#")+1;return([]<C)*(i<1or(i<t
and f([r[i:]for r in C],t-i))+(i>1)*f(C[1:],i-1))

Một hàm, flấy khóa học vượt chướng ngại vật làm danh sách các hàng và trả về số lượng các đường dẫn cơ bản khác nhau.

Giải trình

Khái niệm cơ bản là thế này: Chúng tôi chọn một chướng ngại vật nhất định, o , sao cho không có chướng ngại vật nào khác trong hộp giới hạn o và góc trên cùng bên trái.

+--+....
|..|....  
+--#<==== o
.....#..
.#......
........

Sau đó chúng tôi xem xét hai khóa học ở phía đông và phía nam của o . Chúng tôi chỉ xem xét một trong hai khóa học phụ này nếu o thực sự có thể được vượt qua từ một hướng dẫn đến chúng, nghĩa là, vượt qua từ phía bắc để đến phía đông, và vượt qua từ phía tây để đến phía nam. Chúng tôi giải quyết vấn đề cho từng khóa học đã chọn và trả về tổng kết quả. Các số này tương ứng với số lượng các đường dẫn cơ bản khác nhau khi đi qua o từ bên trái và bên phải, do đó, hai bộ đường dẫn kết quả về cơ bản là khác nhau. Vì không có chướng ngại vật giữa điểm bắt đầu và o, có một đường dẫn giữa điểm bắt đầu và bất kỳ điểm nhập cảnh nào vào mỗi khu vực này và tất cả các đường dẫn như vậy dẫn đến cùng một điểm về cơ bản là tương tự nhau, do đó tổng trên là số đường dẫn cơ bản khác nhau trong toàn bộ khóa học.

                               A
_
........       ...|////      |....
........       ...|////      |....
...#....  -->  ...#////  -->  ....
.#....#.       .#..//#/       ..#.
........       ....////       ....

   |                           |
   v                           v
                  B
........       ___
........       .#....#.
___#....  -->  ........  -->   +
/#////#/       
////////       

Mọi thứ hơi phức tạp bởi thực tế là một mình chướng ngại vật không truyền đạt tất cả thông tin cần thiết. Ví dụ, hãy xem xét khóa học B trong sơ đồ trên. Được thực hiện bởi chính nó, chúng tôi không thể xác định liệu mỗi chướng ngại vật có thể được vượt qua từ phía bắc. Nếu B là khóa học đầu vào, thì, vì tất cả các con đường bắt đầu ở góc trên bên trái, không có chướng ngại vật nào có thể được vượt qua từ phía bắc, nhưng, vì chúng ta có thể đến B từ hai bên của chướng ngại vật bên trái khi đi qua o từ phía đông , chúng ta nên đối xử với trở ngại này như thể nó có thể được vượt qua từ phía bắc khi giải quyết khóa học; điều tương tự không giữ cho chướng ngại vật đúng, tuy nhiên, không thể vượt qua từ hướng này.

Chúng tôi xác nhận thông tin bổ sung này bằng cách chỉ định, cùng với khóa học vượt chướng ngại vật, số lượng ký tự dọc theo hàng đầu tiên, bắt đầu từ bên trái, rằng đường dẫn có thể bắt đầu. Trong sơ đồ trên, đây được coi là đường liền mạch bên cạnh mỗi khóa học. Trong khi, về mặt kỹ thuật, chúng tôi cũng cần chỉ định số lượng ký tự tương ứng dọc theo cột đầu tiên mà đường dẫn có thể bắt đầu, như trong trường hợp của khóa A , trong thực tế, chúng tôi luôn chọn chướng ngại vật cao nhất, vì vậy thông tin này không bắt buộc .

Lựa chọn thực tế của o như sau: Chúng tôi giả vờ rằng mỗi hàng, trừ hàng cuối cùng, được theo sau bởi một chướng ngại vật (nghĩa là có một #phụ kiện cho nó) và chọn chướng ngại vật đầu tiên trong khóa học kết quả, theo thứ tự đọc. Đối với các hàng (không phải là hàng cuối cùng) không có chướng ngại vật ban đầu, điều này có nghĩa là chúng ta bỏ qua chúng (trong khi lưu ý rằng đường dẫn bên dưới có thể bắt đầu ở bất kỳ ký tự nào dọc theo hàng trên cùng). Cuối cùng, chúng tôi kết thúc với một khóa học có một hàng duy nhất không có trở ngại, trong đó chỉ có một con đường có thể.


đây là khá nhiều giải pháp tôi đã xem xét. Tôi biết ai đó sẽ đăng nó trước khi tôi có cơ hội.
quintopia

6

CJam, 85 84 82 81 80 79 byte

qN/:Q,(Qz,(:R_T]2/e~e!{'#Qs@{\(\@>}%s-},{_}{(a\L{@+_@\-_{2$\f.=0fe=2&},}h;}w;],

Hãy thử trực tuyến. Hoặc chạy toàn bộ bộ thử nghiệm.

Hiệu quả của giải pháp này có lẽ khá kinh khủng nhưng nó giải quyết được từng trường hợp thử nghiệm trong vòng vài giây.

Giải trình

Tôi sẽ phải thêm một phân tích đầy đủ về mã sau, nhưng ý tưởng thuật toán là thế này:

  • Hãy để cho chiều rộng và chiều cao của lưới điện được WH, tương ứng.
  • Chúng tôi tạo ra tất cả các đường dẫn có thể dưới dạng hoán vị riêng biệt của các W-1bản sao 0H-1bản sao của W-1(trong đó 0thể hiện một bước ngang và W-1một bước dọc). Chúng tôi đi bộ tất cả những con đường bằng cách liên tục lấy phần tử đầu tiên của lưới điện và sau đó bỏ qua stepcác tế bào trong việc đọc trật tự (nơi step0hay W-1). Chúng tôi loại bỏ tất cả các đường dẫn có chứa a #.
  • Sau đó, chúng tôi liên tục xóa một nhóm các đường dẫn tương tự (sẽ là tất cả các đường dẫn tương tự như đường dẫn đầu tiên của các đường dẫn còn lại). Việc kiểm tra các đường dẫn tương tự trở nên dễ dàng hơn một chút bằng cách thư giãn điều kiện cho chúng một chút: thay vì kiểm tra xem một đường xcó di chuyển hay không, chúng tôi kiểm tra xem các đường dẫn có khác nhau ở chính xác hai vị trí không. Nếu đó là trường hợp, hai nơi đó sẽ có một di chuyển dọc và ngang hoán đổi. Điều này làm cho toàn bộ phân đoạn giữa các di chuyển bị dịch chuyển theo đường chéo bởi một ô. Nhưng nếu cả hai đường dẫn đó đều hợp lệ, việc dịch chuyển bất kỳ phần nào của đường dẫn bằng một ô theo đường chéo không thể vượt qua một chướng ngại vật, vì vậy chúng tương tự nhau. Chúng tôi vẫn cần tìm cách đóng cửa bắc cầu, vì vậy chúng tôi tiếp tục làm điều đó cho đến khi chúng tôi không tìm thấy đường dẫn nào tương tự trước khi chuyển sang nhóm tiếp theo.
  • Cuối cùng, chúng tôi đếm các nhóm chúng tôi đã tìm thấy, mà chúng tôi để lại ở dưới cùng của ngăn xếp.
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.