pengantar
Dalam tantangan ini, Anda diberikan input representasi ASCII dari jaring (permukaan tidak dilipat) berbentuk kubus persegi panjang (kotak 3D). Formatnya adalah ini:
....+--+.......
....|##|.......
....|##|.......
....|##|.......
+---+--+---+--+
|###|##|###|##|
+---+--+---+--+
....|##|.......
....|##|.......
....|##|.......
....+--+.......
Setiap wajah berbentuk kubus adalah persegi panjang #
s dikelilingi oleh +-|
karakter. Bagian luar jaring diisi dengan .
s. Jaring akan selalu memiliki orientasi yang sama: ada wajah tengah yang dikelilingi oleh empat wajah tetangga, dan lawan dari wajah tengah berada di perbatasan kanan input. Input diisi dengan .
s ke bentuk persegi panjang dan tidak akan berisi baris atau kolom ekstra .
s.
Tugas
Tugas Anda adalah mengambil diagram input seperti di atas, dan menghitung volume berbentuk kubus yang diwakilinya, yang hanya merupakan produk dari tinggi, lebar, dan dalamnya. Anda dapat mengambil input sebagai string yang dibatasi-baris baru atau array string.
Panjang setiap tepi adalah jarak antara karakter- +
di kedua ujungnya. Misalnya, tepi horizontal +--+
memiliki panjang 3, dan tepi vertikal
+
|
|
|
+
memiliki panjang 4. Panjang minimum tepi adalah 1. Contoh berbentuk kubus di atas memiliki volume 2 * 3 * 4 = 24.
Aturan dan penilaian
Anda dapat menulis program atau fungsi lengkap, dan jumlah byte terendah menang.
Uji kasus
.++..
+++++
+++++
.++..
1
...++....
...||....
...||....
+--++--++
+--++--++
...||....
...||....
...++....
3
..+-+....
..|#|....
+-+-+-+-+
|#|#|#|#|
|#|#|#|#|
+-+-+-+-+
..|#|....
..+-+....
12
.+---+.....
++---++---+
||###||###|
||###||###|
||###||###|
++---++---+
.+---+.....
16
....++.....
....||.....
....||.....
....||.....
+---++---++
|###||###||
|###||###||
|###||###||
+---++---++
....||.....
....||.....
....||.....
....++.....
16
...+--+......
...|##|......
...|##|......
+--+--+--+--+
|##|##|##|##|
+--+--+--+--+
...|##|......
...|##|......
...+--+......
18
....+--+.......
....|##|.......
....|##|.......
....|##|.......
+---+--+---+--+
|###|##|###|##|
+---+--+---+--+
....|##|.......
....|##|.......
....|##|.......
....+--+.......
24
....+-----+..........
....|#####|..........
....|#####|..........
....|#####|..........
+---+-----+---+-----+
|###|#####|###|#####|
|###|#####|###|#####|
|###|#####|###|#####|
|###|#####|###|#####|
+---+-----+---+-----+
....|#####|..........
....|#####|..........
....|#####|..........
....+-----+..........
120
Jawaban:
Retina ,
2928 byteCobalah online!
Ada banyak cara untuk mendekati ini di Retina, tergantung pada area mana yang ingin Anda gandakan dengan sisi yang mana, jadi saya tidak yakin seberapa optimal ini, tetapi sebenarnya sudah jauh lebih pendek daripada yang saya kira.
Saat ini saya punya dua solusi lain pada jumlah byte yang sama yang tampaknya sedikit lebih golf daripada pendekatan di atas:
Meskipun dalam hal ini saya dapat menyimpan byte masing-masing jika saya berasumsi bahwa input diakhiri dengan linefeed baris tambahan, tetapi saya lebih suka tidak harus bergantung pada itu.
Dan satu lagi, masih pada 28 byte (yang ini sebenarnya mengalikan tiga sisi daripada mengalikan satu area dengan sisi):
Penjelasan
Gagasan utamanya adalah melipatgandakan area wajah di atas dengan panjang sisi vertikal yang menyentuh batas panjang input.
Saya akan menggunakan input berikut sebagai contoh (memiliki panjang sisi 2, 3 dan 4, jadi area 24):
Tahap 1: Transliterasi
Regex
\G\..+¶
cocok dengan garis yang dimulai dengan.
dan berbatasan langsung dengan garis sebelumnya. Jadi ini cocok dengan semua garis yang berisi wajah paling atas. Panggung itu sendiri berubah.
menjadix
dan semua karakter lain (salah satunya|+-#
) menjadiy
. Ini memberi kami hasil berikut:Ini memiliki satu kolom lebih dari yang
y
kita butuhkan untuk mewakili area dari wajah atas. Kami memperbaikinya dengan tahap berikutnya.Tahap 2: Ganti
Jadi kami cocok dengan
y
yang didahului olehx
(yang persis satu dari mereka per baris) dan menghapus keduanya dari string. Kami mendapatkan ini:Jadi sekarang kita punya area wajah atas yang diwakili oleh jumlah
y
s.Tahap 3: Ganti
Tujuan kami di sini adalah untuk mengalikan area ini
A
dengan panjang sisi yang hilang, yaitu jumlah|
pada awal garis ditambah 1. Namun, sebenarnya lebih mudah untuk mengalikannya dengan angkan+1
karena kami sudah memiliki satu salinan dariA
dalam string . Jika kami menggantin
barang denganA
, kami berakhir dengann+1
salinanA
. Ini membuat banyak hal lebih mudah bagi kita.Jadi kami langsung mengganti apa pun
|
segera setelah umpan baris dengan semua yang ada di depan pertandingan. Ini membuat string cukup banyak dan membuatnya sedikit lebih besar dari yang kita butuhkan, tetapi jumlahy
s akhirnya menjadi hasil yang kita cari:Tahap 4: Cocokkan
Yang tersisa adalah menghitung angka
y
s, yang dicetak sebagai angka desimal di bagian akhir.sumber
Python 2, 57 byte
Fungsi yang mengambil daftar string.
Tentukan 3 dimensi secara terpisah:
l[0].find('+')
Indeks pertama
+
di baris pertama.-~l[0].count('-')
Jumlah
-
tanda di baris pertama.~`l`.count("'|")
Jumlah baris yang dimulai dengan
|
simbol, melalui representasi string dari daftar yang memiliki simbol kutipan sebelumnya.62 byte:
Fungsi yang mengambil daftar string dan mencetak hasilnya.
Menemukan satu dimensi
a
sebagai indeks+
di baris pertama. Dua dimensi lain disimpulkan darinya dan lebar serta tinggi persegi panjang input.Alternatif 63-byte, menemukan dimensi secara terpisah:
sumber
Bash + coreutils,
83, 77 byteEDIT:
Golf
Dijelaskan
Transform dengan sed :
Singkirkan baris baru menggunakan backticks, tambahkan)
Umpan ekspresi yang dihasilkan ke bc
Uji
Cobalah online! (menggunakan ekspansi aritmatika bash, alih-alih bc , karena yang terakhir tidak tersedia)
sumber
Siput , 19 byte
Cobalah online.
Idenya adalah bahwa kita mulai di suatu tempat di tepi paling kanan di internet, dan kemudian melakukan perjalanan ke suatu tempat di wajah paling bawah. Panjang tepi dan luas wajah dikalikan dengan mekanisme penghitungan semua jalur yang cocok.
sumber
JavaScript (ES6), 67
91Uji
sumber
Ruby, 44
Bekerja pada prinsip yang mirip dengan jawaban lain: temukan yang pertama
+
untuk menemukan kedalaman, cari berikutnya.
setelah+
untuk menemukan lebar, dan hitung jumlah|
pada akhir baris dan tambahkan 1 untuk menemukan ketinggian.ungolfed dalam program tes
sumber
05AB1E , 21 byte
Biarkan
W
danH
menjadi masing-masing lebar dan tinggi input - bukan kotak. Kemudian, dimensi kotakA
,B
danC
ikuti aturan ini:Gambar berikut menunjukkan apa
A
,B
danC
apa, dalam hal nama tepi:Karena itulah rumus di atas. Program Toedjoe menghitung ini
A
, menyimpulkan nilai-nilaiB
danC
dan akhirnya menghitung produk mereka.Cobalah online!
Versi sebelumnya - Pendekatan berbeda - 26 byte
sumber
Menembus 93 , 56 byte
Cobalah secara Online!
Penjelasan:
Volume kotak dapat dihitung dengan mengalikan jumlah
.
s pada baris pertama sebelum karakter lain, dengan jumlah+
dan-
s pada baris pertama - 1, dan jumlah baris yang dimulai dengan|
+1.Saya harus memindahkan garis IP ke atas daripada ke bawah untuk menggunakan vertikal jika di baris ke-3. Jika IP akan turun garis, vertikal jika akan memaksa bagian atas tumpukan menjadi 1 ketika memukul horizontal berikut jika, mengirimnya ke arah yang salah.
sumber
Haskell,
6456 byteCobalah online!
Penjelasan
Input diharapkan menjadi daftar string untuk setiap baris, jadi dalam
f
parameternyax
adalah baris pertama danr
daftar baris yang tersisa.fst(span(>'+')x)
mengembalikan.
-prefix dari baris pertama sebagai string, begitulength(fst(span(>'+')x))
juga dimensi pertamad1
.['-' | '-' <- x]
mengembalikan string semua-
di baris pertama, sehingga1 + length['-' | '-' <- x]
menghasilkan dimensi keduad2
.|
di baris pertama dapat dihitung, demikian1 + length['|' | '|':_ <- r]
juga dimensi ketigad3
.Pemahaman daftar 2. dan 3. dapat disingkat menjadi
1+sum[1|'-'<-x]
dan1+sum[1|'|':_<-r]
dengan membangun daftar yang untuk setiap kemunculan '-' atau '|' dan kemudian mengambil jumlahnya. Kami lebih lanjut dapat menempatkan luar1+
ke dalam daftar pemahaman dengan menambahkan-
untukx
dan"|"
untukr
menghasilkansum[1|'-'<-'-':x]
dansum[1|'|':_<-"|":r]
. Sekarang kita dapat menggabungkan kedua daftar pemahaman dengan menempatkan kedua predikat dalam pemahaman yang sama:sum[1|'|':_<-"|":r,'-'<-'-':x]
Mudah ini menghitung persis produk dari dua dimensi karena untuk daftarF
danG
pemahaman daftar berikut adalah produk CartesiusF x G =[(a,b)|a<-F,b<-G]
.Akhirnya, alih-alih mengalikan 1. dengan kombinasi 2. dan 3. kita dapat menggunakan
>>
operator pada daftar:F>>G
mengulangiG
length F
kali dan menyatukan hasilnya. Jadifst(span(>'+')x)>>[1|'|':_<-"|":r,'-'<-'-':x]
ulangi daftard2*d3
yangd1
kali, menghasilkan daftard1*d2*d3
yang kemudian diringkas untuk mendapatkan volume.sumber
lines
.Java 8,
185129 byteterima kasih kepada Zgarb untuk -56 byte
golf:
ungolfed:
Penjelasan
a*b*h = ((length_of_line-2*h-1)/2)*(number_of_lines-2*h-1)*h
di mana
a
danb
adalah dimensi dari pangkalan danh
tinggi. Anda dapat menemukanh
dengan menghitungh
baris pertama di mana Anda mulai dengan a.
.sumber
Java, 112 byte
Diperluas:
sumber
Powershell,
6867 byteCatatan:
"$args"|% i*f +
adalah jalan pintas untuk"$args".indexOf('+')
Penjelasan
Penjelasan yang bagus diambil dari jawaban Osable :
Biarkan
W
danH
menjadi masing-masing lebar dan tinggi input - bukan kotak. Kemudian, dimensi kotakA
,B
danC
ikuti aturan ini:Gambar berikut menunjukkan apa
A
,B
danC
apa, dalam hal nama tepi:Dan
C
adalah posisi pertama+
di baris pertama input.Skrip uji:
Keluaran:
sumber
Bahasa Wolfram (Mathematica) , 64 byte
Cobalah online!
Menggunakan jumlah
.
,|
dan\n
karakter dalam input untuk memecahkan volume. Itu terlihat bodoh karena ada baris baru yang sebenarnya di tempat\n
.Jika
A
,,B
danC
sisi-sisinya, maka. = 2C(A+2C)
,,| = 5B+4C-9
dan\n = B+2C
, jadi kita dapat menyelesaikan volumeABC
dalam hal ketiga karakter ini.sumber