यह देखना कि क्या एक निश्चित ग्रिड कॉन्फ़िगरेशन एक निश्चित नुस्खा से मेल खाता है यदि आप एक स्ट्रिंग के रूप में 3x3 ग्रिड को एनकोड करते हैं और एक नियमित अभिव्यक्ति मैच का उपयोग करते हैं । लुक को तेज करना एक अलग मामला है, जिसके बारे में मैं अंत में बात करूंगा। अधिक जानकारी के लिए आगे पढ़िए।
चरण 1) स्ट्रिंग के रूप में एनकोड ग्रिड
बस इस क्रम में प्रत्येक प्रकार के सेल को एक चार-चार आईडी दें और हर चीज को साइड में कर दें:
123
456 => 123456789
789
और अधिक ठोस उदाहरण के रूप में, स्टिक रेसिपी पर विचार करें, जहां डब्ल्यू लकड़ी की है और ई एक खाली सेल है (आप बस एक खाली चार '' का उपयोग कर सकते हैं):
EEE
WEE => EEEWEEWEE
WEE
चरण 2) रेगुलर एक्सप्रेशन (या String.Contains को डेटा पर थोड़ी प्रोसेसिंग के साथ प्रयोग करके मैच रेसिपी)
ऊपर दिए गए उदाहरण से जारी रखते हुए, भले ही हम गठन को चारों ओर ले जाते हैं, फिर भी स्ट्रिंग में एक पैटर्न है (दोनों तरफ ई द्वारा लिखित पैड):
EEW
EEW => EEWEEWEEE
EEE
तो कोई फर्क नहीं पड़ता कि आप छड़ी को किस ओर घुमाते हैं, यह अभी भी निम्नलिखित नियमित अभिव्यक्ति से मेल खाएगा: /^E*WEEWE*$/
नियमित अभिव्यक्तियाँ आपको आपके द्वारा उल्लिखित सशर्त व्यवहार करने देती हैं। उदाहरण के लिए (बनाया गया नुस्खा), यदि आप एक ही परिणाम देने के लिए लोहे या पत्थर से बने पिकैक्स चाहते हैं , अर्थात:
III SSS
EWE or EWE
EWE EWE
आप दोनों को नियमित अभिव्यक्ति में जोड़ सकते हैं: /^(III)|(SSS)EWEEWE$/
क्षैतिज फ़्लिप को भी आसानी से जोड़ा जा सकता है (| ऑपरेटर भी) का उपयोग करके।
संपादित करें: वैसे भी, रेगेक्स भाग कड़ाई से आवश्यक नहीं है। यह एक एकल अभिव्यक्ति में समस्या को एनकैप्सुलेट करने का सिर्फ एक तरीका है, लेकिन चर स्थान की समस्या के लिए आप किसी भी पैडिंग स्पेस (या इस उदाहरण में ई के ग्रिड ग्रिड) को ट्रिम कर सकते हैं और एक स्ट्रिंग कर सकते हैं। कॉन्ट्रैक्ट्स ()। और कई घटक समस्या या प्रतिबिंबित व्यंजनों के लिए, आप उन सभी को एक ही आउटपुट के साथ एकाधिक (यानी अलग) व्यंजनों के रूप में संभाल सकते हैं।
चरण 3) लुकअप को गति देना
खोज को कम करने के लिए, आपको समूह व्यंजनों के लिए कुछ डेटा संरचना एक साथ बनाने और लुकअप के साथ मदद करने की आवश्यकता होगी। ग्रिड को स्ट्रिंग के रूप में मानने से यहाँ कुछ फायदे भी हैं :
आप पहले गैर-खाली चरित्र और अंतिम गैर-खाली चरित्र के बीच की दूरी के रूप में एक नुस्खा की "लंबाई" को परिभाषित कर सकते हैं। एक साधारण Trim().Length()
आपको यह जानकारी देगा। व्यंजनों को लंबाई द्वारा समूहीकृत किया जा सकता है और एक शब्दकोश में संग्रहीत किया जा सकता है।
या
"लंबाई" की एक वैकल्पिक परिभाषा गैर-खाली वर्णों की संख्या हो सकती है। और कुछ नहीं बदलता। आप इस मानदंड द्वारा भी व्यंजनों को समूहित कर सकते हैं।
यदि बिंदु संख्या 1 पर्याप्त नहीं है, तो रेसिपी को पहले घटक के प्रकार से और भी समूहीकृत किया जा सकता है जो रेसिपी में दिखाई देता है। यह करना उतना ही सरल होगा Trim().CharAt(0)
(और ट्रिम से बचाव के लिए एक रिक्त स्ट्रिंग उत्पन्न होती है)।
तो उदाहरण के लिए आप व्यंजनों को एक में संग्रहीत करेंगे:
Dictionary<int, Dictionary<char, List<string>>> _recipes;
और लुकअप कुछ इस तरह से करें:
// A string encode of your current grid configuration
string grid;
// Get length and first char in our grid
string trim = grid.Trim();
int length = trim.Length();
char firstChar = length==0 ? ' ' : trim[0];
foreach(string recipe in _recipes[length][firstChar])
{
// Check for a match with the recipe
if(Regex.Match(grid, recipe))
{
// We found a matching recipe, do something with it
}
}