रेटिना , 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
अंक के रूप में एक बाइट बचा सकता है , लेकिन यह थोड़ा खिंचाव की तरह लगता है।)