असली चेबीशेव रोटेशन


15

यह चेबिशेव रोटेशन से प्रेरित एक चुनौती है । मैं सुझाव देता हूं कि इस चुनौती के लिए प्रेरणा पाने के लिए उत्तर देखें।

विमान पर एक बिंदु को देखते हुए एक अनूठा वर्ग (समान पक्षों के साथ एक आयत) है जो मूल पर केंद्रित है और उस बिंदु ( इंटरेक्टिव डेमो ) को प्रतिच्छेद करता है :

यहां छवि विवरण दर्ज करें

एक बिंदु को देखते हुए पी और एक दूरी , बिंदु दूरी को ले जाकर प्राप्त लौट से पी , वामावर्त (और नकारात्मक के लिए दक्षिणावर्त ), वर्ग की परिधि में मूल कि intersects पर केंद्रित पी । आपका उत्तर कम से कम 4 दशमलव अंकों के लिए सटीक होना चाहिए।

परीक्षण के मामलों:

(0, 0), 100 -> (0, 0)
(1, 1), 81.42 -> (-0.4200, 1.0000)
(42.234, 234.12), 2303.34 -> (-234.1200, 80.0940)
(-23, -39.234), -234.3 -> (39.2340, -21.8960)

मार्टिन एंडर द्वारा मूल परीक्षण से निम्नलिखित परीक्षण मामले हैं, और सभी d = 1 के साथ हैं :

(0, 0)       -> (0, 0)
(1, 0)       -> (1, 1)
(1, 1)       -> (0, 1)
(0, 1)       -> (-1, 1)
(-1, 1)      -> (-1, 0)
(-1, 0)      -> (-1, -1)
(-1, -1)     -> (0, -1)
(0, -1)      -> (1, -1)
(1, -1)      -> (1, 0)
(95, -12)    -> (95, -11)
(127, 127)   -> (126, 127)
(-2, 101)    -> (-3, 101)
(-65, 65)    -> (-65, 64)
(-127, 42)   -> (-127, 41)
(-9, -9)     -> (-8, -9)
(126, -127)  -> (127, -127)
(105, -105)  -> (105, -104)

क्या इनमें से लगभग सभी को केवल दूसरी चुनौती से थोड़ा बदला नहीं जा सकता है? यह एक अनावश्यक जोड़ की तरह लगता है।
अताको

1
@ATaco नहीं, यह काफी अधिक जटिल है।
orlp

पी से शुरू होने वाली परिधि के साथ दूरी की गणना की जानी चाहिए?
गबोर फेकेट

@ GáborFekete और क्या?
orlp

हाँ, मैं देख रहा हूँ, परीक्षण के मामले इसका मतलब है लेकिन यह स्पष्ट रूप से नहीं कहा गया है। मैंने पहले सोचा था कि यह एक्स-अक्ष पर सकारात्मक चौराहे पर शुरू होगा।
गबोर फेकेट

जवाबों:


4

पायथन 2, 363 335 296 266 262 258 256 233 बाइट्स

वू, 130 बाइट्स हार गए! 4 बाइट बचाने के लिए नील का धन्यवाद, 2 बाइट बचाने के लिए नाथन मेरिल और एक हास्यास्पद 23 बाइट बचाने के लिए xnor!

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

वहां से, मैं बस उस चीज़ का उपयोग करता हूं जिसे हम दिए गए x और y-निर्देशांक से जानते हैं कि हम कहाँ हैं: शीर्ष, नीचे, बाएँ, दाएँ, या एक कोने में, और दिशा निर्धारित करें, जो इनमें से एक हो सकती है 0, 1, 2, 3:

0 --> we are on the 'top', moving 'left'
1 --> we are on the 'left', moving 'down'
2 --> we are on the 'bottom', moving 'right'
3 --> we are on the 'right', moving 'up'

इसके बाद, यह लूपिंग जितना आसान है, जबकि हमारे पास अभी भी यात्रा करने के लिए दूरी है, और हम जिस दिशा में जाते हैं, उसके आधार पर हम उपयुक्त समन्वय को जोड़ते हैं, या लूप को बताते हैं कि हम किस दिशा में आगे जा रहे हैं।

p,d=input()
x,y=p
s=max(x,y,-x,-y)
d=d%(s*8or 1)
r=[(y<s)*[2,[3,x>-s][x<s]][y>-s],[2*(y<0),3*(y<=0)][x>0]][y*y==x*x]
while s>0<d:f=1-2*(r<2);m=abs(f*s-p[r%2]);j=d>m;p[r%2]=[p[r%2]+f*d,f*s][j];r=-~r%4;d=(d-m)*j
print"%.4f "*2%tuple(p)

जबकि काफी लंबे समय, यह निश्चित रूप से काम करता है। यहाँ कुछ उदाहरण I / O है:

[0, 0], 100 --> 0.0000 0.0000
[1, 1], 81.42 --> -0.4200 1.0000
[42.234, 234.12], 2303.34 --> -234.1200 80.0940
[-23, -39.234], -234.3 --> 39.2340 -21.8960

इसे ऑनलाइन आज़माएं या परीक्षण मामलों को चलाएं


s=max(x,y,-x,-y)काम करता है ?
नील

@ नील यह करता है, धन्यवाद एक गुच्छा!
Kade

(s>0)*(d>0)है s>0<d। आउटपुट हो सकता है "%.4f "*2%tuple(p)if s:d=d%(8*s)हो सकता है d%(s*8or 1)(r+1)हो सकता है ~-r1*(x>-s)बस हो सकता है (x>-s)abs(y)==abs(x)हो सकता हैy*y==x*x
xnor

@xnor वाह, धन्यवाद! केवल मेरे द्वारा परिवर्तित किए गए थिनस (x>-s)को कोष्ठक, और ~-rक्षरण की आवश्यकता नहीं थी , इसलिए मैंने उपयोग किया -~r
केड

3

जावास्क्रिप्ट (ईएस 6), 147 बाइट्स

f=(x,y,d,s=Math.max(x,y,-x,-y),c=(d/8%s+s)%s*8,v=0,w=x+y>0?1:-1,b=(v?x:y)*w+c-s)=>c?b>0?f(v?s*w:x,v?y:s*w,d,s,b,!v,v?w:-w):[x+c*w*v,y+c*w*!v]:[x,y]

स्पष्टीकरण: वर्ग की सीमा में रखते हुए दिशा वेक्टर को जोड़ने की कोशिश करके काम करता है। किसी भी ओवरशूट को 90 ° द्वारा दिशा में घुमाए गए एंटिक्लॉकवाइज के साथ पुन: उत्तीर्ण किया जाता है। दिशा वास्तव में एक ऊर्ध्वाधर ध्वज vऔर एक इकाई का उपयोग करके एन्कोडेड है wताकि वैक्टर (1, 0), (0, 1), (-1, 0) और (0, -1) को v0, 1, 0 के साथ एन्कोड किया गया हो । , 1 और w1 का, क्रमशः, -1, -1। दिशा वेक्टर शुरू में एक उपयुक्त दिशा में इंगित नहीं हो सकता है, लेकिन यह कभी पीछे की ओर इंगित नहीं करता है इसलिए यह अंततः एक उपयोगी दिशा में घूमेगा।

f=(x,y,d,                   Input parameters
 s=Math.max(x,y,-x,-y),     Calculate half the side of the square
 c=(d/8%s+s)%s*8,           Reduce the distance modulo the perimeter
 v=0,                       Initial vertical flag
 w=x+y>0?1:-1,              Initial direction
 b=(v?x:y)*w+c-s)=>         Will we overshoot the corner?
  c?b>0?f(v?s*w:x,v?y:s*w,  Advance to the next corner
          d,s,b,!v,v?w:-w): Rotate the direction
        [x+c*w*v,y+c*w*!v]: Advance the remaining amout
    [x,y]                   Nothing to do, zero input

ऐसा इसलिए हो सकता है क्योंकि मेरा ब्राउज़र (ओपेरा 40.0.2308.81) है, लेकिन ऐसा लगता है कि इसमें थोड़ी राउंडिंग त्रुटि है, f(42.234, 234.12, 2303.34) -> [-234.12, 80.09399999999988]जिसका अर्थ है कि इसमें 4 अंकों की सटीकता नहीं है। शायद कुछ आउटपुट स्वरूपण को जोड़ने से यह ठीक हो जाएगा? हालांकि अच्छा जवाब! :)
केड

@ साहेब तकनीकी रूप से आउटपुट स्वरूपण के लिए गोलाई की आवश्यकता होती है, और इसलिए एक संभावित गोलाई त्रुटि पेश करते हैं। उत्पन्न संख्याएं फ्लोटिंग-पॉइंट अंकगणित की सीमाओं के भीतर निकटतम संभव हैं, जिन्हें मनमाने ढंग से दशमलव प्रतिनिधित्व के लिए सटीक परिणाम देने की उम्मीद नहीं की जानी चाहिए। यदि आप सटीक उत्तर चाहते हैं तो बाइनरी अंशों से चिपके रहें।
नील
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.