Con đường rừng


9

Sau chuyến đi ca nô thảm khốc , cuối cùng bạn đã rơi xuống một thác nước ở cuối thác ghềnh sông. Xuồng của bạn phát nổ, nhưng bạn đã xoay sở để sống sót sau vụ nổ. Tuy nhiên, hành trình trên sông của bạn đã hoàn toàn rời khỏi bản đồ - bây giờ bạn đã thấy mình bị lạc giữa một khu rừng. May mắn thay, bạn vẫn có kỹ năng lập trình của mình, vì vậy bạn quyết định khắc một chương trình vào bên cạnh một cái cây để giúp bạn tìm đường xuyên rừng. Tuy nhiên, không có nhiều diện tích bề mặt trên cây, vì vậy bạn phải làm cho chương trình của mình càng ngắn càng tốt.

Rừng có thể được mô tả như một nbằng n( n > 5vuông) của nhân vật, mà sẽ chỉ bao gồm các chữ thường a-z. Một ví dụ về rừng:

anehcienwlndm
baneiryeivown
bnabncmxlriru
anhahirrnrauc
riwuafuvocvnc
riwnbaueibnxz
hyirorairener
ruwiiwuauawoe
qnnvcizdaiehr
iefyioeorauvi
quoeuroenraib
cuivoaisdfuae
efoiebnxmcsua

Bạn có thể nhận thấy rằng trong khu rừng này, có một đường chéo các aký tự chạy qua nó từ góc trên bên trái đến góc dưới bên phải. Đây là một "con đường" xuyên qua khu rừng sẽ dẫn bạn đến một nơi nào đó nếu bạn đi theo nó. Nhiệm vụ của bạn là viết một chương trình sẽ tìm ra con đường duy nhất. Bây giờ tôi sẽ mô tả cụ thể hơn những gì hàm ý một "con đường" trong thử thách này.

Một "đường dẫn", trong thử thách này, được định nghĩa là một đường giống với một đường có thể được tạo bằng thuật toán Bresenham , nhưng với các yêu cầu được thêm vào:

  • Dòng phải dài tối thiểu 6 ký tự
  • Mỗi nhóm ký tự (hoàn toàn liền kề) trong dòng phải có cùng độ dài .
  • Nó sẽ bắt đầu ở một cạnh của khu rừng và kết thúc ở cạnh đối diện (xem bình luận của tôi ở đây để biết thêm chi tiết)

Để giải thích rõ hơn yêu cầu thứ hai, hãy xem xét dòng sau:

aaa
   aaa
      aaa
         aaa
            aaa

Dòng này bao gồm các "phân đoạn" của các ký tự, mỗi ký tự dài chính xác ba ký tự. Nó đủ điều kiện như một con đường. Bây giờ hãy xem xét dòng này:

a
 aa
   a
    aa
      a
       aa

Dòng này bao gồm các "phân đoạn" cộng tuyến không hoàn toàn chính xác cùng độ dài của các ký tự (một số trong số chúng dài 1 ký tự và một số trong số chúng là 2). Vì vậy, điều này không đủ điều kiện như một con đường.

Chương trình của bạn, được cung cấp một bản đồ của khu rừng, xác định các ký tự được sử dụng trong đường dẫn. Đầu vào là bất cứ điều gì thuận tiện (ví dụ: đối số dòng lệnh, STDIN prompt(), v.v.). Nó không thể được khởi tạo thành một biến. Phần đầu tiên của đầu vào là một số nguyên duy nhất nbiểu thị kích thước của khu rừng (khu rừng luôn là một hình vuông). Sau đó là một khoảng trắng và sau đó toàn bộ khu rừng như một chuỗi. Ví dụ, rừng ví dụ sẽ được trình bày, như là một đầu vào, như thế này:

13  anehcienwlndmbaneiryeivownbnabncmxlriruanhahirrnraucriwuafuvocvncriwnbaueibnxzhyirorairenerruwiiwuauawoeqnnvcizdaiehriefyioeorauviquoeuroenraibcuivoaisdfuaeefoiebnxmcsua

Đầu ra cho điều này sẽ là:

a

vì con đường được hình thành bằng cách sử dụng thư a. Sẽ chỉ có một con đường trong rừng. Đây là mã golf, vì vậy số lượng nhân vật thấp nhất sẽ thắng. Nếu bạn có câu hỏi, hãy hỏi trong các ý kiến.


Nếu có nhiều đường thì sao?
Eric Tressler

@EricTressler Sẽ chỉ có một con đường trong bất kỳ khu rừng nào. Tôi sẽ chỉnh sửa thông số kỹ thuật để phản ánh điều đó.
absinthe

Có thể sử dụng chữ cái đường dẫn ở một nơi khác không thuộc về đường dẫn không?
Martin Ender

Rừng ví dụ chứa điều đó rất có thể. Chữ a đầu tiên trên dòng này trong khu rừng mẫu không phải là một phần của đường dẫn anhahirrnrauc
Spade

@ MartinBüttner Có. Nhưng chúng sẽ không là hai con đường được tạo từ cùng một chữ cái tại bất kỳ thời điểm nào.
absinthe

Câu trả lời:


3

APL (Dyalog 14) (70)

⎕ML←3⋄Z/⍨1=≢¨Z←∪¨(↓⍉F),(↓F),{(⍳≢⍵)⌷¨↓⍵}¨(⊂F),⊂⌽F←⊃{⍵⍴⍨2/⍎⍺}/I⊂⍨' '≠I←⍞

Giải trình:

  • ⎕ML←3: được đặt MLthành 3, nghĩa là có nghĩa APL2.
  • I←⍞: đọc một dòng từ bàn phím và lưu nó vào I
  • I⊂⍨' '≠I: chia nhỏ Itrên các khoảng trắng
  • {... }/: áp dụng chức năng này cho hai chuỗi kết quả:
    • 2/⍎⍺: đánh giá đối số bên trái và sao chép nó hai lần, đưa ra kích thước ma trận
    • ⍵⍴⍨: định dạng đúng đối số bằng kích thước đó
  • F←⊃: unbox nó và lưu trữ nó trong F.
  • {(⍳≢⍵)⌷¨↓⍵}¨(⊂F),⊂⌽F: lấy các đường chéo: từ mỗi hàng trong cả hai F⌽F(được nhân đôi theo chiều dọc F), lấy giá trị tại cột X, trong đó X là số hàng của nó
  • (↓⍉F),(↓F),: lấy các hàng và cột của F
  • Z←∪¨: tìm các giá trị duy nhất trên mỗi hàng, cột và đường chéo và lưu trữ chúng trong Z.

Vì 'rừng' là hình chữ nhật, nếu có một đường dẫn hợp lệ, điều đó có nghĩa là một trong số đó sẽ chỉ bao gồm một ký tự, đó là ký tự đường dẫn, vì vậy:

  • Z/⍨1=≢¨Z: lấy các tập hợp con từ Zđó chỉ có một phần tử.

Điều này sẽ hiển thị các ký tự cho tất cả các đường dẫn hợp lệ, nhưng vì chỉ có một đường dẫn không quan trọng.


4

Lua - 506 380 - byte

Tôi cảm thấy hơi tệ vì bạn đã không nhận được bất kỳ sự đệ trình nào cho thử thách được cân nhắc kỹ lưỡng của bạn, vì vậy tôi đã cùng nhau ném nó. Thật thú vị khi suy ra những đặc tính có thể phân biệt tối thiểu mà đường dẫn phải có từ thông tin bạn đã cung cấp. Tôi hy vọng tôi đã hiểu đúng ... VÀ thực hiện đúng.

a=io.read"*l"n=a:match("%d+")+0 m=a:match"[a-z]+"o=""for i=1,n do for k=1,n^2,n do o=o..m:sub(i+k-1,i+k-1)end end q={m,o}for g=1,n^2 do for u=1,2 do l=q[u]:sub(g,g)for r=1,n do i=1 t=0 e=0 while i do s,e=q[u]:find(l:rep(r),e+1)if s then x=s-(e-s)-i-1 print(s,i,r,n,r)if x==n or x==n-2 or t==0 then t=t+1 i=s end else i=nil end end if t*r==n then print(l)os.exit()end end end end

Nó có thể được thử nghiệm với:

lua divisorPath.lua "input"

Nếu một kẻ thách thức hoang dã xuất hiện, tôi sẽ tìm đến mã của tôi để biết giá trị của nó.

Cập nhật : chơi golf để vinh danh những người sẽ vượt lên trên chúng ta. Trong khi tôi đang ở đó, tôi đã phải sửa mã của mình sang đường dẫn được nhận biết đi từ phải sang trái. Giáo sư.


3

MATLAB - 270 ký tự

Sau đây định nghĩa một hàm xchấp nhận một chuỗi rừng làm đối số và trả về ký tự đại diện cho "đường dẫn" hợp lệ thông qua chủ đề rừng theo các quy tắc đã cho.

function F=x(s),A=sscanf(s,'%d%s');n=A(1);A=reshape(A(2:end),n,n);for c=A(:)',B=A==c;for i=1:n,if~mod(n,i),C=[kron(eye(i),ones(n/i,1)),zeros(n,n-i)];for j=0:n-i,f=@(B)sum(sum(B&circshift(C,[0,j]))==n;D=fliplr(B);if f(B)|f(B')|f(D)|f(D'),F=char(c);end;end;end;end;end;end

Phiên bản không rút gọn là

function F = x(s)
    A = sscanf( s, '%d %s' );
    n = A(1);
    A = reshape( A(2:end), n,n );
    for c = A(:)'
        B = A==c;
        for i = 1:n
            if ~mod( n, i )
                C = [kron( eye(i), ones( n/i,1 ) ), zeros( n,n-i )];
                for j = 0:n-i
                    f = @(B) sum(sum( B & circshift( C, [0 j] ))) == n;
                    D = fliplr(B);
                    if f(B) | f(B') | f(D) | f(D')
                        F = char(c);
                    end
                end
            end
        end
    end
end

Tiền đề cơ bản là xây dựng mặt nạ boolean cho mọi đường dẫn hợp lệ có thể và trả về bất kỳ ký tự nào có chức năng chỉ mục trong ma trận bao phủ bất kỳ mặt nạ nào. Để thực hiện điều này, chỉ có các mặt nạ hình dấu gạch chéo dọc hoặc từ trên xuống được tạo ra, nhưng ma trận rừng được so sánh theo cả bốn hướng: nhận dạng, lật, xoay 90 °, lật xoay 90 °.

Các chức năng chạy cho bất kỳ n. Một ví dụ về nó được gọi trên dòng lệnh là

x('13 anehcienwlndmbaneiryeivownbnabncmxlriruanhahirrnraucriwuafuvocvncriwnbaueibnxzhyirorairenerruwiiwuauawoeqnnvcizdaiehriefyioeorauviquoeuroenraibcuivoaisdfuaeefoiebnxmcsua')

ans =

    a

3

Con trăn - 384 325 275

Thuật toán này về cơ bản kiểm tra hàng đầu tiên và cuối cùng của ma trận để tìm các ký tự khớp và sau đó tính toán độ dài của từng phân đoạn dòng

012345
------
aaVaaa|0
aaVaaa|1
aaaVaa|2
aaaVaa|3
aaaaVa|4
aaaaVa|5

Trong ví dụ trên:
V ở hàng đầu tiên nằm ở chỉ số 2, V ở hàng cuối cùng ở chỉ số 4.
Vì vậy, độ dài của mỗi phân đoạn dòng sẽ là n / (4-2) +1 = 2 với n = 6 .

Sau đó nó kiểm tra xem dòng có hợp lệ không.

Để tìm đường dẫn từ trái sang phải, nó hoán đổi các hàng với các cột và thực hiện lại điều tương tự.

Chỉnh sửa: Không thể hoàn toàn đến 270 (Chết tiệt Python và vết lõm chết tiệt của bạn !!)

n,m=raw_input().split()
n,r=int(n),range
t=r(n)
a=[m[i:i+n]for i in r(0,n*n,n)]
for v in a,["".join([a[i][j]for i in t])for j in t]:
 for i in t:
  for j in t:
   p=1-2*(j-i<0);d,c=p*(j-i)+1,v[0][i]
   if 6<=sum([v[z][i+(z/(n/d))*p*(n%d==0)]==c for z in t])==n:print c;exit()
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.