एक ASCII बहुभुज का क्षेत्र


31

आपको एक प्रोग्राम या फ़ंक्शन लिखना चाहिए जो इनपुट के रूप में एससी-कला बहुभुज का प्रतिनिधित्व करने वाला एक स्ट्रिंग प्राप्त करता है और आउटपुट ओटी बहुभुज के क्षेत्र को रिटर्न करता है।

इनपुट एक स्ट्रिंग है जिसमें वर्ण शामिल होते हैं _ / \ L V spaceऔर newlineएक साधारण बहुभुज को परिभाषित करते हैं (जिसका अर्थ है कोई अतिरिक्त खंड, कोई आत्म-स्पर्श और कोई आत्म-प्रतिच्छेद नहीं)।

एकल चरित्र कोशिका का क्षेत्र है 2

  • _सेल को आकार में विभाजित करता है 0और2
  • \सेल को आकार में विभाजित करता है 1और1
  • /सेल को आकार में विभाजित करता है 1और1
  • Lसेल को आकार में विभाजित करता है 0और2
  • Vसेल को आकार में विभाजित करता है 1और 1( Vवसीयत के दो पहलू हमेशा बहुभुज के एक ही तरफ होंगे ताकि उनका सूचीकरण में इलाज हो।)

प्रत्येक चरित्र अपने चरित्र सेल के दो कोनों को जोड़ता है जिसकी आप अपेक्षा करते हैं (उदाहरण के मामले में शीर्ष बाएं और शीर्ष दाएं V)।

7 के क्षेत्र के साथ एक उदाहरण ( 1+2+1दूसरी पंक्ति 1+1+1में और तीसरे एक में):

 _
/ \
V\/

इनपुट

  • इनपुट आयत का निर्माण करेगा, यानी नए अक्षरों के बीच समान वर्ण होंगे।
  • बहुभुज के किसी भी तरफ अतिरिक्त व्हाट्सएप हो सकता है।
  • अनुगामी न्यूलाइन वैकल्पिक है।

उत्पादन

  • एक भी सकारात्मक पूर्णांक, बहुभुज का क्षेत्र।

उदाहरण

आउटपुट उनके इनपुट की अंतिम पंक्ति के बाद हैं।

  _  
  V  

1

/L
\/

3



    /VV\
    L  /
     L/
14

  ____/\ 
  \    /
/\/   /
\____/

32  

   /V\
  /   \__ 
  \     /
/\/   /V
L____/

45

यह कोड-गोल्फ है इसलिए सबसे छोटी प्रविष्टि जीतती है।


आपका तीसरा उदाहरण 14
ऑप्टिमाइज़र

@Optimizer धन्यवाद, सही किया गया।
बेतरतीब

क्या ^ जानबूझकर की कमी है ?
रॉबू

@RobAu हाँ, यह काफी अच्छा नहीं लगता है।
12

जवाबों:


5

CJam, 48 43 29 बाइट्स

qN-{i_9%2%U!^:U;J%D%1U2*?}%:+

अद्यतन : orlp के उत्तर से गणित और राज्य * 2 चाल का उपयोग करके बहुत कुछ गढ़ा।

यह कैसे काम करता है (आउटडेटेड, जल्द ही अपडेट करना)

हम इनपुट को न्यूलाइन पर विभाजित करते हैं और फिर प्रत्येक भाग के लिए हम सीमा पात्रों की घटनाओं का एक काउंटर बनाए रखते हैं L\/। यह काउंटर% 2 हमें बताएगा कि सभी वर्णों में से कौन सा विभाजन चुनने के लिए है। फिर हम स्ट्रिंग में प्रत्येक वर्ण का सूचकांक पाते हैं L _। एक सरणी में अंतिम तत्व का जिक्र \/Vकरेंगे -1। सूचकांक प्राप्त करने के बाद, हम 4558Zb2/सरणी बनाने के लिए उपयोग करते हैं [[2 0] [0 2] [0 2] [1 1]]और फिर काउंटर का उपयोग करके गिनती का सही चयन करते हैं।

qN/0f{                                  }      e# Split the input on newline and for each
      \{                             }/        e# swap the 0 to back and for each char in
                                               e# the line, run this loop
        _"L _"#                                e# Copy the char and get index of it in
                                               e# this string "L _"
               4558Zb                          e# This is basically 4558 3base
                                               e# which comes to be [2 0 0 2 0 2 1 1]
                     2/=                       e# Group into pairs of 2 and choose the
                                               e# correct one.
                        2$=                    e# Based on the counter, choose the correct
                                               e# partition amount
                           @@"\/L"&,+          e# Increment the counter if the char is one
                                               e# of \, / and L
                                       ;       e# Pop the counter after each line loop
                                         :+    e# Sum all the numbers to get area

इसे यहाँ ऑनलाइन आज़माएँ


22

पायथ, 47 46 45 36 30

FNs.zx=Z}N"\/L"aY|}N"\/V"yZ;sY

स्पष्टीकरण:

FNs.z            For every character in input, except newlines...
  x=Z}N"\/L"     Swap state if /, \, or L.
  aY|}N"\/V"yZ;  Append 1 if /, \, or V, else 2 times the state to Y.
sY               Sum Y and print.

हमारे पास दो राज्य हैं, "बहुभुज में", और "बहुभुज से बाहर"। निम्न वर्ण प्रत्येक को निम्न करते हैं, जब उन्हें ऊपर-बाएँ से नीचे-दाएँ पढ़ा जाता है:

/ \     swap state, add one to area
V                   add one to area
_ space             if in polygon, add two to area
L       swap state, if in polygon, add two to area

ध्यान दें कि "एक क्षेत्र में जोड़ें" और "यदि बहुभुज में, दो को क्षेत्र में जोड़ें" परस्पर अनन्य हैं।


मैं वास्तव में उलझन में हूं कि कैसे x=काम करता है। क्या यह कहीं दस्तावेज है?
जक्यूब

@ जाकुब यह संवर्धित कार्य है।
orlp

@Jakube ऐसा लगता है की +=या *=या जो कुछ भी। इस मामले xमें एक्सोर के रूप में उपयोग किया जा रहा है, इसलिए यह बिल्कुल पायथन के समान है ^=
isaacg

14

रेटिना , 293 + 15 = 308 314 385 बाइट्स

;`\s
_
;`\\
/
;`.+
o$0iio
;+`(o(?=/.*(i)|L.*(ii)|V.*(io)|_)|i(?=/.*(io)|L.*(o)|_.*(ii)|V.*(i))).
$1$2$3$4$5$6$7$8
;`o
<empty>
;`ii$
#:0123456789
;+`^(?=i)(i*)\1{9}(?=#.*(0)|i#.*(1)|ii#.*(2)|iii#.*(3)|iiii#.*(4)|iiiii#.*(5)|iiiiii#.*(6)|iiiiiii#.*(7)|iiiiiiii#.*(8)|iiiiiiiii#.*(9))
$1#$2$3$4$5$6$7$8$9$10$11
:.*|\D
<empty>

प्रत्येक पंक्ति एक अलग फ़ाइल में जाती है, इसलिए मैंने बाइट संख्या में 13 जोड़ दिए हैं। वैकल्पिक रूप से, आप उस सभी को एकल फ़ाइल में रख सकते हैं और -sध्वज का उपयोग कर सकते हैं । <empty>वास्तव में खाली फाइल या लाइनों के लिए खड़े।

दुर्भाग्य से, परिणाम को दशमलव से दशमलव में बदलने के लिए मुझे 187 बाइट्स की आवश्यकता है। मुझे लगता है कि मुझे वास्तव में इसे जल्द ही लागू करना चाहिए ।

व्याख्या

रेटिना एक रेगेक्स-आधारित भाषा है (जो मैंने रेगेक्स के साथ इस तरह से सामान करने में सक्षम होने के लिए लिखा था)। फ़ाइलों / लाइनों की प्रत्येक जोड़ी एक प्रतिस्थापन चरण को परिभाषित करती है, जिसमें पहली पंक्ति पैटर्न और दूसरी पंक्ति प्रतिस्थापन स्ट्रिंग होती है। पैटर्नों को पूर्व- `निर्धारित कॉन्फ़िगरेशन स्ट्रिंग द्वारा पूर्ववर्ती किया जा सकता है , जिसमें सामान्य रेगेक्स संशोधक, साथ ही कुछ रेटिना-विशिष्ट विकल्प भी हो सकते हैं। उपरोक्त कार्यक्रम के लिए, प्रासंगिक विकल्प हैं ;, जो उस चरण के आउटपुट को दबा देता है और +, जो परिणाम बदलने तक एक लूप में प्रतिस्थापन को लागू करता है।

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

मैं वर्णों के साथ वर्तमान / अंदर के राज्य का ट्रैक रख रहा हूं iऔर o, iक्षेत्र का मिलान करने के लिए भी । ऐसा करने के लिए मैं oजुड़ने के लिए एक लाइन से जुड़कर शुरू करता हूं कि हम बहुभुज के बाहर हैं। मैं iioइनपुट के बहुत अंत में भी जोड़ रहा हूं , जिसे मैं नए वर्ण उत्पन्न करने के लिए लुकअप के रूप में उपयोग करूंगा।

फिर, पहला बड़ा प्रतिस्थापन केवल एक iया oउसके बाद /V_Lके वर्णों के अगले सेट के साथ बदल देता है , जिससे पूरी चीज़ में बाढ़ आ जाती है। प्रतिस्थापन तालिका निम्नानुसार दिखती है, जहां स्तंभ उस पंक्ति के अंतिम वर्ण और अगले वर्ण की पंक्तियों (जहां Sस्थान के लिए और <>रिक्त स्ट्रिंग के लिए है) के अनुरूप हैं । मैंने पहले से उपयोग किए गए समतुल्यों को दिखाने के लिए इनपुट के सभी वर्णों को शामिल किया है:

     i     o

/    io    i
\    io    i
L    o     ii
V    i     io
_    ii    <>
S    ii    <>

ध्यान दें कि अंतिम वर्ण हमेशा इंगित करता है कि क्या चरित्र के बाद हम बहुभुज के अंदर या बाहर हैं, जबकि s की संख्या iउस क्षेत्र से मेल खाती है जिसे बहुभुज में जोड़ने की आवश्यकता है। एक उदाहरण के रूप में यहां अंतिम उदाहरण इनपुट पर पहले चार पुनरावृत्तियों के परिणाम हैं (यह एक पुराने संस्करण द्वारा उत्पन्न किया गया था जो वास्तव में प्रत्येक पंक्ति को अलग से बाढ़ देता था, लेकिन सिद्धांत अभी भी समान है):

o   /V\
o  /   \___
o  L     _/
o/\/   /V
oL__ _/
o   V

o  /V\
o /   \___
o L     _/
oi\/   /V
oii__ _/
o  V

o /V\
o/   \___
oL     _/
oiio/   /V
oiiii_ _/
o V

o/V\
oi   \___
oii     _/
oiioi   /V
oiiiiii _/
oV

oiV\
oiii  \___
oiiii    _/
oiioiii  /V
oiiiiiiii_/
oio

अंत में, मैं बस सभी os और लाइन से छुटकारा पा लेता हूं जो कि मेल खाता है सब कुछ हटाकर [^i], और शेष दशमलव-से-एकात्मक रूपांतरण है जो उबाऊ है।


4

पर्ल, 65 58 बाइट्स

map{map{$b^=2*y,/\\L,,;$a+=y,/\\V,,||$b}split//}<>;print$a
  • 0/2 को देखने / / या L के बीच $ b टॉगल करें।
  • देखने / / या देखने पर 1 से $ जोड़ें।
  • कुछ भी देखने पर $ b को $ a में जोड़ें।

अच्छा समाधान, पर्ल आश्चर्यजनक रूप से कॉम्पैक्ट है।
orlp

1
इनपुट प्रोसेसिंग को कुछ और लाभ के लिए सरल बनाया जा सकता है:$/=\1;$-^=2*y,/\\L,,,$a+=y,/\\V,,||$-for<>;print$a
नटकी

4

GNU सेड, 290 + 1

+ 1 -rको सीड पास करने वाले स्विच का हिसाब देना है। टिप्पणियाँ और अतिरिक्त व्हाट्सएप की गिनती स्कोर में नहीं की गई।

मैंने बहुत विस्तार से नहीं देखा है, लेकिन मुझे लगता है कि यह शायद मार्टिन के रेटिना उत्तर के समान है :

:                      # label to start processing next (or first) line
s/[0-9]//g             # remove the count of colons from previous lines
H                      # append the current line to the hold space
g                      # copy the hold space to the pattern space
y^_\\^ /^              # Replace '_' with ' ' and replace '\' with '/'
s/(\n| +$)//g          # strip newlines and trailing space
:o                     # start of "outside loop"
s/(^|:) *V/\1:/        # replace leading spaces and "V" with ":"
to                     #   if the above matches, stay outside
s/(^|:) *[|/]/\1:/     # replace leading spaces and "|" or "/" with ":"
ti                     #   if the above matches, go inside
s/(^|:) *L/\1::/       # replace leading spaces and "L" with "::"
:i                     # start of "inside" loop
s/: /:::/              # replace space with "::"
ti                     #   if the above matches, stay inside
s/:V/::/               # replace "V" with ":"
ti                     #   if the above matches, stay inside
s/:[|/]/::/            # replace "|" or "/" with ":"
to                     #    if the above matches, go outside
s/:L/:/                # remove "L"
to                     #    if the above matches, go outside
h                      # copy current string of colons to hold buffer
:b                     # start of colon count loop
s/:{10}/</g            # standard sed "arithmetic" to get string length
s/<([0-9]*)$/<0\1/
s/:{9}/9/
s/:{8}/8/
s/:{7}/7/
s/:{6}/6/
s/:{5}/5/
s/::::/4/
s/:::/3/
s/::/2/
s/:/1/
s/</:/g
tb                     # once arithmetic done, pattern buffer contains string length
N                      # append newline and next line to pattern buffer
b                      # loop back to process next line

अवलोकन

  • क्षेत्र की प्रत्येक इकाई को कोलन से बदलें :
  • कॉलनों की संख्या गिनें

टिप्पणियाँ

  • sedलाइन ओरिएंटेड है इसलिए एक बार में कई लाइनों को प्रोसेस करने के लिए कुछ काम की आवश्यकता होती है। Nआदेश तो मौजूदा पैटर्न अंतरिक्ष के लिए अगली पंक्ति एक नई पंक्ति जोड़कर करता है। इसके साथ कठिनाई Nयह है कि एक बार जब यह इनपुट स्ट्रीम EOF को मिल जाता है, तो यह sedआगे की प्रक्रिया करने के लिए किसी भी विकल्प के बिना पूरी तरह से क्विट करता है। इसके चारों ओर जाने के लिए, हम अगली पंक्ति में पढ़ने से पहले प्रत्येक पंक्ति के अंत में कॉलनों के वर्तमान सेट को गिनते हैं।

आउटपुट:

$ echo '   /V\
  /   \__ 
  \     /
/\/   /V
L____/' |sed -rf polyarea.sed
45
$

3

सी, 93 96 108 बाइट्स

संपादित करें: टिप्पणियों में खाते के सुझावों को लिया, जबकि लूप के लिए एकल-कथन में परिवर्तित किया, और "i" चर को पूरी तरह से हटा दिया।

int s,t;main(c,v)char**v;{for(;c=*v[1]++;t+=s+(c>46^!(c%19)^s))s^=c>13^c%9>4;printf("%d",t);}

मूल पोस्ट:

यह एक मजेदार और सरल पर्याप्त समस्या की तरह लग रहा था, आखिरकार मुझे यहां एक खाता बनाने के लिए मिला।

main(c,v)char**v;{int i,t,s;i=t=s=0;while(c=v[1][i++]){s^=c>13^c%9>4;t+=s+(c>46^!(c%19)^s);}printf("%d",t);}

बहुभुज पाठ को पहले कमांड-लाइन तर्क के रूप में पारित किया जाना चाहिए; यह किसी भी मात्रा में newlines / व्हाट्सएप के साथ या उसके बिना काम करना चाहिए।

यह सिर्फ एक समय में बहुभुज एक वर्ण में पढ़ता है, स्विच करता है कि क्या वर्तमान में या इसके बाहर बहुभुज पर '/', 'L', या '\' है, और t '/', 'V' पर 1 से बढ़ता है, और '\', या 2 से अगर अंदर / 0 अगर बाहर 'एल', '_', स्पेस और न्यूलाइन पर।

यह मेरी पहली बार है कि मैं किसी भी तरह के "गोल्फिंग" (या सी, सी ++ से भिन्न होता है) में हाथ आजमा रहा हूं, इसलिए किसी भी आलोचना की सराहना की जाती है!


आपका स्वागत है और अच्छी नौकरी! आप i=t=s=0;मुझे लगता है कि सी को छोड़ सकते हैं सभी intको वैसे भी 0 से आरंभ करता है। इसके अलावा, देखें कि क्या आप whileलूप को लूप में बदल सकते हैं for; वह अक्सर कुछ बाइट्स बचाता है।
यपनिप

ऊपर के लूप के विचार का उपयोग करना मुझे लगता है कि आप कुछ ऐसा कर सकते हैं: ...int i,t,s;for(i=t=s=0;c=v[1][i++];t+=s+(c>46^!(c%19)^s))s^=c>13^c%9>4;...जिसे 4 बाइट्स बचाने चाहिए; एक {, एक} और दो;
DaedalusAlpha

जैसा कि ऊपर बताया गया है, जाहिरा तौर पर वैश्विक चर स्वचालित रूप से 0 पर सेट होते हैं, इसलिए यदि अंदर int i,t,v;के mainबजाय सामने रखा जाए तो हम i=t=s=0एक और 7 बाइट्स को पूरी तरह से बचा सकते हैं ।
DaedalusAlpha

3

पोसिक्स सेड, 245 244

POSIX sed, कोई एक्सटेंशन या विस्तारित rexxps नहीं। इनपुट सेड के अधिकतम होल्ड स्पेस साइज तक सीमित है - POSIX में कम से कम 8192 अनिवार्य है; जीएनयू अधिक प्रबंधन करता है। यह संस्करण मानता है कि आकृति के पहले या बाद में कोई रिक्त रेखा नहीं होगी; एक अतिरिक्त 10 बाइट्स कोड, जिसे विस्तार में संकेत दिया गया है, वह समायोजित कर सकता है यदि यह एक आवश्यकता है (मूल प्रश्न निर्दिष्ट नहीं करता है)।

H
/^\([L\\]_*\/\|V\| \)*$/!d
x
s/[_ ]/  /g
s/^/!/
s/$/!/
:g
s/\([^V]\)V/V\1/
tg
y/V/ /
s/L/!  /g
s,[/\\], ! ,g
s/![^!]*!//g
:d
/ /{
s/     /v/g
s/vv/x/g
/[ v]/!s/\b/0/2
s/  /b/g
s/bb/4/
s/b /3/
s/v /6/
s/vb/7/
s/v3/8/
s/v4/9/
y/ bvx/125 /
td
}

विस्तारित और एनोटेट

#!/bin/sed -f

# If leading blank lines may exist, then delete them
# (and add 8 bytes to score)
#/^ *$/d

# Collect input into hold space until we reach the end of the figure
# The end is where all pieces look like \___/ or V
H
/^\([L\\]_*\/\|V\| \)*$/!d

x

# Space and underscore each count as two units
s/[_ ]/  /g

# Add an edge at the beginning and end, so we can delete matching pairs
s/^/!/
s/$/!/
# Move all the V's to the beginning and convert each
# to a single unit of area
:gather
s/\([^V]\)V/V\1/
tgather
y/V/ /

# L is a boundary to left of cell; / and \ in middle
s/L/!  /g
s,[/\\], ! ,g

# Strip out all the bits of outer region
s/![^!]*!//g

# Now, we have a space for each unit of area, and no other characters
# remaining (spaces are convenient because we will use \b to match
# where they end).  To count the spaces, we use roman numerals v and x
# to match five and ten, respectively.  We also match two (and call
# that 'b').  At the end of the loop, tens are turned back into spaces
# again.
:digit
/ /{
s/     /v/g
s/vv/x/g
/[ v]/!s/\b/0/2
s/  /b/g
s/bb/4/
s/b /3/
s/v /6/
s/vb/7/
s/v3/8/
s/v4/9/
y/ bvx/125 /
tdigit
}

# If trailing blank lines may exist, then stop now
# (and add 2 bytes to score)
#q

1

सी, 84 बाइट्स

a;i;f(char*s){for(;*s;a+=strchr("\\/V",*s++)?1:i+i)i^=!strchr("\nV_ ",*s);return a;}

जब भी हम देखते हैं \, /या L; हम हमेशा एक को जोड़ते हैं \\, /या V, लेकिन 2, (अगर अंदर) या 0 (यदि बाहर) जोड़ते हैं, तो अंतरिक्ष, न्यूलाइन Lया _

चर aऔर iमाना जाता है कि प्रवेश पर शून्य है - उन्हें रीसेट किया जाना चाहिए यदि फ़ंक्शन को एक से अधिक बार कॉल किया जाना है।

Ungolfed:

int a;                          /* total area */
int i;                          /* which side; 0=outside */
int f(char*s)
{
    while (*s) {
        i ^= !strchr("\nV_ ",*s);
        a += strchr("\\/V",*s++) ? 1 : i+i;
    }
    return a;
}

परीक्षण कार्यक्रम:

#include <stdio.h>
int main()
{
    char* s;
    s = "  _  \n"
        "  V  \n";
    printf("%s\n%d\n", s, f(s));
    a=i=0;

    s = "/L\n"
        "\\/\n";
    printf("%s\n%d\n", s, f(s));
    a=i=0;


    s = "    /VV\\\n"
        "    L  /\n"
        "     L/";
    printf("%s\n%d\n", s, f(s));
    a=i=0;

    s = "  ____/\\ \n"
        "  \\    /\n"
        "/\\/   /\n"
        "\\____/";
    printf("%s\n%d\n", s, f(s));
    a=i=0;

    s = "   /V\\\n"
        "  /   \\__ \n"
        "  \\     /\n"
        "/\\/   /V\n"
        "L____/";
    printf("%s\n%d\n", s, f(s));
    a=i=0;

    return 0;
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.