ASCII में कूल्हे की छत के ऊपरी-नीचे के दृश्य को रेंडर करें


23

सबसे पहले, कुछ शब्दावली ( स्रोत ):

  • एक कूल्हे की छत (विकिपीडिया को उद्धृत करते हुए) "एक प्रकार की छत है जहाँ सभी पक्ष दीवारों की ओर नीचे की ओर ढल जाते हैं, आमतौर पर एक पर्याप्त ढलान के साथ"
  • ढलान एक प्लैनर सतह है जो छत का एक हिस्सा है
  • एक रिज एक किनारा है जहां दो विपरीत छत के ढलान मिलते हैं
  • एक कूल्हे एक उत्तल किनारे है जहां लंबवत दीवारों से संबंधित दो ढलान मिलते हैं
  • एक घाटी एक अवतल छोर है जहां लंबवत दीवारों से संबंधित दो ढलान मिलते हैं
  • कूल्हों और घाटियों को सामूहिक रूप से विकर्ण किनारों के रूप में संदर्भित किया जाएगा।

संभव इनपुट:

 ** * ***
******** 
 ** *  **

संगत उत्पादन:

    +-------+   +---+   +-----------+
    |\     /|   |\ /|   |\         /|
    | \   / |   | V |   | \   ^---< |
    |  \ /  |   | | |   |  \ / \   \|
+---+   V   +---+ | +---+   X   +---+
|\   \  |  /     \|/     \ / \  |
| >---> | <-------X-------V   > |
|/   /  |  \     /|\         /| |
+---+   ^   +---+ | +-------+ | +---+
    |  / \  |   | | |       | |/   /|
    | /   \ |   | ^ |       | /---< |
    |/     \|   |/ \|       |/     \|
    +-------+   +---+       +-------+

कुछ और परीक्षण मामले:

** ***   *    *   * *
*       ***   *****  
    ** *****  *****  
* *  *  ***  *** *** 
* ****   *     * *   

अनुरूप आउटपुट:

+-------+   +-----------+           +---+               +---+           +---+   +---+
|\     /|   |\         /|           |\ /|               |\ /|           |\ /|   |\ /|
| \---< |   | >-------< |           | V |               | V |           | V |   | X |
| |\   \|   |/         \|           | | |               | | |           | | |   |/ \|
| | +---+   +-----------+       +---+ | +---+           | | +-----------+ | |   +---+
| | |                           |\   \|/   /|           | |/             \| |
| ^ |                           | \   V   / |           | <               > |
|/ \|                           |  \     /  |           |  \             /  |
+---+           +-------+   +---+   \   /   +---+       |   \-----------/   |
                |\     /|   |\   \   \ /   /   /|       |   |\         /|   |
                | >---/ |   | >--->   X   <---< |       |   | \       / |   |
                |/   /| |   |/   /   / \   \   \|       |   |  \     /  |   |
+---+   +---+   +---+ | |   +---+   /   \   +---+   +---+   ^   +---+   ^   +---+
|\ /|   |\ /|       | | |       |  /     \  |       |\   \ / \  |   |  / \ /   /|
| V |   | V |       | | |       | /   ^   \ |       | >---V   > |   | <   V---< |
| | |   | | |       | | |       |/   /|\   \|       |/       /| |   | |\       \|
| | |   | | +-------+ | |       +---+ | +---+       +-------+ | |   | | +-------+
| | |   | |/         \| |           | | |                   | | |   | | |
| ^ |   | /-----------\ |           | ^ |                   | ^ |   | ^ |
|/ \|   |/             \|           |/ \|                   |/ \|   |/ \|
+---+   +---------------+           +---+                   +---+   +---+

आपका इनपुट एक बिटमैप होगा - वर्ग पिक्सल का एक 2 डी सरणी - उस क्षेत्र का जिसे छत से कवर किया जाना चाहिए। आप मान सकते हैं कि इस क्षेत्र की सीमा एक जॉर्डन वक्र होगी - अर्थात्, निरंतर और गैर-आत्म-प्रतिच्छेदन - अर्थात् छत वाला क्षेत्र निरंतर होगा, बिना छेद के और एक ही बिंदु पर चार दीवारों की बैठक कभी नहीं होगी। मान्य इनपुट स्वरूपों में न्यूलाइन सेपरेटर के साथ एक स्ट्रिंग, स्ट्रिंग की एक सूची और चार्ट या बूलियन का 2 डी सरणी शामिल है।

छत के निर्माण के नियम हैं:

  • छत वाले क्षेत्र के प्रत्येक सीधे सेगमेंट (इसके बाद दीवार के रूप में संदर्भित) में ठीक एक पास की ढलान होगी। ढलान दीवार से दूर हो जाएगा। प्रत्येक ढलान में कम से कम एक समीप की दीवार होगी, और एक ढलान से सटे सभी दीवारों को समतल होना चाहिए।
  • सभी ढलानों में क्षैतिज सतह के खिलाफ समान (नॉनजो) कोण होगा। यानी उनके पास एक ही पिच होनी चाहिए।
  • ढलान एक सतह का निर्माण करेगा जिसकी सीमा छत वाले क्षेत्र की सीमा है। यही है, ढलान के अलावा किसी भी सतहों का उपयोग नहीं किया जा सकता है।
  • कोई भी परिदृश्य जहां एक से अधिक समाधान (वर्टिकल स्केलिंग तक) की अनुमति है, इस विनिर्देश द्वारा विनिर्देश में एक बग माना जाता है। कोई भी सुधार पूर्वव्यापी रूप से लागू होता है।

समान रूप से, छत को नियम द्वारा परिभाषित किया जा सकता है कि छत के प्रत्येक बिंदु को उस छत के लिए अधिकतम ढलान से अधिक के बिना संभव के रूप में रखा गया है, जैसा कि टॉप-डाउन दृश्य में चेबीशेव दूरी का उपयोग करके मापा जाता है ।

आपका आउटपुट छत का एक ASCII कला प्रतिनिधित्व होगा - या तो एक ही स्ट्रिंग जिसमें नईलाइन वर्ण या स्ट्रिंग की एक सरणी होती है, प्रत्येक आउटपुट की एक पंक्ति को दर्शाती है। छत को 4x पैमाने पर टॉप-डाउन दृश्य में प्रस्तुत किया जाएगा - अर्थात, फर्श-प्लान के प्रत्येक वर्ग को आउटपुट के 5x5 क्षेत्र को प्रभावित करना चाहिए, जैसे कि इस 5x5 क्षेत्र के कोनों को पड़ोसी वर्गों (जैसे: प्रत्येक) के साथ साझा किया जाता है। कोने का चरित्र चार अलग-अलग इनपुट वर्गों से प्रभावित होता है), उदाहरण के आउटपुट से संकेत मिलता है। जब तक आउटपुट आकृति संरक्षित है तब तक अतिरिक्त व्हाट्सएप की अनुमति है। उत्पादन में वर्ण होंगे:

  • पर्यावरण-परिभाषित न्यूलाइन मार्कर का उपयोग किया जाएगा (आमतौर पर यू + 000 ए, यू + 000 डी या दोनों की एक जोड़ी) यदि आउटपुट एक स्ट्रिंग के रूप में है
  • (U + 0020 स्पेस) एक छत वाले क्षेत्र के बाहर एक बिंदु या ढलान के लिए एक बिंदु इंटीरियर का प्रतिनिधित्व करता है
  • + (U + 002B प्लस साइन) एक बिंदु का प्रतिनिधित्व करता है जिसमें दो लंबवत दीवारें होती हैं
  • - (U + 002D हाइफ़न-माइनस) एक दीवार या रिज उन्मुख क्षैतिज (पूर्व-पश्चिम) का प्रतिनिधित्व करता है
  • / (U + 002F सॉलिडस) एक कूल्हे या घाटी को उन्मुख करता है जो उत्तर-पूर्व से दक्षिण-पूर्व में या दो में से एक बिंदु से सटा हुआ है
  • < (U + 003C कम-से-साइन) एक बिंदु को दो विकर्ण किनारों के साथ दर्शाता है जो पूर्व में इसके साथ जुड़ा हुआ है
  • > (U + 003E अधिक से अधिक संकेत) पश्चिम में उस पर सटे हुए दो विकर्ण किनारों के साथ एक बिंदु का प्रतिनिधित्व करता है
  • \ (U + 005C रिवर्स सॉलिडस) एक हिप या वैली ओरिएंटेड नॉर्थ-वेस्ट को साउथ-ईस्ट या एक प्वाइंट को दर्शाता है, जो दो में से एक है
  • ^ (U + 005E परिधि उच्चारण) दो बिंदुओं के साथ एक बिंदु का प्रतिनिधित्व करता है, जो दक्षिण में स्थित है
  • V (U + 0056 लैटिन कैपिटल लेटर v) उत्तर में उस पर सटे हुए दो विकर्ण किनारों के साथ एक बिंदु का प्रतिनिधित्व करता है
  • X (U + 0058 लैटिन कैपिटल लेटर x) एक बिंदु का प्रतिनिधित्व करता है जिसमें विकर्ण किनारों के साथ सभी चार तरफ होते हैं
  • | (U + 007C वर्टिकल बार) एक दीवार या रिज ओरिएंटेड वर्टिकली (उत्तर-दक्षिण) को दर्शाता है

ध्यान दें कि विषम संख्या में विकर्ण किनारों के लिए एक ही बिंदु पर समाप्त होना संभव नहीं है (दीवारों पर छोड़कर)। हम कल्पना कर सकते हैं कि प्रत्येक बिंदु के पड़ोस को उत्तर ढलान + दक्षिण ढलान में और पूर्व ढलान + पश्चिम ढलान में विभाजित किया जाए। दोनों विभाजनों के बीच की सीमा को विकर्ण किनारों से बना होना चाहिए।

यदि आपका वातावरण ASCII के साथ असंगत एक वर्ण एन्कोडिंग का उपयोग करता है, तो आप अपने वातावरण के एन्कोडिंग चरित्र में समान वर्ण (समान ग्लिफ़ या निकटतम उपलब्ध) का उपयोग कर सकते हैं।

रूबी में निम्नलिखित (बदसूरत) संदर्भ कार्यान्वयन गैर-व्हाट्सएप आउटपुट के संबंध में मानक है। विशेष रूप से renderविधि पर ध्यान दें :

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 

1
आपको अधिक परीक्षण मामलों को जोड़ना चाहिए।
mbomb007

@ mbomb007 जोड़ा गया। वे जो स्थान लेते हैं, उसे देखते हुए - क्या मुझे और जोड़ना चाहिए?
जॉन ड्वोरक

@JDDvorak शायद परीक्षण मामले को जोड़ते हैं *। नहीं तो शायद इतना ही काफी है।
mbomb007

है [[0,1,1],[1,0,1],[1,1,1]]मान्य इनपुट? (इनपुट में "छेद" नहीं है, लेकिन आत्म-चौराहे के पास एक पेस्की कॉर्नर है।)
लिन

@Lynn आपको उस मामले के बारे में चिंता करने की ज़रूरत नहीं है, यह वैध इनपुट नहीं है। आप जिस कोने का उल्लेख करते हैं, वह एक आत्म-प्रतिच्छेद सीमा (या बल्कि, एक सीमा जो वक्र नहीं है) के रूप में गिना जाता है।
जॉन डेवोरक

जवाबों:


11

पायथन 2, 500 बाइट्स

z=input()
W=4*len(z[0])+1
H=4*len(z)+1
R=range
s=[-~W*[0]for _ in R(-~H)]
for y in R(H/4):
 for x in R(W/4):
        for h in R(25):s[y*4+h%5][x*4+h/5]|=z[y][x]
F=[(x/3-1,x%3-1)for x in[1,7,3,5,0,6,8,2]]
exec'for y in R(H):\n for x in R(W):s[y][x]+=0<s[y][x]<=min(s[y+d][x+e]for(e,d)in F)\n'*H
for y in R(H):
 l=''
 for x in R(W):h=s[y][x];a=[s[y+d][x+e]for(e,d)in F[:4]];l+=r' XabcVde^f ||g>h\\+//+<<jk<l//+\\+>>m --^^oVVqrX'[h and int(''.join(`int(n==h)`for n in a),2)*3+((h==1)*2or max(a)==h)+1]
 print l

यह नीचे गोल्फ से थक गया, और मैं एक अच्छा दौर स्कोर करने के लिए मिला है, तो यहाँ यह है।

आठ-अंतरिक्ष इंडेंटेशन एक टैब है।

STDIN पर एक बाइनरी मैट्रिक्स पास करें, जैसे:

python2.7 roof.py <<<"[[1,1,0,1,1,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0], [1,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,0], [0,0,0,0,1,1,0,1,1,1,1,1,0,0,1,1,1,1,1,0], [1,0,1,0,0,1,0,0,1,1,1,0,0,1,1,1,0,1,1,1], [1,0,1,1,1,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0]]"

पूरी तरह से गोल्फ या नहीं, यह अद्भुत है। बहुत बढ़िया। +1
आर। कप
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.