रेटिना , 353 339 178 175 150 130 129 117 बाइट्स
R
5$*r
T`aq\we\ds`so`r.+
)`r(.*)
$1
^
:
a
sq
e
wd
+`(.+)q
w$1
+`(.+)d
s$1
+`sw
(.*)(\1w?):
$0$2
+`sw|ws
w+
-$0
\w
1
आउटपुट एकात्मक में है, एक बृहदान्त्र द्वारा अलग किया गया है। इसका मतलब है कि आप वास्तव में आउटपुट में शून्य नहीं देखेंगे (हालांकि एक बृहदान्त्र की उपस्थिति आपको बताएगी कि दोनों में से कौन सा निर्देशांक शून्य है, अगर केवल एक है)।
इसे ऑनलाइन आज़माएं!
यह वास्तव में मजेदार था और आश्चर्यजनक रूप से कम हो गया। :)
व्याख्या
पहले कुछ पृष्ठभूमि। हेक्सागोनल ग्रिड का वर्णन करने के लिए कई समन्वय प्रणाली हैं। एक ऑफसेट निर्देशांक का उपयोग करने के लिए कहा। यह अनिवार्य रूप से आयताकार ग्रिड के निर्देशांक की तरह है, सिवाय इसके कि एक अक्ष "वॉबल्स" को थोड़ा सा। विशेष रूप से, प्रश्न "विषम-क्यू" लेआउट के लिए लिंक किए गए पृष्ठ पर दिखाया गया है। यह समन्वय प्रणाली के साथ काम करने के लिए थोड़ा कष्टप्रद है, क्योंकि एक चाल के दौरान निर्देशांक कैसे बदलते हैं यह न केवल कदम की दिशा पर निर्भर करता है, बल्कि वर्तमान स्थिति पर भी निर्भर करता है।
एक अन्य समन्वय प्रणाली अक्षीय निर्देशांक का उपयोग करती है। यह अनिवार्य रूप से हेक्सग्रिड को क्यूब्स की मात्रा के माध्यम से एक विकर्ण टुकड़ा के रूप में कल्पना कर रहा है, और 2 डी विमान पर एक स्थिति खोजने के लिए दो अक्षों (जैसे x और z) का उपयोग कर रहा है। हेक्स ग्रिड पर, इसका मतलब है कि दो अक्ष 60 (या 120) डिग्री का कोण बनाते हैं। यह प्रणाली थोड़ी कम सहज है, लेकिन इसके साथ काम करना बहुत आसान है, क्योंकि हर दिशा एक निश्चित "डेल्टा" वेक्टर से मेल खाती है। (इस समन्वय प्रणाली में कैसे पहुंचें, इसकी बेहतर व्याख्या के लिए, लिंक और प्यारे आरेख और एनिमेशन देखें।)
तो यहां हम क्या करेंगे: हम अक्षीय निर्देशांक में आंदोलन की गणना करते हैं (रोटेशन का ख्याल रखना, जैसा कि चुनौती में सुझाव दिया गया है, आज्ञाओं के अर्थ को हटाकर), और जब हमने किया है तो हम अक्षीय को विषम-क्यू ऑफसेट में बदल देते हैं निर्देशांक।
अक्षीय निर्देशांक (xz) में निम्नलिखित डेल्टा वैक्टर के लिए छह चालों का नक्शा:
q => (-1, 0)
w => ( 0, -1)
e => ( 1, -1)
d => ( 1, 0)
s => ( 0, 1)
a => (-1, 1)
रुको, यह रेटिना है, हमें एकात्मक संख्याओं के साथ काम करना होगा। हम नकारात्मक एकात्मक संख्याओं के साथ कैसे काम करते हैं? दो अलग-अलग अंकों का उपयोग करने का विचार है। एक प्रतिनिधित्व करता है +1और दूसरा प्रतिनिधित्व करता है -1। इसका मतलब है कि चाहे हम 1वर्तमान स्थिति से जोड़ना या घटाना चाहें , हम हमेशा एक अंक जोड़कर ऐसा कर सकते हैं। जब हम कर लेते हैं तो हम संतुलित अंकों को रद्द करके इसके परिमाण (संबंधित अंक का) में परिणाम को ध्वस्त कर देते हैं। फिर हम शेष अंकों के आधार पर साइन आउट करते हैं, और सभी अंकों को प्रतिस्थापित करते हैं 1।
:इनपुट के सामने अक्षीय एक्स और जेड घटकों को बाईं और दाईं ओर (एक विभाजक के रूप में) बनाने की योजना है । wऔर sदाईं ओर जोड़ देगा। qऔर dबाएं ओर करने के लिए जोड़ देगा, और eऔर aदोनों पक्षों के लिए जोड़ देगा। चूंकि wऔर sपहले से ही :(जो सामने जाएगा) के दाईं ओर है , हम क्रमशः उन -1और +1अंकों के रूप में उपयोग करेंगे ।
कोड के माध्यम से चलते हैं।
R
5$*r
हम प्रत्येक Rको पाँच rएस में बदलकर शुरू करते हैं । बेशक, एक लेफ्ट टर्न एक हेक्स ग्रिड पर पांच राइट टर्न के समान है, और ऐसा करके हम रीमैपिंग स्टेप पर बहुत अधिक दोहराव कर सकते हैं।
T`aq\we\ds`so`r.+
यह एक लिप्यंतरण चरण है जो छह कमांडों को घुमाता है, यदि वे पहले के बाद पाए जाते हैं r(इस प्रकार पहले प्रसंस्करण करते हैं r)। wऔर dउन्हें चरित्र वर्गों में विस्तार से रोकने के लिए भागने की जरूरत है। oलक्ष्य सेट जो इन कार्यों के लिए रोटेशन बाइट्स के एक झुंड की बचत होती है में स्रोत सेट सम्मिलित करता है। चरित्र मानचित्रण इसलिए है:
aqweds
saqweds
जहाँ sदूसरी पंक्ति में अंतिम को अनदेखा किया जा सकता है।
)`r(.*)
$1
यह rस्ट्रिंग से पहले को हटा देता है , क्योंकि यह संसाधित किया गया है (काश मैं पहले से ही प्रतिस्थापन सीमाएं लागू कर चुका होता ...)। )रेटिना को यह भी बताता है कि जब तक स्ट्रिंग बदलना बंद न हो जाए, तब तक यह सभी चरणों को एक लूप में चलाता है। बाद के पुनरावृत्तियों पर, पहला चरण एक ऑप-ऑप है क्योंकि कोई भी अधिक Rएस नहीं हैं और दूसरा चरण तब तक एक और रोटेशन लागू करेगा जब तक rकि स्ट्रिंग में शेष नहीं हो जाते ।
जब हम काम कर चुके होते हैं, तो हम सभी कमांड्स को उस दिशा में मैप कर देते हैं, जो वे अनियंत्रित ग्रिड के अनुरूप होते हैं और उन पर कार्रवाई शुरू कर सकते हैं। बेशक यह आंदोलन सिर्फ उन डेल्टा वैक्टरों का एक योग है, और रकम कम्यूटेटिव है, इसलिए यह वास्तव में कोई फर्क नहीं पड़ता कि हम किस क्रम में उन्हें संसाधित करते हैं कि घुमाव समाप्त हो गए हैं।
^
:
सामने पर समन्वित सीमांकक डालें।
अब हम वास्तव में कार्रवाई करने के लिए की जरूरत नहीं है sऔर w। वे हमारे +1और -1अंक हैं और वे पहले से ही सही हैं, :इसलिए वे अंत में आवश्यक रूप से छोड़ देंगे। हम एक और सरलीकरण कर सकते हैं: aबस है s + qऔर eहै w + d। चलो करते हैं:
a
sq
e
wd
फिर से, उन sऔर wबाहर छोड़ देंगे। हमें बस की जरूरत है उन लोगों के लिए कदम है qऔर dसामने से रों और उन्हें में बदल जाते हैं wऔर sखुद को है। हम दो अलग छोरों के साथ करते हैं:
+`(.+)q
w$1
+`(.+)d
s$1
तो हो गया। निर्देशांक से ऑफसेट करने के लिए अक्षीय से रूपांतरण के लिए समय। उसके लिए हमें अंकों को समाप्त करना होगा। हालाँकि, अब हम केवल बाएं हाथ की ओर ध्यान रखते हैं। जिस तरह से हमने qएस और dएस को संसाधित किया है , हम जानते हैं कि sबाएं हाथ में सभी एस किसी भी wएस के सामने दिखाई देंगे , इसलिए हमें केवल उन्हें गिराने के लिए एक जोड़ी की जांच करने की आवश्यकता है:
+`sw
अब वास्तविक रूपांतरण। यहाँ pseudocode, ऊपर दिए गए लिंक से लिया गया है:
# convert cube to odd-q offset
col = x
row = z + (x - (x&1)) / 2
दाएं, इसलिए बाएं हाथ की तरफ पहले से ही सही है। दाएं हाथ की ओर (x - (x&1)) / 2हालांकि सुधार अवधि की आवश्यकता है । लेना &1मोड्यूलो 2 के समान है। यह मूल रूप x/2से पूर्णांक विभाजन, माइनस इनफिनिटी की ओर गोल होता है। तो सकारात्मक के लिए x, हम अंकों की आधी संख्या (नीचे की ओर) जोड़ते हैं, और नकारात्मक के लिए x, हम अंकों की आधी संख्या (पूर्णांक) को घटाते हैं। यह regex में आश्चर्यजनक रूप से स्पष्ट रूप से व्यक्त किया जा सकता है:
(.*)(\1w?):
$0$2
लालच के कारण, यहां तक कि x, समूह 1 बिल्कुल आधे अंकों से मेल खाएगा, \1अन्य आधा और हम इसे अनदेखा कर सकते हैं w?। हम उस के बाद आधा डालें :(जो है x/2)। यदि समान xहै, तो हमें सकारात्मक और नकारात्मक में अंतर करने की आवश्यकता है। यदि xसकारात्मक है, तो w?कभी मेल नहीं खाएगा, इसलिए दोनों समूहों को अभी भी समान अंकों का मिलान करना होगा। यह कोई समस्या नहीं है अगर पहली sबस छोड़ दी जाती है, तो हम गोल हो जाते हैं। यदि xनकारात्मक और विषम है, तो संभव मैच \1( xगोल नीचे का आधा ) और उस वैकल्पिक के साथ है w। चूंकि वे दोनों समूह में जाते हैं 2, हम x/2परिमाण के साथ लिखेंगे (आवश्यकतानुसार)।
+`sw|ws
अब हम दायीं ओर के अंकों को समाप्त करते हैं। इस बार, हमें आदेश का पता नहीं है sऔर wइसलिए हमें दोनों जोड़ियों का हिसाब देना होगा।
w+
-$0
दोनों भागों को अब एक ही दोहराया अंक (या कुछ नहीं) के लिए कम कर दिया जाता है। यदि वह अंक है w, तो हम सामने एक ऋण चिह्न डालते हैं।
\w
1
और अंत में हम दोनों में बदल जाते हैं wऔर sएक भी उचित एकल अंकों में। (मुझे लगता है कि मैं एक अंक का उपयोग करके wया एक sअंक के रूप में एक बाइट बचा सकता है , लेकिन यह थोड़ा खिंचाव की तरह लगता है।)