Gambarkan Kontur saya

25

Diberi matriks ketinggian persegi panjang, gambarkan konturnya.

Tugas

Dua elemen xdan yberada pada level kontur yang sama jika floor(x/10) == floor(y/10). Misalnya, 52dan 58berada pada level kontur yang sama, tetapi 58dan 64tidak.

Tindakan menggambar kontur didefinisikan sebagai berikut: Untuk setiap elemen e, gantikan dengan string dua karakter yang dipilih sebagai berikut:

  • karakter pertama adalah " "jika elemen di bawah eini pada tingkat kontur yang sama dengan eatau jika tidak ada elemen di bawah ini edan "_"sebaliknya
  • karakter kedua adalah " "jika elemen di sebelah kanan eberada pada level kontur yang sama dengan eatau tidak ada elemen di sebelah kanan edan "|"sebaliknya

Elemen-elemen dalam baris digabungkan bersama, kemudian baris digabungkan bersama dengan baris baru.

Contoh

Katakanlah inputnya [[5,20],[3,6]], divisualisasikan sebagai

5 20
3 6

Kami pertama kali melihat 5. Karena 3berada pada level kontur yang sama dengan 5, karakter pertama adalah " ". Karena 20tidak pada level kontur yang sama dengan 5, karakter kedua adalah "|".

Sekarang kita lihat 20. Karena 6tidak pada level kontur yang sama dengan 20, karakter pertama adalah "_". Karena tidak ada elemen di sebelah kanan 20, karakter kedua adalah " ".

Sekarang kita lihat 3. Karena tidak ada elemen di bawah ini 3, karakter pertama adalah " ". Karena 6berada pada level kontur yang sama dengan 3, karakter kedua adalah " ".

Sekarang kita lihat 6. Karena tidak ada elemen di bawah ini 6, karakter pertama adalah " ". Karena tidak ada elemen di sebelah kanan 6, karakter kedua adalah " ".

Berdasarkan dua karakter ini, kami melakukan penggantian untuk mendapatkan [[" |","_ "],[" "," "]]. Bergabung bersama ini, kami mendapatkan output dari

 |_ 
    

Aturan

  • Matriks input akan selalu berbentuk persegi panjang dan terdiri dari bilangan bulat positif.
  • Ruang tambahan atau baris baru mungkin dalam jumlah berapa pun (termasuk 0) dan tidak harus konsisten dengan cara apa pun.
  • Anda tidak harus mengikuti algoritma yang sama selama Anda menghasilkan hasil yang sama.
  • Program atau fungsi Anda dapat menampilkan string yang dipisahkan baris baru, daftar string, atau yang setara.
  • Ini adalah , jadi kode terpendek dalam byte menang.

Uji Kasus

input
output

[[1,5,8,9],[3,11,13,8],[7,14,10,9],[4,8,7,6]]
  _ _  
 |   | 
 |_ _| 

[[0,10,20,30,40,50,60,70,80,90],[0,0,10,10,20,20,30,30,40,40],[0,0,0,10,10,10,20,20,20,30],[0,0,0,0,10,10,10,10,20,20],[0,0,0,0,0,10,10,10,10,10],[0,0,0,0,0,0,10,10,10,10],[0,0,0,0,0,0,0,10,10,10],[0,0,0,0,0,0,0,0,10,10],[0,0,0,0,0,0,0,0,0,10],[0,0,0,0,0,0,0,0,0,0]]
 |_|_|_|_|_|_|_|_|_
   |_  |_ _|_ _|_ _
     |_    |_ _  |_
       |_      |_ _
         |_        
           |_      
             |_    
               |_  
                 |_


[[5,5,5,5,5,5,5,5,5,5,5],[5,10,10,10,10,10,10,10,10,10,5],[5,10,15,15,15,15,15,15,15,10,5],[5,10,15,20,20,20,20,20,15,10,5],[5,10,15,20,25,25,25,20,15,10,5],[5,10,15,20,25,30,25,20,15,10,5],[5,10,15,20,25,25,25,20,15,10,5],[5,10,15,20,20,20,20,20,15,10,5],[5,10,15,15,15,15,15,15,15,10,5],[5,10,10,10,10,10,10,10,10,10,5],[5,5,5,5,5,5,5,5,5,5,5]]
  _ _ _ _ _ _ _ _ _  
 |                 | 
 |    _ _ _ _ _    | 
 |   |         |   | 
 |   |    _    |   | 
 |   |   |_|   |   | 
 |   |         |   | 
 |   |_ _ _ _ _|   | 
 |                 | 
 |_ _ _ _ _ _ _ _ _| 

[[35,32,29,26,25,25,25,26,29,32,35],[32,28,25,22,20,20,20,22,25,28,32],[29,25,21,18,15,15,15,18,21,25,29],[26,22,18,14,11,10,11,14,18,22,26],[25,20,15,11,7,5,7,11,15,20,25],[25,20,15,10,5,0,5,10,15,20,25],[25,20,15,11,7,5,7,11,15,20,25],[26,22,18,14,11,10,11,14,18,22,26],[29,25,21,18,15,15,15,18,21,25,29],[32,28,25,22,20,20,20,22,25,28,32],[35,32,29,26,25,25,25,26,29,32,35]]
  _|             |_  
_|    _ _ _ _ _    |_
    _|         |_    
   |    _ _ _    |   
   |   |     |   |   
   |   |     |   |   
   |   |_ _ _|   |   
   |_           _|   
_    |_ _ _ _ _|    _
 |_               _| 
   |             |  
fireflame241
sumber
1
Saya bahkan tidak mulai membaca ini sebelum menyadari betapa kerennya ini
Christopher

Jawaban:

6

Perl 6 , 135 byte (131 karakter)

{my$n="_";sub w{$^a.chop-$^b.chop??$n!!" "};my&q={|.[1..*],.tail};(($_ «[&w]».&q) ZZ~{$n="|";$_ «[&w]».map(*.&q)}()).map:{say |$_}}

Cobalah online!

Sedikit tidak berbulu:

{
    my $n = "_";
    sub w { $^a.chop - $^b.chop ?? $n !! " "};
    my &q = {|.[1..*],.tail};
    (
        ($_ «[&w]».&q)
        ZZ~
        {$n="|";$_ «[&w]».map(*.&q)}()
    ).map:{say |$_}
}

Penjelasan : Pertama, kami mendefinisikan variabel $n(baris 2) dan fungsi w(baris 3). Fungsi ini mengembalikan spasi jika dua argumennya berada pada "ketinggian" yang sama, dan isi variabel $nsebaliknya. Alih-alih membaginya dengan 10 dan lantai, kami menyalahgunakan fakta bahwa int adalah Cool(dapat diperlakukan seperti string) dan digunakan chopuntuk menghapus karakter terakhir (= digit). Lalu kami dengan tenang mengurangi mereka, memaksa mereka menjadi angka lagi :—).

Setelah itu (baris 4) kita membuat fungsi qyang mengambil daftar dan mengembalikan daftar itu dengan elemen pertama dihapus dan elemen terakhir digandakan.

Pada 3 baris berikutnya, kita akan membuat 2 matriks lagi dari matriks input: yang pertama memiliki baris pertama yang hilang dan baris terakhir digandakan (itu hanya .&q- menggunakan .&, Anda dapat memanggil fungsi pada apa pun seolah-olah itu adalah sebuah metode - benda di depan titik kemudian argumen pertama), yang lain memiliki kolom pertama hilang dan kolom terakhir digandakan (itu .map(*.&q)).

Pertama (baris 4) kita mengambil matriks asli $_, "overlay" dengan matriks "shifted rows" dan menggunakan fungsinya wsebagai operator biner (begitulah [&w]) pada elemen yang cocok. Yang satu menempatkan di _mana pun elemen yang cocok berada pada ketinggian yang berbeda, dan sebaliknya. Jadi kita mendapatkan ½ dari hasil (hanya "karakter pertama").

Pada baris 6, kita melakukan hal yang sama, tetapi pertama kita beralih $nke |, dan sekarang kita "overlay" matriks asli dengan matriks dengan kolom bergeser. Hasil memiliki |perbedaan dan ketinggian yang sama. Ini adalah "karakter kedua".

Sekarang kita hanya menggabungkan keduanya. Kami zip array dengan zip dengan concat (yeah ...), yang menghasilkan matriks dari bentuk asli yang masing-masing elemen adalah 2 elemen yang cocok dari "solusi setengah" yang digabungkan. Akhirnya, kami hanya memetakan di atas matriks ini (yang benar-benar daftar daftar). Masing-masing daftar ini diratakan dan kemudian saydicetak ulang (dicetak dengan baris baru). Karena saydapat mengambil sejumlah argumen dan mencetak semuanya tanpa pemisah, membuat baris baru di bagian akhir, kita mendapatkan gambar yang diinginkan di stdout. (Dan blok mengembalikan daftar Trues (masing-masing saymengembalikan satu True), tetapi siapa yang peduli.)

Ramillies
sumber
+1 untukbut who cares
HyperNeutrino
5

Jelly ,  25 23  22 byte

-1 byte berkat mil ( Ivektorisasi)

:⁵I;€0ao⁶
Zç”_Zż"ç”|$Y

Program lengkap mencetak hasilnya. Sebagai tautan monadik diperlukan daftar daftar angka, ketinggian, dan mengembalikan daftar daftar, namun "baris" ini terdiri dari daftar dua karakter "pasangan" - jika ini baik maka 1 byte dapat disimpan dengan menghapus Y.

Cobalah online!

Bagaimana?

:⁵I;€0ao⁶ - Link 1, assignCharacters (row-wise): list of lists of numbers; character, c
 ⁵        - literal 10
:         - integer division (vectorises)
  I       - incremental differences (vectorises) (zero if the same else non-zero)
     0    - literal 0
   ;€     - concatenate for €ach (rightmost edge of a row has no contour mark)
      a   - logical and (vectorises) with c (replace non-zeros with the contour character)
        ⁶ - literal space character
       o  - logical or (vectorises) (replace the zeros with spaces)

Zç”_Zż"ç”|$Y - Main link: list of lists of numbers, contours
Z            - transpose the input (get the columns)
  ”_         - literal underscore character, '_'
 ç           - call the last link (1) as a dyad with '_'
    Z        - transpose the result
          $  - last two links as a monad:
        ”|   -   literal pipe character, '|'
       ç     -   call the last link (1) as a dyad with '|'
      "      - zip with the dyadic operation:
     ż       -   zip (interleave the column-wise characters with the row-wise ones)
           Y - join with newlines
             - implicit print
Jonathan Allan
sumber
grr 3 byte. +1 tetapi saya akan mencoba untuk mengalahkan Anda;)
HyperNeutrino
Solusi independen - hanya melihat milik Anda sangat mirip! menghemat satu langsung ...
Jonathan Allan
Anda dapat menyimpan byte menggunakan masing-masing pada join di helper :⁵I;€0ao⁶alih-alih di tautan utamaZç”_Zż"ç”|$Y
mil
@miles Oh wow, itu berhasil? Terima kasih! Saya membayangkan Itidak akan vectorise seperti itu.
Jonathan Allan
Ya Ivektorisasi pada kedalaman 1, dan keduanya adan ovektorkan pada kedalaman 0
mil
3

Python 2 , 199 186 157 155 byte

lambda a:(lambda x:'\n'.join(''.join('_ '[x==z]+'| '[x==y]for x,y,z in zip(r,r[1:]+r[-1:],q))for r,q in zip(x,x[1:]+x[-1:])))([[v/10for v in r]for r in a])

Cobalah online!

Chas Brown
sumber
3

Jelly , 24 byte

:⁵IṠ;€0
ZÇZị⁾_ +³Ç¤ị⁾| ¤

Cobalah online!

Penjelasan

:⁵IṠ;€0           Helper Link; get contour data
:                 Floor division by
 ⁵                10
  I               Compute increments
   Ṡ              Sign; ±1 for different values and 0 for same values
    ;             Append
      0           Zero
     €            To each row
ZÇZị⁾_ +³Ç¤ị⁾| ¤  Main Link
Z                 Zip the input (for vertical contours _)
 Ç                Get the contour data
  Z               Zip the data (because it's zipped from the first Z)
   ị              Index into the string
    ⁾_            "_ "
       +          Add (vectorizing twice) to
        ³ ¤    ¤  Nilad starting from (input)
         Ç        Get contour data (horizontal contours |)
           ị      Index into the string
            ⁾|    "| "

-2 byte terima kasih kepada Jonathan Allan

HyperNeutrino
sumber
Solusi Anda sebenarnya dapat menghilangkan Y- itu akan mengembalikan daftar daftar karakter, yang saya percaya tidak apa-apa (sementara milik saya memiliki pasangan di dalam "baris").
Jonathan Allan
@ Jonathan Allan oh yeah benar ... terima kasih!
HyperNeutrino
2

Python 2 , 226 byte

l=[[j/10for j in i]for i in input()]
for i,j in enumerate(l[:-1]):print''.join('_ '[h==l[i+1][g]]+'| '[h==j[g+1]]for g,h in enumerate(j[:-1]))+'_ '[j[-1]==l[i+1][-1]]
print''.join(' '+'| '[i==j]for i,j in zip(l[-1],l[-1][1:]))

Cobalah online!

Wah, itu adalah doozy untuk mengerjakan logikanya. Saya sekarang melihat Hyper Neutrino memberi saya ninja dengan jawaban yang lebih pendek tetapi saya menghabiskan terlalu banyak pekerjaan untuk tidak mempostingnya. : P

Juga, bisa saya katakan, ini adalah cara yang luar biasa untuk membuat ASCII-art. Maafkan saya sementara saya membuat lebih banyak kapal dari ini.

benar-benar manusiawi
sumber
> ninja'd: dude sudah 45 menit
HyperNeutrino
Ya, saya tidak melihat jawaban ...: P
totallyhuman
Anda dapat menyimpan 4 byte dengan mendefinisikan variabel untuk enumeratealih - alih menggunakan nama lengkap dua kali.
Jonathan Frech
218 byte dengan menghapus yang pertama enumerate(obs, saya harus menghapus beberapa input untuk dapat menghubungkannya di sini)
Felipe Nardi Batista
2

J, 58 byte

f=.{~0==/@]
[:(,/"2)2 2((' _'f{."1),' |'f{.);.3 1:+<.@%&10

Cobalah online!

Fungsi anonim yang mengambil matriks dan menampilkan kontur.

Banyak ruang untuk perbaikan di sini. Saya tidak punya waktu untuk mencoba semua kasus uji jadi beri tahu saya jika ada masalah. Akan mencoba golf lebih banyak dan menjelaskannya nanti.

(Cepat) Penjelasan

Fungsi pembantu: mengindeks ke dalam string panjang 2 berdasarkan pada apakah elemen pertama dari array 2 panjang sama dengan yang kedua. Jika sama, itu akan diindeks ke elemen nol, jika tidak sama, itu diindeks menjadi yang pertama. Array 1 panjang selalu diindeks ke elemen nol dari string.

f=.{~0==/@]

Fungsi utama

[:(,/"2)2 2((' _'f{."1),' |'f{.);.3 1:+<.@%&10

1:+<.@%&10 lantai setiap elemen dibagi 10 dan menambahkan 1 (jadi kita tidak akan pernah mendapatkan 0 - ini penting untuk fungsi pembantu).

2 2((' _'f{."1),' |'f{.);.3memotong matriks menjadi segmen 2 x 2 jika dapat (jika tidak akan memberikan segmen 2 x 1, 1 x 2, atau 1 x 1 di dekat tepi) dan menerapkan fungsi yang digunakan funtuk membandingkan elemen kiri atas ke atas. elemen kanan dan kiri atas ke kiri bawah.

(,/"2)ratakan hasilnya menjadi bentuk yang diinginkan. Saya benar-benar merasa harus menghindari penggunaan ini (dan banyak hal lainnya, tetapi saya ngelantur).

cole
sumber
2

JavaScript (ES6), 120 118 byte

a=>a.map(b=>b.map(c=>c/10|0)).map((b,i,a)=>b.map((c,j)=>((a[i+1]||0)[j]-c?'_':' ')+(b[j+1]-c?'|':' ')).join``).join`\n`

Dimana \nmewakili karakter baris baru literal. Sunting: Disimpan 2 byte berkat @ Bálint.

f=
a=>a.map(b=>b.map(c=>c/10|0)).map((b,i,a)=>b.map((c,j)=>((a[i+1]||0)[j]-c?'_':' ')+(b[j+1]-c?'|':' ')).join``).join`
`
;[
[[5,20],[3,6]]
,
[[1,5,8,9],[3,11,13,8],[7,14,10,9],[4,8,7,6]]
,
[[0,10,20,30,40,50,60,70,80,90],[0,0,10,10,20,20,30,30,40,40],[0,0,0,10,10,10,20,20,20,30],[0,0,0,0,10,10,10,10,20,20],[0,0,0,0,0,10,10,10,10,10],[0,0,0,0,0,0,10,10,10,10],[0,0,0,0,0,0,0,10,10,10],[0,0,0,0,0,0,0,0,10,10],[0,0,0,0,0,0,0,0,0,10],[0,0,0,0,0,0,0,0,0,0]]
,
[[5,5,5,5,5,5,5,5,5,5,5],[5,10,10,10,10,10,10,10,10,10,5],[5,10,15,15,15,15,15,15,15,10,5],[5,10,15,20,20,20,20,20,15,10,5],[5,10,15,20,25,25,25,20,15,10,5],[5,10,15,20,25,30,25,20,15,10,5],[5,10,15,20,25,25,25,20,15,10,5],[5,10,15,20,20,20,20,20,15,10,5],[5,10,15,15,15,15,15,15,15,10,5],[5,10,10,10,10,10,10,10,10,10,5],[5,5,5,5,5,5,5,5,5,5,5]]
,
[[35,32,29,26,25,25,25,26,29,32,35],[32,28,25,22,20,20,20,22,25,28,32],[29,25,21,18,15,15,15,18,21,25,29],[26,22,18,14,11,10,11,14,18,22,26],[25,20,15,11,7,5,7,11,15,20,25],[25,20,15,10,5,0,5,10,15,20,25],[25,20,15,11,7,5,7,11,15,20,25],[26,22,18,14,11,10,11,14,18,22,26],[29,25,21,18,15,15,15,18,21,25,29],[32,28,25,22,20,20,20,22,25,28,32],[35,32,29,26,25,25,25,26,29,32,35]]
].forEach(a=>document.write(['<pre>','</pre>'].join(f(a))));

Neil
sumber
Anda dapat mengubah (a[i] || [])[j]konstruksi menjadi(a[i] || 0)[j]
Bálint
Juga, pada bagian terakhir join`\n`Anda dapat menghapus \nbagian dan menggantinya dengan baris baru yang sebenarnya
Bálint
114 byte:a=>a.map(b=>b.map(c=>c/10|0)).map((b,i,a)=>b.map((c,j)=>" _"[(a[i+1]||0)[j]-c&1]+" |"[b[j+1]-c&1]).join``).join`<new line here>`
Bálint
@ Bálint Bah, saya terus lupa melakukan \nbagian itu; Saya menguji dalam REPL sehingga baris baru literal akan menghalangi.
Neil
@ Bálint Tapi saran terakhir Anda gagal untuk contoh asli, yang saya tambahkan ke daftar output.
Neil
1

Proton , 202 byte

R=(L=len)+range
k=[map((//)&10,r)for r:eval(input())]
d=(x,y,X,Y)=>X>=L(k)or Y>=L(k[X])or k[x][y]==k[X][Y]
print('\n'.join(map(''.join,[['_ '[d(x,y,x+1,y)]+'| '[d(x,y,x,y+1)]for y:R(k[x])]for x:R(k)])))

Cobalah online!

-2 byte berkat Jonathan Frech
-15 byte dengan beralih ke Proton alih-alih Python 2

HyperNeutrino
sumber
Anda dapat menyimpan dua byte dengan mengganti len dengan Ldan mendefinisikan L=len;.
Jonathan Frech
1

Java 8, 200 170 169 byte

a->{String r="";for(int l=a.length,i=0,j;i<l;i++,r+="\n")for(j=0;j<l;r+=(i>l-2||a[i][j]/10==a[i+1][j]/10?" ":"_")+(j++>l-2||a[i][j-1]/10==a[i][j]/10?" ":"|"));return r;}

Penjelasan:

Coba di sini.

Perhatikan bahwa pembagian integer di Jawa secara otomatis lantai.

a->{                   // Method with 2D int-array as parameter and String return-type
  String r="";         //  Result-String
  for(int l=a.length,  //  Length of the input array
      i=0,j;           //  Index integers
      i<l;i++,         //  Loop (1) over the rows of the input array
          r+="\n")     //  and append a new-line to the result after every iteration
    for(j=0;j<l;       //   Inner loop (2) over the columns of a row
      r+=              //    Append the String with:
         (i>l-2        //      If it's the last row,
         ||a[i][j]/10==a[i+1][j]/10?
                       //      or the current and next rows are equal floored/10:
          " "          //       Use a space
         :             //      Else:
          "_")         //       Use a "_"
        +              //     Plus
         (j++>l-2      //      If it's the last column in the row,
         ||a[i][j-1]/10==a[i][j]/10?
                       //      or the current and next columns are equal floored/10:
          " "          //       Use a space
         :             //      Else:
          "|")         //       Use "|"
    );                 //   End of column loop (2)
                       //  End of row-loop (1) (implicit / single-line body)
  return r;            //  Return the result-String
}                      // End of method
Kevin Cruijssen
sumber
1

R, 159 byte

f=function(m){M=m%/%10;a=cbind(0,t(apply(M,1,diff)));b=rbind(apply(M,2,diff),0);a[!!a]="|";b[!!b]="_";M[]=gsub("0"," ",paste0(a,b));write(t(M),"",ncol(m),,"")}

Dengan baris baru dan lekukan:

f=function(m){
    M=m%/%10
    a=cbind(0,t(apply(M,1,diff))) #row-wise difference
    b=rbind(apply(M,2,diff),0) #column-wise difference
    a[!!a]="|"
    b[!!b]="_"
    M[]=gsub("0"," ",paste0(a,b)) # M[] is a trick to force the result to have the same structure as M
    write(t(M),"",ncol(m),,"")
    }

Apakah pembagian integer dari matriks, mengukur perbedaan baris-bijaksana dan kolom-bijaksana, dan ketika tidak nol ganti dengan |dan _masing - masing, kemudian tempelkan keduanya (tanpa rasa sakit, berkat vektorisasi R) dan output.

Kasus uji:

> m=matrix(c(0,10,20,30,40,50,60,70,80,90,0,0,10,10,20,20,30,30,40,40,0,0,0,10,10,10,20,20,20,30,0,0,0,0,10,10,10,10,20,20,0,0,0,0,0,10,10,10,10,10,0,0,0,0,0,0,10,10,10,10,0,0,0,0,0,0,0,10,10,10,0,0,0,0,0,0,0,0,10,10,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0),byrow=T,ncol=10)
> f(m)
  |_|_|_|_|_|_|_|_|_
    |_  |_ _|_ _|_ _
      |_    |_ _  |_
        |_      |_ _
          |_        
            |_      
              |_    
                |_  
                  |_

> m=matrix(c(5,5,5,5,5,5,5,5,5,5,5,5,10,10,10,10,10,10,10,10,10,5,5,10,15,15,15,15,15,15,15,10,5,5,10,15,20,20,20,20,20,15,10,5,5,10,15,20,25,25,25,20,15,10,5,5,10,15,20,25,30,25,20,15,10,5,5,10,15,20,25,25,25,20,15,10,5,5,10,15,20,20,20,20,20,15,10,5,5,10,15,15,15,15,15,15,15,10,5,5,10,10,10,10,10,10,10,10,10,5,5,5,5,5,5,5,5,5,5,5,5),byrow=T,ncol=11)
> f(m)
   _ _ _ _ _ _ _ _ _  
  |                 | 
  |    _ _ _ _ _    | 
  |   |         |   | 
  |   |    _    |   | 
  |   |   |_|   |   | 
  |   |         |   | 
  |   |_ _ _ _ _|   | 
  |                 | 
  |_ _ _ _ _ _ _ _ _| 
plannapus
sumber
0

Perl 5 , 130 126 byte

124 byte kode + 2 untuk -apbendera

push@a,[map 0|$_/10,@F]}{map{say map{($a[$r+1][$c]-$_&&$r<$#a?'_':$").($a[$r][++$c]-$_&&$c<@{$a[0]}?'|':$")}@$_;$c=0;$r++}@a

Cobalah online!

Format input adalah grid 2-D angka yang dipisahkan oleh ruang.

Penjelasan

Ini dari iterasi kode sebelumnya.

push@a,[map 0|$_/10,@F]     # read the input, divide it by 10, and store it in a 2-D array
}{                          # end the implicit while loop and start the final block
map{                        # repeat this for each line
  $_=($a[$r+1][$c]-$_&&$r<$#a?'_':$")       # set appropriate characters to output based
     .($a[$r][++$c]-$_&&$c<@{$a[0]}?'|':$") # on the given rules
  for@$_;                                   # repeat for each number on the line
  $c=0;$r++;                         # setup row and column counters for next iteration
  say@$_                             # output this line
}@a
Xcali
sumber