अजगर 1166 बाइट्स
पठनीयता के लिए व्हॉट्सएप की काफी मात्रा को छोड़ दिया गया है। आकार इस सफेद स्थान को निकाल, और करने के लिए विभिन्न इंडेंटेशन स्तर बदलने के बाद मापा जाता है Tab
, Tab
Space
, Tab
Tab
, आदि मैं भी किसी भी गोल्फ जो भी काफी प्रदर्शन को प्रभावित किया बचा लिया है।
T=[]
S=[0]*20,'QTRXadbhEIFJUVZYeijf',0
I='FBRLUD'
G=[(~i%8,i/8-4)for i in map(ord,'ouf|/[bPcU`Dkqbx-Y:(+=P4cyrh=I;-(:R6')]
R=range
def M(o,s,p):
z=~p/2%-3;k=1
for i,j in G[p::6]:i*=k;j*=k;o[i],o[j]=o[j]-z,o[i]+z;s[i],s[j]=s[j],s[i];k=-k
N=lambda p:sum([i<<i for i in R(4)for j in R(i)if p[j]<p[i]])
def H(i,t,s,n=0,d=()):
if i>4:n=N(s[2-i::2]+s[7+i::2])*84+N(s[i&1::2])*6+divmod(N(s[8:]),24)[i&1]
elif i>3:
for j in s:l='UZifVYje'.find(j);t[l]=i;d+=(l-4,)[l<4:];n-=~i<<i;i+=l<4
n+=N([t[j]^t[d[3]]for j in d])
elif i>1:
for j in s:n+=n+[j<'K',j in'QRab'][i&1]
for j in t[13*i:][:11]:n+=j%(2+i)-n*~i
return n
def P(i,m,t,s,l=''):
for j in~-i,i:
if T[j][H(j,t,s)]<m:return
if~m<0:print l;return t,s
for p in R(6):
u=t[:];v=s[:]
for n in 1,2,3:
M(u,v,p);r=p<n%2*i or P(i,m+1,u,v,l+I[p]+`n`)
if r>1:return r
s=raw_input().split()
o=[-(p[-1]in'UD')or p[0]in'RL'or p[1]in'UD'for p in s]
s=[chr(64+sum(1<<I.find(a)for a in x))for x in s]
for i in R(7):
m=0;C={};T+=C,;x=[S]
for j,k,d in x:
h=H(i,j,k)
for p in R(C.get(h,6)):
C[h]=d;u=j[:];v=list(k)
for n in i,0,i:M(u,v,p);x+=[(u[:],v[:],d-1)]*(p|1>n)
if~i&1:
while[]>d:d=P(i,m,o,s);m-=1
o,s=d
नमूना उपयोग:
$ more in.dat
RU LF UB DR DL BL UL FU BD RF BR FD LDF LBD FUL RFD UFR RDB UBL RBU
$ pypy rubiks.py < in.dat
F3R1U3D3B1
F2R1F2R3F2U1R1L1
R2U3F2U3F2U1R2U3R2U1
F2L2B2R2U2L2D2L2F2
यह एक स्टेप के लिए हल करने के लिए एक आईडीए * खोज का उपयोग करते हुए थिस्टलेथवेट के एल्गोरिथ्म का एक कार्यान्वयन है। चूँकि सभी हेयुरिस्टिक टेबल को मक्खी पर परिकलित करने की आवश्यकता होती है, इसलिए कई समझौते किए गए हैं, जो आमतौर पर एक हेयुरिस्टिक को दो या अधिक समान आकार के भागों में तोड़ते हैं। यह खोज के चरण को धीमा करते हुए, हेयुरिस्टिक टेबल की गणना को सैकड़ों गुना तेज बनाता है, आमतौर पर केवल थोड़ा, लेकिन यह प्रारंभिक घन अवस्था के आधार पर महत्वपूर्ण हो सकता है।
चर सूचकांक
T
- मुख्य हेयुरिस्टिक टेबल।
S
- एक हल किया हुआ घन अवस्था। प्रत्येक व्यक्ति के टुकड़े को एक बिट मास्क के रूप में संग्रहीत किया जाता है, एक चरित्र के रूप में दर्शाया जाता है। एक सॉलिड ओरिएंटेशन वेक्टर को जीरो वेक्टर के रूप में परिभाषित किया गया है।
I
- विभिन्न ट्विस्ट, इस क्रम में कि वे खोज स्थान से समाप्त हो जाते हैं।
G
- मोड़ क्रमपरिवर्तन के लिए समूह, जोड़े जाने वाले जोड़े के रूप में स्वैप किए जाते हैं। एक जोड़ी के लिए संपीड़ित स्ट्रिंग एन्कोड में प्रत्येक बाइट। प्रत्येक मोड़ को छह स्वैप की आवश्यकता होती है: किनारे के चक्र के लिए तीन, और कोने के चक्र के लिए तीन। संपीड़ित स्ट्रिंग में केवल मुद्रण योग्य एएससीआई (चार 32 से 126) शामिल हैं।
M
- एक फ़ंक्शन जो एक चाल करता है, जी द्वारा दिया गया।
N
- एन्कोडिंग प्रयोजनों के लिए एक नंबर के लिए चार वस्तुओं के एक क्रमचय को परिवर्तित करता है।
H
- दिए गए घन राज्य के लिए अनुमानी मूल्य की गणना करता है, जिसका उपयोग टी से गहराई को देखने के लिए किया जाता है।
P
- एल्गोरिथ्म के एकल चरण की एक ही गहराई पर एक खोज करें।
s
- इनपुट क्यूब का क्रमचय अवस्था।
o
- इनपुट क्यूब का ओरिएंटेशन वेक्टर।
प्रदर्शन
टॉमस रोक्की के डेटा सेट का उपयोग करते हुए , इस स्क्रिप्ट में औसतन 16.02 ट्विस्ट प्रति हल (अधिकतम 35), औसत समय 472ms (i5-3330 CPU @ 3.0 Ghz, PyPy 1.9.0) के साथ था। न्यूनतम समाधान समय अधिकतम 2.97 के साथ 233ms था, मानक विचलन 0.488। प्रतियोगिता से स्कोरिंग दिशानिर्देशों का उपयोग करते हुए (सफेद स्थान की गणना नहीं की जाती है, कीवर्ड और पहचानकर्ता 870 की लंबाई के लिए एक बाइट के रूप में गिना जाता है), कुल स्कोर 13,549 रहा होगा।
पिछले 46 मामलों (रैंडम स्टेट्स) के लिए, इसने औसतन 721ms के साथ 30.83 ट्विस्ट प्रति सॉल्व किया।
थीस्लथ्वाइट के एल्गोरिथम पर नोट्स
किसी के लाभ के लिए, जो थीस्लथेवाइट के एल्गोरिथ्म के कार्यान्वयन का प्रयास करना चाहते हैं , यहां एक संक्षिप्त विवरण दिया जा सकता है।
एल्गोरिथ्म एक बहुत ही सरल समाधान अंतरिक्ष कमी सिद्धांत पर काम करता है। यही है, क्यूब को उस अवस्था में कम करें जिसमें इसे हल करने के लिए ट्विस्ट का एक सबसेट आवश्यक नहीं है, इसे एक छोटे से घोल के स्थान पर कम करें, और फिर बचे हुए कुछ ट्विस्ट का उपयोग करके शेष को हल करें।
थीस्लथ्वाइट ने मूल रूप से <L,R,F,B,U,D>
→ <L,R,F,B,U2,D2>
→ <L,R,F2,B2,U2,D2>
→ सुझाव दिया <L2,R2,F2,B2,U2,D2>
। हालांकि, इनपुट प्रारूप को देखते हुए, मुझे लगता है कि पहले <L,R,F2,B2,U,D>
(कोई तिमाही मोड़ F
या B
) कम करना आसान है , और फिर <L2,R2,F2,B2,U,D>
अंत में आधे मोड़ तक पहुंचने से पहले। यह समझाने के बजाय कि ऐसा क्यों है, मुझे लगता है कि यह प्रत्येक राज्य के लिए मानदंड निर्धारित करने के बाद स्पष्ट होगा।
<L,R,F,B,U,D>
⇒ <L,R,F2,B2,U,D>
घुमावों को समाप्त करने F
और करने के लिए B
, केवल किनारों को सही ढंग से उन्मुख होना चाहिए। गाइल्स रौक्स ने अपनी साइट पर 'सही' और 'गलत' अभिविन्यास के बारे में बहुत अच्छी व्याख्या की है, इसलिए मैं उसे समझाता हूँ। लेकिन मूल रूप से, (और यही कारण है कि यह इनपुट प्रारूप बहुत ही अनुकूल है F
और इसे B
समाप्त कर देता है), एक किनारे क्यूबाई सही रूप से उन्मुख है यदि यह निम्नलिखित रेगेक्स से मेल खाता है [^RL][^UD]
:। एक सही अभिविन्यास आम तौर पर एक के साथ 0
और गलत के साथ संकेतित है 1
। मूल रूप से U
और D
स्टिकर पर दिखाई नहीं दे R
या L
चेहरे, या किसी के किनारों पर U
या D
किनारे cubies, या वे आवश्यकता के बिना जगह में स्थानांतरित नहीं किया जा सकता है एक F
याB
तिमाही मोड़।
<L,R,F2,B2,U,D>
⇒ <L2,R2,F2,B2,U,D>
यहां दो मापदंड। सबसे पहले, हर कोने सही ढंग से उन्मुख किया जाना चाहिए, और दूसरा, मध्यम परत cubies के लिए में से प्रत्येक ( FR
, FL
, BR
, BL
) कहीं मध्यम परत में होना चाहिए। एक कोने के अभिविन्यास को बहुत ही सरल रूप से परिभाषित किया गया है जो इनपुट प्रारूप दिया गया है: पहले की स्थिति U
या D
। उदाहरण के लिए, URB
अभिविन्यास 0
(सही ढंग से उन्मुख) है, LDF
अभिविन्यास है 1
, और LFU
अभिविन्यास है 2
।
<L2,R2,F2,B2,U,D>
⇒ <L2,R2,F2,B2,U2,D2>
यहां मानदंड इस प्रकार है: प्रत्येक चेहरे में केवल इसके चेहरे से स्टिकर हो सकते हैं, या इसके विपरीत सीधे चेहरे से हो सकते हैं। उदाहरण के लिए, पर U
चेहरा देखते ही हो सकता है U
और D
स्टिकर, पर R
चेहरा देखते ही हो सकता है R
और L
स्टिकर, पर F
चेहरा देखते ही हो सकता है F
और B
यदि प्रत्येक बढ़त टुकड़ा में है स्टिकर, आदि सबसे आसान तरीका है यह सुनिश्चित करने के लिए है की जाँच करने के इसके 'स्लाइस', और इसके 'ऑर्बिट' में प्रत्येक कोने का टुकड़ा। इसके अतिरिक्त, किसी को किनारे-कोने की समानता पर ध्यान देने की आवश्यकता है। यद्यपि, यदि आप केवल कोने की समानता के लिए जाँच करते हैं, तो किनारे की समानता की भी गारंटी है, और इसके विपरीत।
कैसे ट्विस्ट ओरिएंटेशन को प्रभावित करते हैं
U
और D
ट्विस्ट न तो एज ओरिएंटेशन को प्रभावित करते हैं, न ही कॉर्नर ओरिएंटेशन को। ओरिएंटेशन वेक्टर को अपडेट किए बिना टुकड़ों को सीधे स्वैप किया जा सकता है।
R
और L
मोड़ किनारे के अभिविन्यास को प्रभावित नहीं करते हैं, लेकिन वे कोने के उन्मुखीकरण को प्रभावित करते हैं। इस आधार पर कि आप अपने चक्र को कैसे परिभाषित करते हैं, कोने के अभिविन्यास में परिवर्तन +1, +2, +1, +2
या तो होगा +2, +1, +2, +1
, या सभी मोडुलो 3
। ध्यान दें कि R2
और L2
ट्विस्ट कॉर्नर ओरिएंटेशन को प्रभावित नहीं करता है, जैसा +1+2
कि शून्य मोडुलो है 3
, जैसा कि है +2+1
।
F
और B
दोनों किनारे झुकाव और कोने झुकाव को प्रभावित करते हैं। एज झुकाव बन +1, +1, +1, +1
(आधुनिक 2), और कोने झुकाव के लिए जैसे ही हैं R
और L
। ध्यान दें कि F2
और B2
न तो धार झुकाव, और न ही कोने झुकाव को प्रभावित करें।