Tantangan
Diberikan input grafis dari suatu bentuk, tentukan berapa banyak lubang yang ada di dalamnya.
Tidak Gandakan
Pertanyaan ini ditandai sebagai duplikat yang mungkin dari Pulau Count . Saya percaya tantangan ini berbeda dari tantangan Count Island karena dalam tantangan ini, Anda harus memikirkan cara menghilangkan blok yang menyentuh perbatasan.
Memasukkan
Input akan diberikan sebagai bentuk input 2D, baik string multiline, array string, atau array array karakter. Ini mewakili bentuk. Bentuknya dijamin hanya akan menjadi satu bagian, dihubungkan dengan ujung. Silakan tentukan bagaimana Anda ingin input diambil.
Keluaran
Output adalah bilangan bulat tunggal yang menyatakan berapa banyak lubang yang ada dalam bentuk. Sebuah trailing newline diizinkan, tetapi tidak ada spasi putih terdepan atau tambahan lainnya. Dengan kata lain, output harus cocok dengan ekspresi reguler ^\d+\n?$
.
Apa itu lubang?
Ini adalah lubang tunggal:
####
# #
# #
####
####
# #
# ##
###
#####
# # #
# #
#####
Ini bukan lubang:
########
########
# ####
# ####
# ######
#
########
###
#
###
##########
#
# ########
# # #
# # #### #
# # ## #
# ###### #
# #
##########
Cukup banyak, jika celah bergabung dengan tepi luar, itu bukan lubang.
Uji kasus
#####
# # # -> 2
#####
#####
#
# ### -> 1
# # #
#####
####
## # -> 1 (things are connected by edges)
# ##
####
###
### -> 0 (You must handle shapes with no holes, but input will always contain at least one filled space)
###
Anda dapat menggunakan karakter apa pun sebagai ganti '#', dan sebagai ganti spasi.
Kriteria Penilaian Objektif
Skor diberikan sebagai jumlah byte dalam program Anda.
Kemenangan
Pemenang akan menjadi pengajuan dengan skor terendah, pada 4 April.
###|# #|##
sebagai test case? Seharusnya begitu0
, kan?Jawaban:
MATLAB / Oktaf, 18 byte
Cobalah online!
Ini adalah fungsi anonim yang mengambil matriks logis sebagai input. Objek dibentuk oleh
true
entri (dengan konektivitas yang ditentukan), ruang kosong adalahfalse
entri.bweuler
kemudian menghitung angka euler dari citra biner yang diwakili oleh matriks itu, yaitu jumlah objek dikurangi jumlah lubang.sumber
Mathematica,
5957 byteAda built-in untuk itu. Mengambil input sebagai matriks 2D
1
s (dinding) dan0
s (lubang). Untuk kenyamanan, berikut adalah semua test case dalam format input ini:Solusi alternatif, 59 byte
Ini adalah pendekatan awal saya. Ini juga didasarkan pada komponen bawaan yang terkait, tetapi tidak menghitung lubang secara langsung (melainkan memperlakukan lubang itu sendiri sebagai komponen).
Mengambil format input yang sama seperti di atas, tetapi dengan peran
0
s dan1
s bertukar.Alasan saya perlu mengonversikan ini menjadi yang
Image
pertama adalah, jika tidak, Mathematica akan menganggap semua-1
sel sebagai bagian dari komponen tunggal (karena itu memperlakukan matriks sebagai matriks komponen-label). Oleh karena itu, jika ada -1
sel yang berbatasan dengan margin, itu akan menghapus semuanya. KetikaDeleteBorderComponents
digunakan pada gambar sebagai gantinya, maka itu akan melakukan pemeriksaan konektivitas implisit untuk menemukan komponen.Atau, saya bisa menelepon
MorphologicalComponents
dulu , yang akan mengubah input menjadi matriks label yang sesuai, tetapi jika saya lakukanDeleteBorderComponents
kedua itu tidak lagi dijamin bahwa label komponen maksimum sesuai dengan jumlah komponen (karena saya mungkin menghapus komponen yang lebih kecil).sumber
GenerateBuiltin
. Ini menghasilkan built-in untuk setiap tantangan yang tidak memiliki built-in. Juga, saya merasa tidak enak untuk kotak masuk Martin Ender, jadi jika Anda mau, mari kita lanjutkan diskusi ini di siniPerl 5 , 154 byte
152 byte kode + 2 byte untuk
-p0
flag.Cobalah online!
Saya pikir kode ini cukup jelas.
Jika Anda memerlukan beberapa penjelasan untuk dipahami, berikut adalah beberapa langkah transformasi yang dilakukan oleh program dengan masukan sederhana (datang dari sini ), diikuti dengan beberapa penjelasan di bawah:
Pertama,
s/^ | $/A/gm;s/^.*\K | (?=.*$)/A/&&redo
akan mengganti spasi di perbatasan (regex ke-1 untuk kiri / kanan, ke-2 untuk ke bawah / atas) denganA
(saya memilih karakter yang cukup sewenang-wenang).Lalu, kita dapatkan lebar bentuk dengan
/.*/;$@="@+"-1;
.Sekarang, kami ingin mengganti setiap ruang yang terhubung ke
A
denganA
(karena jika ruang terhubung keA
, itu berarti itu tidak bisa menjadi bagian dari lubang. Itu dilakukan olehfor$%(A,X){(s/$%(.?.?.{$@})? /$%$1$%/s||s/ (.?.?.{$@})?$%/$%$1$%/s)&&redo}
. (Anda akan melihat bahwa ini dilakukan sekali untukA
s dan satu untukX
s - penjelasan untuk diX
bawah) .Ada dua regex di sini:s/$%(.?.?.{$@})? /$%$1$%/s
berurusan dengan spasi yang ada di kanan atau bawah A.A
Dans/ (.?.?.{$@})?$%/$%$1$%/s
dengan spasi di atas atau kiri aA
.Pada titik ini, satu-satunya ruang yang tersisa di string adalah bagian dari lubang.
Meskipun masih ada spasi, kami ulangi:
- Untuk mengetahui berapa banyak lubang yang ada, kami mengganti spasi dengan
X
(s/ /X/
) dan menambah penghitung lubang ($\++
), dan mengulang seluruh program (sebenarnya, kami hanya ingin mengulangfor
loop) , tetapi kurang byte untuk mengulang seluruh program).- Kemudian,
for
loop akan mengganti setiap ruang yang terhubung keX
denganX
, karena mereka adalah bagian dari lubang yang sama.Pada akhirnya,
$\|=0
pastikan bahwa jika tidak ada lubang, a0
dicetak dan bukannya string kosong. Dan$\
dicetak secara tersirat berkat-p
bendera.sumber
Python 2, 282 byte
+100 untuk menangani sentuhan diagonal TT_TT (apakah kita benar-benar membutuhkannya?)
-119 berkat panduan @Rod :)
Cobalah online . Mengambil array array karakter '#' dan spasi sebagai input.
Mencari spasi putih pertama dan menandainya sebagai non-kosong ('#'). Periksa secara rekursif semua di sekitarnya, sambil mengisi semua sel kosong. Jika sel kosong "lubang" saat ini tampaknya berada di konter perbatasan tidak akan berubah, jika tidak maka akan meningkat 1. Proses ulang, sampai tidak ada lagi spasi putih.
sumber
sum(A,[])
untuk meratakanNone
s, tapi itu tidak relevan)x=T[0];y=T[1]
->x,y=T
, Anda (mungkin) tidak perlu mendeklarasikang=1
pada baris ke-3, dan Anda dapat menggunakan<
atau>
membandingkan string (itu akan mengambilord()
nilai dari masing-masing karakter) yang memungkinkan Anda untuk menggantiA[y][x]!='#'
denganA[y][x]<'#'
, karena' '<'#'
.Python 2,
233225222 bytemath_junkie : -8 byte
Mengambil array 2d dari booleans / integer (0/1) sebagai input
Cobalah online!
Versi yang diformat:
sumber
print sum(m(x,y)...
sebagai gantia=
danprint a
C # 7, 364 byte
Kurang senang dengan ini ... mungkin orang lain dapat mengatasinya ... Jika saya memiliki energi nanti saya akan membalikkan loop pertama, dan melihat apakah itu dapat membantu untuk memotong batas memeriksa.
Cobalah online
Program yang lengkap, menerima input ke standar, output ke standar Menggunakan set terpisah untuk menentukan lubang sementara, dan ketika membunuh menyentuh batas (dengan beberapa dodgyness untuk tepi atas).
Kode yang diformat dan dikomentari:
sumber
Func<List<string>, int>
untuk menghapus bulu dan konsol. Namun, saya telah melihat Anda memiliki fungsi lokal sehingga Anda mungkin tidak dapat memilikinya di func. Hanya bisa mengkompilasi ke suatu metodeint h(string[] s) { }
.Siput , 48 byte
Tidak Disatukan:
sumber
JavaScript (ES6), 192 byte
Berdasarkan jawaban saya untuk Mendeteksi Kastil Gagal . Pertama-tama tali diisi dengan ruang untuk membuat area di sekitar bentuk. RegExp kemudian mencari dua kotak yang berdekatan, satu berisi
@
, satu berisi spasi, dan menggantinya dengan@
. Jika tidak bisa melakukan ini, ia mengisi ruang dengan@
dan menghitung ini sebagai lubang baru. Akhirnya seseorang dikurangkan untuk memperhitungkan daerah sekitarnya.sumber