Buat labirin ASCII

18

Lihat! Ini adalah labirin ASCII! Soo coolzors, amazeballs dan lainnya.

+-+-----+---+
| |     |   |
| |  ++   | |
| |  ++ +-+ |
|       |   |
+-------+ | |
|         | |
+---------+-+

Tapi, tapi, tapi ... itu menyusahkan untuk mengetahui ke arah mana semua bagian labirin pergi. Saya hanya ingin menggambar tata letak dan labirin membuat dirinya sendiri jadi kul tanpa banyak waktu.

Bagaimana jika saya bisa menggambar ini di ...

#############
# #     #   #
# #  ##   # #
# #  ## ### #
#       #   #
######### # #
#         # #
#############

Itu akan sangat manis!


Aturan (Karena aturan keren):

  • Tulis kode untuk mengonversi string menjadi labirin ascii dan hasilkan hasilnya.
  • Setiap karakter non-spasi putih akan dibaca sebagai dinding.
  • Setiap karakter dinding akan memutuskan karakter mana yang akan didasarkan pada tetangganya (hanya di arah Utara, Selatan, Timur dan Barat).
    • Jika char tidak memiliki tetangga non-spasi putih, itu akan menjadi tanda tambah (+).
    • Jika char memiliki tetangga di kedua arah vertikal (Utara-Selatan) dan horisontal (Timur-Barat), itu akan menjadi tanda tambah (+).
    • Jika char memiliki tetangga hanya dalam arah vertikal (Utara-Selatan), itu akan menjadi simbol pipa (|).
    • Jika char memiliki tetangga hanya dalam arah horisontal (Timur-Barat), itu akan menjadi tanda minus (-).
  • Input dapat berupa string tunggal (dengan garis yang dipisahkan oleh karakter baris baru, atau array string).
  • Semua karakter input akan dicetak karakter ASCII, Anda tidak perlu berurusan dengan rangkaian karakter yang diperluas.
  • Silakan gunakan bahasa lama mana saja.
  • Jika ada spasi putih sebelum garis, itu harus jumlah yang sama di setiap baris. Setiap ruang putih setelah setiap jalur output baik-baik saja.
  • Coba atasi dengan jumlah byte terkecil.

Kasus uji:

1: Bingkai

Memasukkan:

##########
#        #
#        #
#        #
##########

Keluaran:

+--------+
|        |
|        |
|        |
+--------+

2: Labirin klasik

Memasukkan:

#################
        #       #
# ##### # ##### #
#   # # #     # #
# # # # ##### # #
#   # #       # # 
### # ####### # #
#   # #    #  # # 
# ### # ## # ##
#     # ##    #  
#################

Keluaran:

--------+-------+
        |       |
| --+-+ | ----+ |
|   | | |     | |
| + | | +---- | |
|   | |       | | 
+-- | +----+- | |
|   | |    |  | | 
| --+ | ++ | -+
|     | ++    |  
+-----+-++----+--

3: Telur hijau, man.

Memasukkan:

I do not like green eggs and ham.
I do not like them, sam I am.
Would you like them here or there?
I would not like them anywhere!

Keluaran:

| ++ +++ ++++ +++++ +++- -++ ----
| ++ +++ ++++ +++++ +++ + +++
+-+++ +++ ++++ ++++ ++++ ++ +++---
| +++-+ +++ ++++ ++-+ +++++++++

4: Es

Memasukkan:

Word Icicle!
Word Icicle 
Word  cicle 
 ord  cicle 
 ord   icle 
 ord   i le 
 or    i le 
 or    i l  
 or      l  
 or         
  r         

Keluaran:

++++ ++++++-
++++ ++++++ 
++++  +++++ 
 +++  +++++ 
 +++   ++++ 
 +++   | ++ 
 ++    | ++ 
 ++    | |  
 ++      |  
 ++         
  |         
AJFaraday
sumber
1
Bukankah seharusnya baris ketiga dari telur hijau dan ham diakhiri dengan ---?
LiefdeWen
1
Hasil untuk tetangga campuran masih belum jelas; tidak yakin mengapa es akan memiliki -s sama sekali atau mengapa labirin klasik tidak memiliki empat +s di baris bawah.
Neil
1
apakah kita diizinkan mengambil input sebagai kotak yang diisi dengan spasi (yaitu matriks)? Apakah output diperbolehkan untuk memiliki spasi tambahan di sekitarnya? Juga, maksud Anda smallest number of characters, bukan byte?
dzaima
1
Saya berpikir bahwa 1) labirin klasik harus ada +di tengah baris ke-2 2) !es harus diganti dengan a -. Bisakah Anda memeriksa ulang yang ini?
Arnauld
1
Oleh whitespace, apakah Anda hanya berarti hanya ruang? Saya tidak ingin harus mendukung tab dan Anda mungkin tidak ingin saya mengubah baris baru
Jo King

Jawaban:

11

APL (Dyalog Unicode) , 57 35 byte SBCS

–22 berkat solusi baru oleh ngn .

Fungsi diam-diam anonim mengambil matriks karakter sebagai argumen.

{⊃'+-|+'↓⍨25 4 2⊃¨⊂⍱∘⌽⍨' '≠,⍵}⌺3 3

Cobalah online!

{}⌺3 3 Pada setiap lingkungan 3-oleh-3, terapkan fungsi berikut:

,⍵ ravel (meratakan)

' '≠ Boolean mana non-ruang

⍱∘⌽⍨ bahwa NOR itu terbalik (termasuk tidak atas NOR bawah, tidak kiri NOR kanan)

5 4 2⊃¨⊂memilih 5 th , 4 th , dan 2 nd elemen dari yang seluruh daftar
  yaitu diri kosong, tidak ada vertikal, tidak ada horisontal

2⊥ mengevaluasi dalam basis-2 (biner)
  yaitu ≥4: kosong diri; 3: tidak ada tetangga; 2: tidak ada tetangga horisontal; 1: tidak ada vertikal; 0: memiliki keduanya

'+-|+'↓⍨ jatuhkan banyak elemen dari string ini
  yaitu kosong sendiri :; sendiri +:; tetangga vertikal saja |+:; horisontal: -|+; kedua:+-|+

 pilih elemen pertama (pad dengan spasi jika tidak tersedia)
  yaitu kosong sendiri :; sendiri +:; tetangga vertikal saja |:; horisontal: -; kedua:+


Solusi lama

Fungsi diam-diam anonim mengambil matriks karakter sebagai argumen.

{' +-|+'⊃⍨1⍳⍨(' '=5⊃,⍵),(∧/,⊢)∨/2 21' '≠(90 1)/,⍵}⌺3 3

Cobalah online!

{}⌺3 3 Pada setiap lingkungan 3-oleh-3, terapkan fungsi berikut:

,⍵ ravel (meratakan)

(... )/ filter menggunakan masker berikut:

  9⍴0 1 membentuk kembali secara siklis [0,1]hingga panjang 9 (memilih N, W, E, S)

' '≠ Boolean mana non-ruang

1⌽ putar satu langkah ke kiri; [W,E,S,N]

2 2⍴ membentuk kembali menjadi 2-oleh-2 matriks; [[W,E],[S,N]]

∨/ pengurangan baris ATAU: [horizontal,vertical]

(... ) terapkan fungsi diam-diam berikut:

   identitas; [horizontal,vertical]

  ∧/, didahului dengan pengurangan AND; [both,horizontal,vertical]

(... ), tambahkan yang berikut:

  ,⍵ Ravel (meratakan) lingkungan

  5⊃ pilih elemen ke- 5 (sendiri)

  ' '= Boolean jika spasi (mis. Kosong)

 Sekarang kita punya [empty,both,horizontal,vertical]

1⍳⍨ indeks paling kiri 1 (memberikan 5 jika tidak ada tetangga sama sekali)

' +-|+'⊃⍨ gunakan itu untuk memilih simbol

   

Adm
sumber
6

JavaScript (ES6), 110 byte

Format I / O: array string.

a=>a.map((s,y)=>s.replace(/\S/g,(_,x)=>'+|-+'[[-1,p=0,1,2].map(c=>p|=(a[y+c%2]||0)[x+~-c%2]>' '?c&1||2:0)|p]))

Cobalah online!

Atau 108 byte dengan menggunakan matriks karakter sebagai gantinya.

Arnauld
sumber
6

Python 2 , 181 168 byte

terima kasih kepada Leaky Nun untuk -13 byte

m=input()
f=lambda x,y:(['']+m+[''])[y+1][x:x+1]>' '
print[[(c<'!')*' 'or'+-|+'[f(x+1,y)|f(x-1,y)|2*f(x,y+1)|2*f(x,y-1)]for x,c in enumerate(r)]for y,r in enumerate(m)]

Cobalah online!

ovs
sumber
5

MATLAB, 113 110 101 byte

function F(A)
B=A>32
c=[1 1 1]
f=@(c)conv2(B,c,'s')>1
h=f(c)
v=f(c')
char((13*h+92*v-94*(h&v)).*B+32)

Mengubah input menjadi logis, menerapkan konvolusi secara horizontal dan vertikal dan menggabungkan output untuk membuat karakter yang sesuai.

3 byte disimpan oleh @Adriaan karena memberi tahu saya bahwa Anda dapat menyumbat output di PPCG: P

9 byte disimpan berkat banyak komentar @ flawr!

Pemandu Otak
sumber
2

Retina 0.8.2 , 92 byte

\S
0
(?<=(.)*)0(?=(?>.*\n(?<-1>.)*)0)|0(?=(.)*)(?<=0(?>(?<-2>.)*\n.*))
1
T`d`+|`\b.\b
T`d`-+

Cobalah online! Membutuhkan input persegi panjang. Tautan termasuk kasus uji. Penjelasan:

\S
0

Ubah semua non-spasi menjadi 0 s.

(?<=(.)*)0(?=(?>.*\n(?<-1>.)*)0)|0(?=(.)*)(?<=0(?>(?<-2>.)*\n.*))
1

Cari semua 0dengan yang lain 0tepat di atas atau di bawah di kolom yang sama dan ubah menjadi 1. 1Sekarang adalah tempat-tempat dengan tetangga vertikal, sedangkan0 s tidak memiliki tetangga vertikal.

T`d`+|`\b.\b

Cari semua digit tanpa tetangga horisontal. The 0s tidak memiliki tetangga vertikal baik, sehingga mereka menjadi +s, sedangkan 1s memiliki tetangga vertikal, sehingga mereka menjadi| s.

T`d`-+

Digit yang tersisa memiliki tetangga horisontal. The 1s juga memiliki tetangga vertikal, sehingga mereka menjadi +s, sedangkan 0s hanya memiliki tetangga horisontal, sehingga mereka menjadi -s.

Neil
sumber
1

Python 3 , 336 byte

def g(s):
 h,j,s=' +|-+','',s.splitlines()
 s+=['']
 for n in range(len(s)):
  s[n]+=' '
  for i in range(len(s[n])-1):
   l,r,k=s[n][i-1],s[n][i+1],0
   try:u=s[n-1][i]
   except:u=' '
   try:d=s[n+1][i]
   except:d=' '
   if not s[n][i]==' ':
    k+=1
    if not u==d==' ':k+=1
    if not l==r==' ':k+=2
   j+=h[k]
  j+='\n'
 print(j)

Cobalah online!

Saya harus menggunakan banyak kode untuk menangani kesalahan kasus tepi.

akozi
sumber
1

C (gcc) , 143 byte

char**y,*z,h,v;f(char**x){for(y=x;*y;++y)for(z=*y;*z;++z)if(*z-32){h=z[1]-32|z[-1]-32;v=y[1][z-*y]-32|y[-1][z-*y]-32;*z=h?v?43:45:(v?'|':43);}}

Cobalah online!

Fungsi f memodifikasi array string di tempat. Area di sekitar array harus diisi dengan spasi (sedikit dibatasi). Meskipun ini tidak benar-benar memenuhi persyaratan yang digunakan kebanyakan solusi, itu sesuai dengan aturan jika kita mengatakan bahwa kita mewakili baris baru dengan dua spasi (dan mengambil array string yang diakhiri dengan baris baru).

Tidak disatukan

f(char**x){
    char **y;
    for (y = x; *y; ++y) {
        char *z;
        for (z = *y; *z; ++z) {
            if (*z != ' ') {
                if (z[1] != ' ' || z[-1] != ' ') {
                    // Horizontal exists
                    if (y[1][z-*y] != ' ' || y[-1][z-*y] != ' ')
                        // Vertical exists
                        *z = '+';
                    else
                        *z = '-';
                } else {
                    // Horizontal doesn't exist
                    if (y[1][z-*y] != ' ' || y[-1][z-*y] != ' ')
                        // Vertical exists
                        *z = '|';
                    else
                        *z = '+';
                }
            }
        }
    }
}

Ini adalah tantangan yang menyenangkan dari pointer aritmatika. Menggunakan iterasi pointer C-style mudah untuk mendapatkan tetangga horisontal, tetapi yang vertikal lebih keras. Untungnya pointer y masih ada (yang menunjuk ke nilai awal z) sehingga saya dapat menyimpulkan indeks saya darinya dan menggunakannya untuk mengakses elemen yang sama pada baris yang berbeda. Rasanya sangat keliru menulis y[-1][z-*y]saat terbang di hadapan gaya apa pun yang masuk akal!

LambdaBeta
sumber
120 byte
ceilingcat