Pertama, beberapa terminologi ( sumber ):
- Sebuah atap pinggul adalah (mengutip Wikipedia) "jenis atap di mana semua pihak kemiringan ke bawah ke dinding, biasanya dengan kemiringan yang cukup lembut"
- Kemiringan adalah permukaan planar yang merupakan bagian dari atap
- Bubungan adalah tepi tempat dua lereng atap yang berseberangan bertemu
- Pinggul adalah tepi cembung di mana dua lereng yang dimiliki oleh dinding tegak lurus bertemu
- Sebuah lembah adalah tepi cekung di mana dua lereng yang dimiliki oleh dinding tegak lurus bertemu
- Pinggul dan lembah secara kolektif disebut sebagai tepi diagonal.
Masukan yang mungkin:
** * ***
********
** * **
Output yang sesuai:
+-------+ +---+ +-----------+
|\ /| |\ /| |\ /|
| \ / | | V | | \ ^---< |
| \ / | | | | | \ / \ \|
+---+ V +---+ | +---+ X +---+
|\ \ | / \|/ \ / \ |
| >---> | <-------X-------V > |
|/ / | \ /|\ /| |
+---+ ^ +---+ | +-------+ | +---+
| / \ | | | | | |/ /|
| / \ | | ^ | | /---< |
|/ \| |/ \| |/ \|
+-------+ +---+ +-------+
Beberapa kasus tes lagi:
** *** * * * *
* *** *****
** ***** *****
* * * *** *** ***
* **** * * *
Output yang sesuai:
+-------+ +-----------+ +---+ +---+ +---+ +---+
|\ /| |\ /| |\ /| |\ /| |\ /| |\ /|
| \---< | | >-------< | | V | | V | | V | | X |
| |\ \| |/ \| | | | | | | | | | |/ \|
| | +---+ +-----------+ +---+ | +---+ | | +-----------+ | | +---+
| | | |\ \|/ /| | |/ \| |
| ^ | | \ V / | | < > |
|/ \| | \ / | | \ / |
+---+ +-------+ +---+ \ / +---+ | \-----------/ |
|\ /| |\ \ \ / / /| | |\ /| |
| >---/ | | >---> X <---< | | | \ / | |
|/ /| | |/ / / \ \ \| | | \ / | |
+---+ +---+ +---+ | | +---+ / \ +---+ +---+ ^ +---+ ^ +---+
|\ /| |\ /| | | | | / \ | |\ \ / \ | | / \ / /|
| V | | V | | | | | / ^ \ | | >---V > | | < V---< |
| | | | | | | | | |/ /|\ \| |/ /| | | |\ \|
| | | | | +-------+ | | +---+ | +---+ +-------+ | | | | +-------+
| | | | |/ \| | | | | | | | | | |
| ^ | | /-----------\ | | ^ | | ^ | | ^ |
|/ \| |/ \| |/ \| |/ \| |/ \|
+---+ +---------------+ +---+ +---+ +---+
Input Anda akan berupa bitmap - array 2D piksel persegi - dari area yang harus ditutup oleh atap. Anda dapat mengasumsikan batas area ini adalah kurva Jordan - yaitu, kontinu dan tidak berpotongan-sendiri - yaitu, area beratap akan kontinu, tanpa lubang dan tidak akan pernah ada empat dinding yang bertemu pada satu titik. Format input yang valid termasuk string tunggal dengan pemisah baris baru, daftar string dan array karakter atau boole 2D.
Aturan membangun atap adalah:
- Setiap segmen lurus dari area beratap (untuk selanjutnya disebut sebagai dinding) harus memiliki tepat satu lereng yang berdampingan. Kemiringan akan menjauh dari dinding. Setiap lereng harus memiliki setidaknya satu dinding yang bersebelahan, dan semua dinding yang bersebelahan dengan lereng harus berbentuk collinear.
- Semua lereng harus memiliki sudut yang sama (bukan nol) terhadap permukaan horizontal. Artinya, mereka harus memiliki nada yang sama.
- Lereng harus membentuk permukaan yang batasnya adalah batas area beratap. Artinya, tidak ada permukaan selain lereng yang dapat digunakan.
- Setiap skenario di mana lebih dari satu solusi (hingga penskalaan vertikal) diizinkan oleh spesifikasi ini dianggap sebagai bug dalam spesifikasi. Setiap koreksi berlaku surut.
Secara ekivalen, atap dapat didefinisikan dengan aturan bahwa setiap titik atap ditempatkan setinggi mungkin tanpa melebihi kemiringan maksimum untuk atap itu yang diukur dengan menggunakan jarak Chebyshev dalam tampilan top-down.
Output Anda harus berupa representasi seni ASCII dari atap - baik string tunggal yang berisi karakter baris baru atau array string, masing-masing menunjukkan satu baris output. Atap akan ditampilkan dalam tampilan top-down pada skala 4x - yaitu, setiap kuadrat denah lantai harus memengaruhi area 5x5 dari output sehingga sudut-sudut area 5x5 ini dibagi dengan kotak tetangga (sehingga masing-masing karakter sudut dipengaruhi oleh empat kotak input yang berbeda), seperti ditunjukkan oleh contoh output. Ruang kosong ekstra diizinkan selama bentuk output dipertahankan. Karakter yang ditampilkan adalah:
- penanda baris baru yang ditetapkan lingkungan harus digunakan (biasanya U + 000A, U + 000D atau sepasang keduanya) jika output dalam bentuk string tunggal
(Ruang U + 0020) mewakili titik di luar area beratap atau interior titik ke lereng
+
(U + 002B tanda plus) mewakili titik dengan dua dinding tegak lurus berdampingan dengannya-
(U + 002D tanda hubung minus) mewakili dinding atau punggungan yang berorientasi horizontal (timur-barat)/
(U + 002F solidus) mewakili pinggul atau lembah yang berorientasi timur laut ke tenggara, atau titik yang disatukan dengan dua di antaranya.<
(U + 003C tanda kurang dari) merupakan titik dengan dua tepi diagonal yang disatukan di sebelah timur>
(U + 003E lebih besar dari tanda) mewakili titik dengan dua tepi diagonal yang disatukan di sebelah barat\
(U + 005C membalikkan solidus) mewakili pinggul atau lembah yang berorientasi barat laut ke tenggara, atau titik yang disatukan dengan dua di antaranya.^
(U + 005E aksen sirkumfleksa) mewakili titik dengan dua tepi diagonal yang disatukan di selatanV
(U + 0056 huruf kapital latin v) merupakan titik dengan dua tepi diagonal yang disatukan di sebelah utaraX
(U + 0058 huruf latin x) mewakili titik dengan tepi diagonal yang disatukan di keempat sisinya|
(U + 007C batang vertikal) mewakili dinding atau punggungan yang berorientasi secara vertikal (utara-selatan)
Perhatikan bahwa tidak mungkin jumlah tepi diagonal ganjil berakhir pada titik yang sama (kecuali di dinding). Kita dapat memvisualisasikannya dengan mempartisi lingkungan dari setiap titik ke lereng utara + lereng selatan dan ke lereng timur + lereng barat. Batas antara kedua partisi harus terdiri dari tepi diagonal.
Jika lingkungan Anda menggunakan pengkodean karakter yang tidak kompatibel dengan ASCII, Anda dapat menggunakan karakter yang setara (mesin terbang yang sama atau terdekat yang tersedia) dalam pengkodean karakter yang digunakan lingkungan Anda.
Implementasi referensi berikut (jelek) di Ruby adalah normatif sehubungan dengan output non-spasi. Perhatikan khususnya render
metode ini:
def pad ary
row = ary.first.map{-1}
([row] + ary + [row]).map{|r| [-1] + r + [-1]}
end
def parse str
str.split("\n").map{|r| r.chars.map(&{" " => -1, "*" => Float::INFINITY})}
end
def squares ary, size
ary.each_cons(size).map do |rows|
rows.map{|row| row.each_cons(size).to_a}.transpose
end
end
def consmap2d ary, size
squares(ary, size).map{|sqrow| sqrow.map{|sq| yield sq}}
end
def relax ary
loop do
new = consmap2d(pad(ary), 3){|sq| sq[1][1] == -1 ? -1 : sq.flatten.min + 1}
return new if new == ary
ary = new
end
end
def semidouble ary, op
ary.zip(ary.each_cons(2).map{|r1,r2|r1.zip(r2).map(&op)}).flatten(1).compact.transpose
end
def heightmap str
relax(semidouble(semidouble(semidouble(semidouble(pad(parse str),:max),:max),:min),:min))
end
def render heightmap
puts consmap2d(heightmap, 3){|sq|
next " " if sq[1][1] == -1
hwall = sq[0][1] == -1 || sq[2][1] == -1
vwall = sq[1][0] == -1 || sq[1][2] == -1
next "+" if hwall && vwall
next "-" if hwall
next "|" if vwall
next "+" if sq.flatten.min == -1
nws = sq[0][1] == sq[1][0]
nes = sq[0][1] == sq[1][2]
sws = sq[2][1] == sq[1][0]
ses = sq[2][1] == sq[1][2]
next "X" if nws && nes && sws && ses
next "V" if nws && nes
next "^" if sws && ses
next ">" if nws && sws
next "<" if nes && ses
next "/" if nes && sws
next "\\" if nws && ses
next " " if sq[0][1] != sq[2][1] || sq[1][0] != sq[1][2]
next "|" if sq[0][1] == sq[1][1]
next "-" if sq[1][0] == sq[1][1]
??
}.map(&:join)
end
render heightmap $<.read if __FILE__ == $0
*
. Kalau tidak, itu mungkin sudah cukup.[[0,1,1],[1,0,1],[1,1,1]]
input yang valid? (Input tidak memiliki "lubang", tetapi ada sudut sial di dekat persimpangan-sendiri.)Jawaban:
Python 2, 500 byte
Lelah bermain golf, dan saya mendapat skor bulat yang bagus, jadi ini dia.
Lekukan delapan spasi adalah tab.
Lewatkan matriks biner di atas STDIN, seperti:
sumber