Jalan Hutan

9

Setelah perjalanan kano yang membawa bencana , Anda akhirnya jatuh dari air terjun di ujung jeram sungai. Sampan Anda meledak, tetapi Anda berhasil selamat dari ledakan itu. Namun, perjalanan sungai Anda benar-benar hilang dari peta - Anda sekarang telah menemukan diri Anda tersesat di tengah-tengah hutan. Untungnya, Anda masih memiliki keterampilan pemrograman, sehingga Anda memutuskan untuk mengukir program ke sisi pohon untuk membantu Anda menemukan jalan melalui hutan. Namun, tidak banyak area permukaan pada pohon, jadi Anda harus membuat program sesingkat mungkin.

Hutan dapat digambarkan sebagai noleh n( n > 5) kuadrat karakter, yang hanya akan terdiri dari huruf kecil a-z. Contoh hutan:

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

Anda mungkin telah memperhatikan bahwa di hutan ini, ada garis diagonal akarakter berjalan melaluinya dari sudut kiri atas ke sudut kanan bawah. Ini adalah "jalan" melalui hutan yang akan membawa Anda ke suatu tempat jika Anda mengikutinya. Tugas Anda adalah menulis program yang akan menemukan jalur tunggal. Sekarang saya akan lebih spesifik menggambarkan apa yang berkonotasi "jalan" dalam tantangan ini.

"Jalur", dalam tantangan ini, didefinisikan sebagai garis yang serupa dengan jalur yang mungkin dihasilkan dengan algoritme Bresenham , tetapi dengan persyaratan tambahan yang:

  • Panjang garis harus minimal 6 karakter
  • Setiap kelompok karakter collinear (benar-benar berdekatan) dalam garis harus memiliki panjang yang sama .
  • Itu akan dimulai di satu ujung hutan dan berakhir di ujung yang berlawanan (lihat komentar saya di sini untuk penjelasan lebih lanjut)

Untuk menjelaskan persyaratan kedua lebih jelas, pertimbangkan baris berikut:

aaa
   aaa
      aaa
         aaa
            aaa

Baris ini terdiri dari "segmen" collinear karakter, yang masing-masing panjangnya tepat tiga karakter. Itu memenuhi syarat sebagai jalur. Sekarang pertimbangkan baris ini:

a
 aa
   a
    aa
      a
       aa

Baris ini terdiri dari "segmen" collinear yang tidak semua panjang karakternya persis sama (beberapa di antaranya panjangnya 1 karakter dan beberapa di antaranya 2). Dengan demikian, yang ini tidak memenuhi syarat sebagai jalan.

Program Anda, diberi peta hutan, mengidentifikasi karakter yang digunakan di jalan. Input untuk apa pun yang nyaman (mis. Argumen baris perintah, STDIN prompt(),, dll.). Itu tidak dapat diinisialisasi menjadi variabel. Bagian pertama dari input adalah bilangan bulat tunggal yang nmewakili ukuran hutan (hutan selalu persegi). Setelah itu adalah spasi dan kemudian seluruh hutan sebagai string tunggal. Sebagai contoh, contoh hutan akan disajikan, sebagai input, seperti ini:

13  anehcienwlndmbaneiryeivownbnabncmxlriruanhahirrnraucriwuafuvocvncriwnbaueibnxzhyirorairenerruwiiwuauawoeqnnvcizdaiehriefyioeorauviquoeuroenraibcuivoaisdfuaeefoiebnxmcsua

Output untuk ini adalah:

a

karena jalur dibentuk menggunakan huruf a. Hanya akan ada satu jalan di hutan. Ini adalah kode golf, jadi jumlah karakter terendah yang menang. Jika Anda memiliki pertanyaan, tanyakan di komentar.

Absinth
sumber
Bagaimana jika ada banyak jalur?
Eric Tressler
@EricTressler Hanya akan ada satu jalur di hutan mana pun. Saya akan mengedit spesifikasi untuk mencerminkan itu.
absinthe
Bisakah huruf path digunakan di tempat lain di mana itu bukan milik path?
Martin Ender
Contoh hutan berisi itu sangat mungkin. Huruf pertama pada baris ini dalam contoh hutan bukan bagian dari jalan anhahirrnrauc
Spade
@ MartinBüttner Ya. Tetapi mereka tidak akan menjadi dua jalur yang dibuat dari huruf yang sama pada titik mana pun.
absinthe

Jawaban:

3

APL (Dyalog 14) (70)

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

Penjelasan:

  • ⎕ML←3: diatur MLke 3, artinya memiliki arti APL2.
  • I←⍞: baca baris dari keyboard dan simpan di I
  • I⊂⍨' '≠I: split Ipada spasi
  • {... }/: terapkan fungsi ini ke dua string yang dihasilkan:
    • 2/⍎⍺: mengevaluasi argumen kiri dan menggandakannya dua kali, memberikan ukuran matriks
    • ⍵⍴⍨: memformat argumen yang tepat menggunakan ukuran itu
  • F←⊃: hapus kotaknya dan simpan di F.
  • {(⍳≢⍵)⌷¨↓⍵}¨(⊂F),⊂⌽F: dapatkan diagonal: dari setiap baris di keduanya Fdan ⌽F(dicerminkan secara vertikal F), dapatkan nilai di kolom X, di mana X adalah nomor barisnya
  • (↓⍉F),(↓F),: dapatkan baris dan kolom F
  • Z←∪¨: temukan nilai unik pada setiap baris, kolom dan diagonal dan simpan di Z.

Karena 'hutan' berbentuk persegi panjang, jika ada jalur yang valid, artinya salah satu dari ini hanya terdiri dari satu karakter, yang merupakan karakter jalur, jadi:

  • Z/⍨1=≢¨Z: ambil subarrays dari Zyang hanya memiliki satu elemen.

Ini akan menampilkan karakter untuk semua jalur yang valid, tetapi karena seharusnya hanya ada satu yang tidak masalah.

marinus
sumber
4

Lua - 506 380 - byte

Saya merasa agak buruk karena Anda belum menerima pengajuan untuk tantangan dipikirkan dengan baik, jadi saya melemparkan ini bersama. Itu berhenti menyenangkan menyimpulkan apa sifat dibedakan minimum jalan harus dari informasi yang Anda berikan. Saya harap saya melakukannya dengan benar ... DAN mengimplementasikannya dengan benar.

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

Itu dapat diuji dengan:

lua divisorPath.lua "input"

Jika penantang liar muncul, saya akan mencari kode golf saya untuk apa nilainya.

Update : golf untuk menghormati mereka yang akan naik di atas kita. Sementara saya berada di sana saya harus memperbaiki kode saya ke jalur yang dikenal pergi dari kanan ke kiri. Ups.

AndoDaan
sumber
3

MATLAB - 270 karakter

Berikut ini mendefinisikan fungsi xyang menerima string hutan sebagai argumen dan mengembalikan karakter yang mewakili "jalan" yang valid melalui hutan tunduk pada aturan yang diberikan.

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

Versi non-minified adalah

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

Premis dasarnya adalah untuk membangun topeng boolean untuk setiap jalur yang valid yang mungkin dan mengembalikan karakter yang fungsi indeksnya dalam matriks mencakup topeng apa pun. Untuk mencapai hal ini, hanya topeng berbentuk backslash vertikal atau top-to-bottom yang dibuat, tetapi matriks hutan dibandingkan dalam keempat orientasi: identitas, diputar, diputar 90 °, diputar diputar 90 °.

Fungsi berjalan untuk apa saja n. Contoh dari itu dipanggil pada commandline adalah

x('13 anehcienwlndmbaneiryeivownbnabncmxlriruanhahirrnraucriwuafuvocvncriwnbaueibnxzhyirorairenerruwiiwuauawoeqnnvcizdaiehriefyioeorauviquoeuroenraibcuivoaisdfuaeefoiebnxmcsua')

ans =

    a
Eric K.
sumber
3

Python - 384 325 275

Algoritma ini pada dasarnya memeriksa baris pertama dan terakhir dari matriks untuk karakter yang cocok dan kemudian menghitung panjang setiap segmen baris

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

Dalam Contoh di atas:
V di baris pertama adalah di indeks 2, V di baris terakhir di indeks 4.
Jadi panjang setiap segmen baris akan menjadi n / (4-2) +1 = 2 dengan n = 6 .

Itu kemudian memeriksa apakah garis itu valid.

Untuk menemukan jalur dari kiri ke kanan, ia bertukar baris dengan kolom dan melakukan hal yang sama lagi.

Sunting: Tidak bisa mencapai 270 (Sialan Anda Python dan indentasi sialan Anda !!)

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()
Markuz
sumber