वोरोनोई आरेख बनाएं (ASCII संस्करण)


24

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

निम्नलिखित व्यवहार के साथ एक प्रक्रिया उपप्रोग्राम लिखें , वोरोनोई आरेख का एक प्रकार का निर्माण ...

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

आउटपुट : प्रत्येक रिक्त सीमा-सेल के साथ इनपुट स्ट्रिंग का एक प्रिंटआउट जो उस पत्र के निचले संस्करण द्वारा प्रतिस्थापित किया जाता है। (उपप्रोग्राम मुद्रण करता है।)

उदाहरण 1

इनपुट:

......B..
.........
...A.....
.........
.......D.
.........
.C.......
.....E...
.........

आउटपुट:

...ab.B..
....ab.bb
...A.abdd
aa...ad..
cca.ad.D.
..caeed..
.C.ce.edd
..ce.E.ee
..ce.....

सीमाओं को उजागर करने वाला एक स्केच:

सीमाओं को उजागर करने वाला एक स्केच

उदाहरण 2

इनपुट:

............................U...........
......T.................................
........................................
.....................G..................
..R.......S..........F.D.E............I.
.........................H..............
.....YW.Z...............................
......X.................................
........................................
........................................
......MN...........V....................
......PQ................................
........................................
.............L...............J..........
........................................
........................................
....C...........K.......................
........................................
..................................A.....
...........B............................

आउटपुट:

..rt.....ts...sg......gduu..U.....ui....
..rt..T..ts...sg......gddeu......ui.....
...rt...ts....sg......gddeeu....ui......
....rttts.....sggggggGgdde.euuuui.......
..R.rywss.S....sfffffFdDdEeeeeeei.....I.
...ryywwzs.....sf....fddhHhhhhhhhi......
..ryyYWwZzs..sssffff.fddh.......hi......
..rxxxXxzzs.sllvvvvvffddh....hhhhi......
rrrxxxxnzzssl.lv....vfddh...hjjjjii.....
mmmmmmmnnnnnl.lv.....vvdh..hj....jai....
mmmmmmMNnnnnl.lv...V...vvhhj.....jaai...
ppppppPQqqql...lv.......vhj......ja.ai..
ppppp.pq.ql....lkv.....vjj.......ja..aii
cccccppqql...L.lkkv...vj.....J...ja...aa
.....cpqqlll..lk..kvvvvj........ja......
......cccbbbllk....kkkkj.......ja.......
....C...cb..bk..K......kj.....ja........
.......cb....bk........kjjjjjja.........
......cb......bk.......kaaaaaa....A.....
.....cb....B...bk......ka...............

रंग वृद्धि:

रंग में वृद्धि


1
+1; दिलचस्प; लेकिन मैंने देखा कि नमूना इनपुट और आउटपुट में कोशिकाओं में प्रत्येक वर्ण के बीच पैडिंग का एक स्थान होता है। क्या यह एक आवश्यकता है?
दरवाज़े

@DoorknobofSnow - उफ़, मेरी गलती - यह अनायास ही था। मैं उन्हें हटाने के लिए संपादित करूँगा।
रेस

तो यह स्पष्ट है कि यह मैनहट्टन मीट्रिक आरेख है, यूक्लिडियन नहीं? Voronoi चित्र सुंदर गैर इयूक्लिडियन मीट्रिक रिक्त स्थान में शांत हो सकता है (देखें यहाँ , या आग ब्लेंडर यदि आप एक प्रति है, यह में बनाया कुछ दिलचस्प मीट्रिक होने के कारण)।
21

@Chargin - अनिवार्य रूप से, हाँ। यहां दो कोशिकाओं के बीच "दूरी" एक सेल से दूसरे तक चलने के लिए आवश्यक कम से कम कदम हैं, केवल क्षैतिज रूप से या लंबवत-आसन्न कोशिकाओं के बीच कदम रखते हुए। (यह हमेशा एक nonnegative पूर्णांक होता है।) यह टेक्सी मेट्रिक है यदि हम एक शहर में सड़क-चौराहों के रूप में उन कोशिकाओं की कल्पना करते हैं जिनकी सड़कें शून्य-चौड़ाई हैं और जिनके ब्लॉक इकाई वर्ग हैं।
रेस

जवाबों:


5

गोल्फस्क्रिप्ट, 138 144 137 वर्ण

:^n%,,{{^n/1$=2$>1<.'.'={;{@~@+@@+\{^3$?^<n/),\,@-abs@@-abs+99*+}++^'.
'-\$1<{32+}%}++[0..1.0..(.0]2/%..&,(\0='.'if}{@@;;}if}+^n?,%puts}/

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

कोड की व्याख्या

बाहरी ब्लॉक अनिवार्य रूप से इनपुट आयतों के आकार के अनुसार सभी स्थिति (x, y) पर लूप करता है। लूप के भीतर निर्देशांक x और y को हर बार स्टैक पर छोड़ा जाता है। प्रत्येक पंक्ति पूरी होने के बाद परिणाम कंसोल पर प्रिंट किया जाता है।

:^              # save input in variable ^
n%,,{{          # split along newlines, count rows, make list [0..rows-1] 
    ???             # loop code, see below
}+^n?,%puts}/       # ^n?, count columns, make list [0..cols-1], loop and print

लूप के भीतर निष्पादित कोड पहले इनपुट के संबंधित चरित्र को लेता है।

^n/                 # split input into lines
1$=                 # select the corresponding row
2$>1<               # select the corresponding col

तब मूल रूप से हम जांच करते हैं, अगर हमारे पास एक है ., अर्थात यदि हम (संभवतः) को चरित्र को बदलना है।

.'.'={              # if the character is '.'
    ;               # throw away the '.'
    ???             # perform more code (see below)
}{                  # else
    @@;;            # remove coordinates, i.e. keep the current character 
                    # (i.e. A, B, ... or \n)
}if                 # end if

फिर, आंतरिक कोड एक लूप के साथ शुरू होता है, अब सभी निर्देशांक (x, y) (x, y + 1) (x + 1, y) (x, y-1) (x-1, y) पर

{                   
    @~@+@@+\        # build coordinates x+dx, y+dy
    ???             # loop code
}++                 # push coordinates before executing loop code
[0..1.0..(.0]2/%    # loop over the coordinates [0 0] [0 1] [1 0] [0 -1] [-1 0]

हाल ही में आंतरिक कोड स्निपेट केवल दो बिंदुओं को देखते हुए, निकटतम बिंदु के (निचले मामले) पत्र को वापस करता है।

{                   # loop
    ^3$?^<          # find the current letter (A, B, ...) in the input string, 
                    # take anything before
    n/              # split at newlines
    ),              # from the last part take the length (i.e. column in which the letter is)
    \,              # count the number of lines remaining (i.e. row in which the letter is)
    @-abs@@-abs+    # calculate distance to the given coordinate x, y
    99*+            # multiply by 99 and add character value (used for sorting
                    # chars with equal distance)
}++                 # push the coordinates x, y
^'.
'-                  # remove '.' and newline
\$                  # now sort according to the code block above (i.e. by distance to letter)
1<{32+}%            # take the first one and make lowercase

तो निर्देशांक (x, y) (x, y + 1) (x + 1, y) (x, y-1) (x-1, y) के लिए पांच निकटतम पत्रों से पहले ले लें, यदि सभी नहीं हैं बराबर, अन्यथा एक ले लो .

.                   # copy five letter string
.&,(                # are there distinct letters?
\0=                 # first letter (i.e. nearest for coordinate x,y)
'.'                 # or dot
if                  # if command

आपके कोड ने उदाहरण 1 के साथ ठीक किया, इसलिए मुझे आश्चर्य हुआ जब उसने उदाहरण 2 में कुछ कोशिकाओं को गलत तरीके से किया: पहली तीन पंक्तियों में, यह ".यूआई" जहां "उई।" होना चाहिए, और चौथी पंक्ति में, यह "zs" डालता है जहां "s"। होना चाहिए, और "ui" डालता है जहां "मैं।" होना चाहिए, आदि आदि
Res

@res ने "समतुल्य - पहले वर्णमाला क्रम में" भाग को याद किया। दुर्भाग्य से, सॉर्ट ऑपरेशन स्थिर नहीं है। उस एक को ठीक करने के लिए कुछ वर्ण जोड़े।
हावर्ड

7

पायथन 3 - 424 422 417 332 295 वर्ण:

def v(s):
 w=s.find("\n")+1;n=(-1,1,-w,w);r=range(len(s));x=str.replace;s=x(x(s,*".~"),*"\n~")+"~"*w;t=0
 while s!=t:t=s;s=[min(s[i+j]for j in n).lower()if"~"==s[i]and(i+1)%w else s[i]for i in r]+["~"]*w
 print(x("".join(s[i]if any(s[i]!=s[i+j].lower()!="~"for j in n)else"."for i in r),*"~\n"))

तीन भाग हैं, जिनमें से प्रत्येक को पायथन के सिंटैक्स के कारण अपनी लाइन में होना चाहिए:

  1. पहली पंक्ति चरों को सेट करती है। wबोर्ड की एक पंक्ति की चौड़ाई (अंत में न्यूलाइन सहित, जिसे एक पैडिंग कॉलम के रूप में पुनर्नवीनीकरण किया जाएगा)। rएक ऐसी rangeवस्तु है जो सभी वर्णों को अनुक्रमित करती है snएक चरित्र के पड़ोसियों को प्राप्त करने के लिए अनुक्रमणिका ऑफसेट का एक टपल है (इसलिए यदि आप अक्षरों को तिरछे फैलाने की अनुमति देना चाहते हैं, तो आपको केवल -w-1,-w+1,w-1,w+1टपल में जोड़ने की आवश्यकता होगी )। विधि xका एक संक्षिप्त नाम है str.replace, जिसे बाद के कोड में कई बार उपयोग किया जाता है (हालांकि कॉल अजीब दिखेंगे, क्योंकि मैं x(s,*"xy")पारंपरिक के बजाय पात्रों को बचाने के लिए उपयोग करता हूं s.replace("x", "y"))। sपैरामीटर स्ट्रिंग के रूप में अच्छी तरह से इस बिंदु पर थोड़ा संशोधित किया जाता है, के साथ अपने .पात्रों और नई पंक्तियों से प्रतिस्थापित किया जा रहा~वर्ण (क्योंकि वे सभी पत्रों के बाद क्रमबद्ध होते हैं)। एक पंक्ति के पेडिंग ~वर्णों को अंत में जोड़ा जाता है। tबाद में के "पुराने" संस्करण के संदर्भ के रूप में उपयोग किया जाएगा s, लेकिन इसे शुरू में नहीं के बराबर कुछ के लिए आरंभीकृत किया जाना चाहिए s, और शून्य केवल एक वर्ण लेता है (एक अधिक पायथनिक मान होगा None, लेकिन वह तीन अतिरिक्त वर्ण हैं) ।
  2. दूसरी पंक्ति में एक लूप होता है जो बार-बार sसूची बोध का उपयोग करके अद्यतन करता है । जैसा कि समझ के अनुक्रमों पर पुनरावृत्ति होती है s, ~पात्रों को minउनके पड़ोसियों द्वारा प्रतिस्थापित किया जाता है। यदि एक ~चरित्र पूरी तरह से अन्य ~एस से घिरा हुआ था , तो यह कुछ भी नहीं करेगा। यदि यह एक या एक से अधिक अक्षरों के बगल में था, तो यह उनमें से सबसे छोटा हो जाएगा (एहसान "a"पर "b", आदि)। ~वर्णों के लिए बदले गए नए खंडों को मापांक ऑपरेटर के साथ उनके अनुक्रमितों का पता लगाकर संरक्षित किया जाता है। अंत में पैडिंग पंक्ति को सूची बोध में अद्यतन नहीं किया गया है (क्योंकि अनुक्रमित की श्रेणी r, उन्हें जोड़े जाने से पहले गणना की गई थी s)। इसके बजाय, एक नई पंक्ति~कॉम्प्रिहेंशन होने के बाद पात्रों को जोड़ा जाता है। ध्यान दें कि sलूप के पहले पास के बाद एक स्ट्रिंग के बजाय पात्रों की एक सूची बन जाती है (लेकिन क्योंकि पायथन उन प्रकारों के बारे में लचीला है जिन्हें हम अभी भी उसी तरह से पात्रों पर प्राप्त करने के लिए अनुक्रमित कर सकते हैं)।
  3. अंतिम पंक्ति आरेख के अंदरूनी हिस्सों को खोखला करती है और वर्णों को मुद्रित करने के लिए एक स्ट्रिंग में पुनर्निर्मित करती है। सबसे पहले, किसी भी पत्र को केवल स्वयं की अन्य प्रतियों (या ~गद्दी से वर्ण) से घिरा हुआ है .। इसके बाद, पात्रों को एक साथ एक स्ट्रिंग में समेटा जाता है। अंत में, पेडिंग ~वर्णों को वापस नई कथनों में बदल दिया जाता है और स्ट्रिंग को मुद्रित किया जाता है।

संभवतः r=rangeफ़ंक्शन बॉडी के अंदर होना चाहिए जिसे कॉल करने योग्य प्रक्रिया का हिस्सा माना जाता है, लेकिन आप वर्णों को लिखकर सहेज सकते हैं r=range;s=[l.replace। आप कुल ४२० के लिए लिखकर if"~"==s[y][x]elseऔर भी अधिक चरित्रों को निचोड़ सकते हैं if"~"==s[y][x]else। (Btw, यह मेरे लिए
२.

@res: उन सुझावों के लिए धन्यवाद। मैंने r=rangeफ़ंक्शन की पहली पंक्ति के अंत में डाल दिया है (जहां मैंने अन्य चर सेट किए हैं), और उन दो स्थानों को छोड़ दिया , जिन्हें मैंने पहले याद किया था। मुझे यकीन नहीं है कि अगर मैं दोनों का उल्लेख कर रहा हूं, जैसा कि आप दो बार एक ही बात का उल्लेख करते हैं। और, पायथन 2.7 में, यह आगे के दो वर्णों वाला हो सकता है, क्योंकि आपको कोष्ठकों की आवश्यकता नहीं है print(आमतौर पर जो केवल 1 वर्ण को बचाता है, लेकिन print"\n".join(...)काम करता है)।
ब्लाकनाथ

उफ़, मैंने उस दूसरे को गलत तरीके से चिपकाया। यह होना चाहिए था s[y][x]for(एक स्थान को हटाने), लेकिन आप इसे वैसे भी मिल गया है।
डेस

हां, यह वही है जो मुझे मिला है। मैंने सिर्फ एक बड़ा बदलाव करने की कोशिश की और 2d सूची के बजाय 1d पर चला गया, जो पात्रों का एक समूह बचाने के लिए निकला!
ब्लाकनाथ

3

पायथन, 229 226 वर्ण

def F(s):
 e,f,b='~.\n';N=s.index(b)+1;s=s.replace(f,e)
 for i in 2*N*e:s=''.join(min([x[0]]+[[y.lower()for y in x if y>b],all(y.lower()in f+b+x[0]for y in x)*[f]][x[0]!=e])for x in zip(s,s[1:]+b,s[N:]+b*N,b+s,b*N+s))
 print s

F("""......B..
.........
...A.....
.........
.......D.
.........
.C.......
.....E...
.........
""")

क्या परिणाम की गणना करने के लिए बाढ़ भरती है। अनुगामी for/ zipकॉम्बो xप्रत्येक सेल के लिए एक सरणी उत्पन्न करता है जिसमें उस सेल और उसके चार पड़ोसियों के मूल्य होते हैं। फिर हम ब्लेकनाथ की चाल और minप्रत्येक सेल के लिए संभावनाओं का एक गुच्छा का उपयोग करते हैं। वे मूल सेल मान हैं, किसी भी पड़ोसी अगर सेल का अभी तक दौरा नहीं किया गया है, या .अगर यह दौरा किया गया है और सभी पड़ोसी .सेल के बराबर या बराबर हैं ।


चूंकि दौरान subprogram- मुद्रण करने के लिए माना जाता है, तो आप सिर्फ बदल सकते हैं return sकरने के लिए print s। भी, के लिए नहीं y!=bबदला जा सकता है y>b? मुझे लगता है कि 226 अक्षर बनेंगे।
रेस

3

यही पर है। यह मेरा पहला F # प्रोग्राम है। अगर मुझे भाषा की कोई सुविधा नहीं मिली है, तो कृपया मुझे सतर्क करें क्योंकि मैं अभी भी सीख रहा हूं।

यहाँ मेरा नमूना इनपुट है

 . . . . . . . . . . . . . . . . . . . . . . . . .
 . . . . . . . . . . . . B . . . . . . . . . . . .
 . . . . . . . . . . . . . . . . . . . . . . . . .
 . . . . . . . . A . . . . . . . . . . . . . . . .
 . . . . . . . . . . . . . . . . . . . . . . . . .
 . . . . . . . . . . . . . . . . C . . . . . . . .
 . . . . . . . . . . . . . . . . . . . . . . . . .
 . . . . . . . . . . . . . . . . . . . G . . . . .
 . . . . . . . D . . . . . . . . . . . . . . . . .
 . . . . . . . . F . . . . . . . . . . . . . . . .
 . . . . . . . E . . . . . . . . . . . . . . . . .
 . . . . . . . . . . . . . . . . . . . . . . . . .
 . . . . . . . . . . . . . . . . . . . . . . . . .
 . . . . . . . . . . . . . . . . . . . . . . . . .

यहाँ आउटपुट है

 . . . . . . . . . a b . . . . . . . b g . . . . .
 . . . . . . . . . a b . B . . . b b b g . . . . .
 . . . . . . . . . . a b . . . b c c c g . . . . .
 . . . . . . . . A . . a b . b c . . c g . . . . .
 . . . . . . . . . . . a b b c . . . c g . . . . .
 a a a a a a a a . . . a b c . . C . c g . . . . .
 d d d d d d d d a a a a b c . . . c g . . . . . .
 . . . . . . . . d d d d b c . . c g . G . . . . .
 . . . . . . . D d d d d d c . . c g . . . . . . .
 d d d d d d d d f f f f f f c . c g . . . . . . .
 e e e e e e e e e e e e e e c . c g . . . . . . .
 . . . . . . . . . . . . . e c . c g . . . . . . .
 . . . . . . . . . . . . . e c . c g . . . . . . .
 . . . . . . . . . . . . . e c . c g . . . . . . .

यहाँ कोड है। का आनंद लें।

// The first thing that we need is some data. 
let originalData = [
     "........................."
     "............B............" 
     "........................." 
     "........A................" 
     "........................." 
     "................C........"          
     "........................." 
     "...................G....." 
     ".......D................." 
     "........F................"           
     ".......E................."          
     "........................."
     "........................."
     "........................."
     ]

अब हमें उस डेटा को दोहरे आयाम सरणी में बदलने की आवश्यकता है ताकि हम इसे इंडेक्सर्स के माध्यम से एक्सेस कर सकें।

let dataMatrix = 
    originalData
    |> List.map (fun st -> st.ToCharArray())
    |> List.toArray

// We are going to need a concept of ownership for each
// cell. 
type Owned = 
    | Unclaimed
    | Owner of char
    | Claimed of char
    | Boundary of char

आइए हम प्रत्येक कोशिका के स्वामित्व का प्रतिनिधित्व करने वाले एक मैट्रिक्स का निर्माण करें

let claims =
    dataMatrix
    |> Array.map (fun row ->
        row
        |> Array.map (function
            | '.' -> Owned.Unclaimed
            | ch -> Owned.Owner(ch))
        )

आइए हम देखें कि क्या हुआ है।

let printIt () =
    printfn ""
    claims
    |> Array.iter (fun row ->
        row |> Array.iter (function
            | Owned.Claimed(ch) -> printf " ." 
            | Owned.Owner(ch) -> printf " %c" ch
            | Owned.Boundary(ch) -> printf " %c" ch
            | _ -> printf " ." )
        printfn "")            

हमें यह दर्शाने के लिए एक रिकॉर्ड बनाते हैं कि कोई विशेष पूंजी पत्र कहाँ रहता है।

type CapitalLocation = { X:int; Y:int; Letter:char }

अब हम सभी बड़े अक्षरों को खोजना चाहते हैं।

let capitals = 
    dataMatrix
    |> Array.mapi (fun y row -> 
        row 
        |> Array.mapi (fun x item -> 
            match item with
            | '.' -> None
            | _ -> Some({ X=x; Y=y; Letter=item }))
        |> Array.choose id
        |> Array.toList
        )
    |> Array.fold (fun acc item -> item @ acc) List.empty<CapitalLocation>
    |> List.sortBy (fun item -> item.Letter)

जैसे-जैसे हम आगे बढ़ते हैं, हमें दिशा की अवधारणा की आवश्यकता होती है।

type Direction =
    | Left = 0
    | Up = 1
    | Right = 2
    | Down = 3   

// Function gets the coordinates of the adjacent cell. 
let getCoordinates (x, y) direction =
    match direction with
    | Direction.Left -> x-1, y
    | Direction.Up -> x, y-1
    | Direction.Right -> x+1, y
    | Direction.Down -> x, y+1
    | _ -> (-1,-1) // TODO: Figure out how to best throw an error here. 

जैसा कि हम आगे बढ़ते हैं, हमें आकार के बारे में जानने की आवश्यकता है। इससे हमें यह पता लगाने में मदद मिलेगी कि क्या हम सीमा से बाहर जा रहे हैं।

type Size = { Width:int; Height: int }    

// Get the size of the matrix. 
let size = {Width=originalData.Head.Length; Height=originalData.Length}

सक्रिय पैटर्न: किसी दिए गए सेल के मानदंडों से मेल खाता है।

let (|OutOfBounds|UnclaimedCell|Claimed|Boundary|) (x,y) =
    match (x,y) with 
    | _,_ when x < 0 || y < 0 -> OutOfBounds
    | _,_ when x >= size.Width || y >= size.Height -> OutOfBounds
    | _ ->                     
        match claims.[y].[x] with
        | Owned.Unclaimed -> UnclaimedCell(x,y)
        | Owned.Claimed(ch) -> Claimed(x,y,ch)
        | Owned.Boundary(ch) -> Boundary(x,y,ch)
        | Owned.Owner(ch) -> Claimed(x,y,ch)

अब हम पीतल कर पर उतर रहे हैं। यह सेल का दावा करता है!

let claimCell letter (x, y) =         
    // Side effect: Change the value of the cell
    (claims.[y].[x] <- Owned.Claimed (System.Char.ToLower letter)) |> ignore

सक्रिय पैटर्न का उपयोग करते हुए, यदि लावारिस है, तो इस सेल का दावा करें और आसन्न कोशिकाओं के निर्देशांक को लौटाएं।

let claimAndReturnAdjacentCells (letter, coordinates, direction) =
    match coordinates with 
    | UnclaimedCell (x,y) ->         
        // Claim it and return the Owned object.
        claimCell letter coordinates // meaningful side effect
        // use Direction as int to allow math to be performed. 
        let directionInt = int direction;            
        Some(
            // [counter-clockwise; forward; clockwise]
            [(directionInt+3)%4; directionInt; (directionInt+1)%4]                 
            |> List.map enum<Direction>                 
            |> List.map (fun newDirection -> 
                (
                    letter, 
                    getCoordinates coordinates newDirection, 
                    newDirection
                ))
        )
    | Claimed(cx,cy,cch) when cch <> System.Char.ToLower letter-> 
        // If we find a "Claimed" element that is not our letter, we have 
        // hit a boundary. Change "Claimed" to "Boundary" and return the 
        // element that led us to evaluating this element. It is also a 
        // boundary. 
        (claims.[cy].[cx] <- Owned.Boundary (System.Char.ToLower cch)) |> ignore
        let reverseDirection = enum<Direction>(((int direction)+2)%4)
        Some[(
            cch,
            getCoordinates (cx, cy) reverseDirection,
            reverseDirection
        )]
    | _ -> None

हम इस डेटा बैग की सूची बनाना शुरू कर रहे हैं, आइए हम चीजों को स्पष्ट करने के लिए एक प्रकार बनाएं।

type CellClaimCriteria = (char * (int * int) * Direction)

कोशिकाओं का दावा करने के लिए मानदंड की एक सूची को देखते हुए, हम उस सूची में दावा करने और पुनः प्राप्त करने के लिए अगली कोशिकाओं को वापस करने वाली सूची पर पुनरावृत्ति करेंगे।

let rec claimCells (items:CellClaimCriteria list) =
    items
    |> List.fold (fun acc item ->
        let results = claimAndReturnAdjacentCells item 
        if Option.isSome(results) 
        then (acc @ Option.get results) 
        else acc
        ) List.empty<CellClaimCriteria> 
    |> (fun l ->            
        match l with
        | [] -> []
        | _ -> claimCells l)

प्रत्येक पूंजी के लिए, प्रत्येक दिशा में एक दावा मानदंड बनाएं और फिर उन कोशिकाओं पर पुन: दावा करें।

let claimCellsFromCapitalsOut ()=
    capitals
    |> List.fold (fun acc capital ->
        let getCoordinates = getCoordinates (capital.X, capital.Y)
        [Direction.Left; Direction.Up; Direction.Right; Direction.Down]
        |> List.map (fun direction ->                
            (
                capital.Letter, 
                getCoordinates direction, 
                direction
            ))
        |> (fun items -> acc @ items)) List.empty<CellClaimCriteria>
    |> claimCells

हर कार्यक्रम को एक मुख्य की आवश्यकता होती है।

[<EntryPoint>]
let main args = 
    printIt()
    claimCellsFromCapitalsOut()
    printIt()
    0

अच्छी तरह से एक ऐसी भाषा में काम करने के समाधान के लिए किया जाता है जिससे आप परिचित नहीं हैं। हालांकि, आप अंतिम चरण से चूक गए हैं: यह कोड-गोल्फ है , जिसका अर्थ है कि उद्देश्य सबसे कम संभव प्रोग्राम लिखना है: एकल-चरित्र पहचानकर्ता, केवल व्हाट्सएप जिसे कड़ाई से संकलन करने की आवश्यकता है, आदि
पीटर टेलर

3
पीटरटायर आप सही हैं। मैंने यह खो दिया। इस साइट को अधिक "प्रोग्रामिंग पहेलियाँ" और कम "कोड गोल्फ" की आवश्यकता है।
फिलिप स्कॉट गिवेंस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.