एक कुत्ता एक श्रृंखला पर


31

मैं अपनी अटारी खिड़की से अपने पड़ोसी के यार्ड में देख रहा हूँ। उनके पास यार्ड के केंद्र में एक कुत्ते की जंजीर है। कुत्ता यार्ड के चारों ओर चलता है, लेकिन हमेशा इसकी श्रृंखला के अंत में होता है, इसलिए यह गंदगी में एक ट्रैक को छोड़कर समाप्त होता है। आम तौर पर यह ट्रैक पूरी तरह से गोलाकार होगा, लेकिन मेरे पड़ोसियों के पास उनके यार्ड में कुछ अन्य डंडे हैं जिन्हें कुत्ते की चेन ने पकड़ लिया। हर बार जब कुत्तों की श्रृंखला एक ध्रुव से टकराती है, तो कुत्ते उस नए ध्रुव के बारे में घूमना शुरू कर देते हैं जो श्रृंखला की लंबाई के साथ उसके दायरे के रूप में छोड़ दिया जाता है। चूंकि डंडे, कुत्ते और श्रृंखला सभी में शून्य चौड़ाई है (मेरे पड़ोसी गणितज्ञ हैं) श्रृंखला सर्कल के त्रिज्या के बिना अनिश्चित काल के लिए एक पोल के चारों ओर हवा कर सकती है। अगर चेन अपने रास्ते में है तो कुत्ता भी चेन से गुजर सकता है (सिर्फ उसका कॉलर नहीं)। थोड़ी देर के लिए इस विषमता को देखने के बाद, मैं तय करता हूं कि मैं अपने पड़ोसी के कुत्ते को अनुकरण करने के लिए कुछ कोड लिखूंगा। कोड एक केंद्र ध्रुव के स्थानों को ले जाएगा, जिसमें कुत्ते को जंजीर दी गई है, मेरे पड़ोसी यार्ड में अन्य ध्रुवों के स्थान, श्रृंखला की लंबाई, और कुत्ते के शुरुआती स्थान, और आउटपुट का संकेत देगा एक आरेख पथ जहां कुत्ते ने घास को पहना है। आप मान सकते हैं कि निम्नलिखित में से कोई भी संयोजन स्थिर है (और इस तरह उन्हें इनपुट के रूप में नहीं लिया जाता है):

  • जिस स्थान पर कुत्ते को जंजीर पहनाई जाती है

  • श्रृंखला की लंबाई

  • कुत्ते का स्थान शुरू करना

सूरज उग रहा है, इसलिए खिड़की से रोशन मेरे अटारी के फर्श पर जगह सिकुड़ रही है, जिससे मुझे अपना कोड लिखने के लिए कम और कम जगह मिल रही है। कृपया अपने कोड की बाइट गिनती को कम करने की कोशिश करें ताकि मेरे पास मेरी अटारी मंजिल पर ड्राफ्ट करने के लिए जगह हो।

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

यहां मैं मानता हूं कि कुत्ता 3 इकाइयों को दक्षिण की ओर से शुरू करता है, जहां से यह जंजीर (लाल बिंदी) पर स्थित है 0,0। मैंने संकेत दिया है कि स्पष्टता के लिए डंडे कहां हैं, आपको उन्हें अपने आउटपुट में शामिल करने की आवश्यकता नहीं है।

Poles at 1,2 -1,2

परीक्षण 1

Poles at 0,.5

परीक्षण २

Poles at 0,1 1,1 -2,1 -1,-.5

परीक्षण ३

Poles at 0,1 1,1

टेस्ट 4


के लिए उत्पादन क्या है {0,-.5}?
कृति लिथोस

@KritiiLithos इसका उत्पादन {0,.5}सबसे बड़े सर्कल के बिना लंबवत रूप से फ़्लिप किया गया। कुत्ता अनिवार्य रूप से दूसरे ध्रुव पर पकड़ना शुरू कर देता है।
गेहूं जादूगर

फ्लोटिंग-पॉइंट मुद्दों के परिणामस्वरूप, मेरा प्रोग्राम अंतिम टेस्टकेस में (1,1) के चारों ओर एक सर्कल खींचता है (स्ट्रिंग की लंबाई 99.99 मीटर है)। यह ठीक है?
क्रिति लिथोस

कुत्ता दक्षिणावर्त और वामावर्त दोनों चलाता है, लेकिन एक निश्चित बिंदु से?
user202729

3
"सूरज मेरे अटारी के फर्श पर जगह बढ़ रहा है खिड़की से रोशन हो रहा है और मुझे अपने कोड लिखने के लिए कम और कम जगह दे रहा है" +1 इसके लिए
लियो

जवाबों:


11

Python 3 का उपयोग matplotlib, 457 बाइट्स में किया जाता है

from cmath import*
from matplotlib import pyplot as g,patches as i
def x(p):
 p+=[0];d=180/pi;a=2;h=g.gca();h.set_xlim(-5,5);h.set_ylim(-5,5)
 while a:
  a-=1;c=0;y=3;z=-pi/2
  while 1:
   s=[n for n in p if abs(n-c)<=y and n!=c]
   if not s:h.add_patch(i.Arc((c.real,c.imag),y*2,y*2));break
   n=[max,min][a](s,key=lambda n:(z-phase(n-c))%(2*pi));l,r=polar(n-c);h.add_patch(i.Arc((c.real,c.imag),y*2,y*2,[z,r][a]*d,0,[r-z,z-r][a]*d));y-=l;z=r;c=n
 g.show()

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

x([2j+1,2j-1])
x([.5j])
x([1j,1+1j,-2+1j,-1-.5j])
x([1j,1+1j])

इसके अलावा, कार्यक्रम निम्नलिखित चीजों को मानता है: पट्टा बिंदु 0 से बंधा हुआ है, पट्टा 3 इकाइयां लंबा है, और भूखंड का क्षेत्रफल 10 से 10 सेंटीमीटर के आसपास है। 0. इन मापदंडों के लिए, परिणाम बिल्कुल उदाहरणों के साथ मेल खाते हैं, और यह परिणाम कैसा दिखता है (अंतिम उदाहरण के लिए):

एक्स ([1j, 1 + 1j])

एल्गोरिथ्म काफी सरल है, केवल दक्षिणावर्त और वामावर्त खोज को अलग करने के लिए एक सशर्त की आवश्यकता होती है। एल्गोरिथ्म की स्थिति को वर्तमान रोटेशन बिंदु द्वारा परिभाषित किया जाता है और वर्तमान घुमाव बिंदु को हिट करते समय पट्टा की अभिविन्यास / शेष लंबाई। यह निम्नानुसार काम करता है:

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

इस एल्गोरिथ्म को पहले दक्षिणावर्त दिशा में किया जाता है, उसके बाद स्थिति को रीसेट किया जाता है और इसे वामावर्त दिशा में निष्पादित किया जाता है। एल्गोरिथ्म की सादगी का मतलब है कि कार्यक्रम के लगभग आधे बाइटकाउंट को ड्राइंग फ़ंक्शन पर खर्च किया जाता है। यदि ड्राइंग रूटीन छीन लिए गए तो यह कार्यक्रम के आकार से 218 बाइट निकाल देगा।

निम्नलिखित एक ungolfed संस्करण है जिसमें डिबग कोड भी है, जो अंक और पट्टा टकराव को भी प्रदर्शित करता है:

from cmath import pi, rect, polar, phase
from matplotlib import pyplot, patches
def x_ungolfed(points):
    degrees = 180/pi # conversions

    # add the center point to the collision points
    points.append(0.0)

    # configure plot area
    axes=pyplot.gca()
    axes.set_xlim(-5,5)
    axes.set_ylim(-5,5)

    # plot the points
    x, y =zip(*((p.real, p.imag) for p in points))
    axes.scatter(x, y, 50, "b")

    # first iteration is clockwise, second counterclockwise
    clockwise = 2
    while clockwise:
        clockwise -= 1

        # initial conditions
        center = 0 + 0j;
        leash_size = 3
        leash_angle = -pi / 2

        # initial leash plot
        leash_start = rect(leash_size, leash_angle)
        axes.plot([center.real, leash_start.real], [center.imag, leash_start.imag], "r")

        # search loop
        while 1:
            # find possible collission candidates
            candidates = [n for n in points if abs(n - center) <= leash_size and n != center]
            # if we reached the end, draw a circle
            if not candidates:
                axes.add_patch(patches.Arc(
                    (center.real, center.imag), 
                    leash_size*2, leash_size*2
                ))
                break
            # find the actual collision by comparing the phase difference of the leash angle vs the difference between the candidate and the current node
            new = (min if clockwise else max)(candidates, key=lambda n: (leash_angle - phase(n - center)) % (2 * pi))

            # convert the difference to polar coordinates
            distance, new_angle = polar(new - center)
            # draw the arc
            if clockwise:
                axes.add_patch(patches.Arc(
                    (center.real, center.imag),
                    leash_size * 2, leash_size * 2,
                    new_angle * degrees,
                    0,
                    (leash_angle-new_angle) * degrees
                ))
            else:
                axes.add_patch(patches.Arc(
                    (center.real, center.imag),
                    leash_size * 2, leash_size * 2,
                    leash_angle * degrees,
                    0,
                    (new_angle - leash_angle) * degrees
                ))
            # draw intermediate lines
            edge = rect(leash_size, new_angle) + center
            axes.plot([center.real, edge.real], [center.imag, edge.imag], "g")

            # perform updates: decrease remaining leash size, set new leash angle, move rotation center to the collision
            leash_size -= distance
            leash_angle = new_angle
            center = new

    # show the graph
    pyplot.show()

इसका उत्पादन इस तरह होता है:

पिछली छवि के समान लेकिन अधिक रेखाएँ


एक बहुत ही शानदार विवरण के लिए +1 और मुझे लगभग दोगुने से अधिक गोल्फ होने के लिए! <s> gosh मैं उन
बिल्डरों से

7

प्रसंस्करण 3, 815 833 835 876 879 बाइट्स

अनावश्यक कोष्ठक को हटाकर @ZacharyT को दो बाइट्स का धन्यवाद दिया

void settings(){size(600,600);}int i,w,x,n;float l,d,t,a,f,g,m,R,U;float[][]N,T;float[]S,p;void s(float[][]t){N=new float[t.length+1][2];N[0][0]=N[0][1]=i=0;for(float[]q:t)N[++i]=q;translate(w=300,w);noFill();pushMatrix();f(N,0,-w,w,1,0);popMatrix();f(N,0,-w,w,0,0);}float p(float a,float b){for(a+=PI*4;a>b;)a-=PI*2;return a;}void f(float[][]P,float x,float y,float L,int c,int I){l=2*PI;d=i=0;S=null;for(;i<P.length;i++){float[]p=P[i];g=atan2(y,x);m=atan2(p[1],p[0]);if(p(f=(c*2-1)*(g-m),0)<l&(t=dist(0,0,p[0],p[1]))<=L&I!=i){l=p(f,0);S=new float[]{g,m};d=t;n=i;}}if(S==null)ellipse(0,0,2*(L-d),2*(L-d));else{arc(0,0,L*2,L*2,p(S[c],S[1-c]),S[1-c]);R=cos(a=S[1]);U=sin(a);translate(d*R,d*U);T=new float[P.length][2];for(int i=0;i<T.length;T[i][1]=P[i][1]-d*U,i++)T[i][0]=P[i][0]-d*R;f(T,(L-d)*R,(L-d)*U,L-d,c,n);}}

इस प्रोग्राम को ऐसे चलाएं:

void setup() {
    s(new float[][]{{0,100},{100,100},{-200,100},{-100,-50}});
}

(फ़ंक्शन में sलेता है float[][])। यह अनिवार्य रूप से # 3 का परीक्षण है, लेकिन खिड़की को फिट करने के लिए इसे 100 से गुणा किया जाता है।

ध्यान देने योग्य कई बातें:

  • कार्यक्रम डंडे नहीं खींचता है
  • छवियाँ उलटी-सीधी दिखाई देती हैं क्योंकि प्रसंस्करण की समन्वय प्रणाली में, सकारात्मक y- अक्ष नीचे चला जाता है
  • क्योंकि प्रसंस्करण फ़्लोट का उपयोग करता है, गणना बहुत सटीक नहीं है, इसलिए आप इसे छवियों में देख सकते हैं। मैंने ओपी से पूछा है कि क्या ये फ़्लोटिंग-पॉइंट त्रुटि मामला है।
  • खिड़की का आकार 600 पिक्सल 600 पिक्सल है
  • बहुत छोटे इनपुट निर्देशांक कार्यक्रम को बोर कर देंगे क्योंकि स्टैक pushMatrix()और popMatrix()संचालन केवल 32 मैट्रिसेस को पकड़ सकते हैं।
  • कुत्ता (0 -300) पर शुरू होता है और श्रृंखला 300 पिक्सेल लंबी होती है
  • नीचे दी गई छवियों को सुविधा के लिए छोटा किया गया है

उपरोक्त टेस्टकेस के लिए नमूना आउटपुट।

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

यदि आप पहले से तैयार आउटपुट देखना चाहते हैं, तो translate(w,w);फ़ंक्शन के ठीक बाद इस लाइन को जोड़ें s

background(-1);scale(1,-1);fill(255,0,0);ellipse(0,0,25,25);fill(0);for(float[]q:N)ellipse(q[0],q[1],25,25);

और यह हमें यह परिणाम देता है:

वृत्त

अपुष्ट f()और व्याख्या

(इसमें डिबग कोड भी शामिल है)

void f(float[][]points, float x, float y, float len, int c, int pindex) {
    print(asd+++")");
    float closest = 2*PI;
    float d=0,t;
    float[]stuff = null;
    int index = 0;
    for(int i=0;i<points.length;i++) {
        if(pindex != i) {
            float[]p = points[i];
            float originAngle = atan2(y, x);
            float tempAngle = atan2(p[1], p[0]);
            //println(x,y,p[0],p[1]);
            float diff = c<1?tempAngle-originAngle:originAngle-tempAngle;
            println("@\t"+i+"; x=\t"+x+"; y=\t"+y+"; tx=\t"+p[0]+"; ty=\t",p[1], diff, originAngle, tempAngle);
            if(p(diff) < closest && (t=dist(0,0,p[0],p[1])) < len) {
                println("+1");
                closest = p(diff);
                stuff = new float[]{originAngle, tempAngle};
                d=t;
                index = i;
            }
        }
    }
    if(stuff == null) {
        ellipse(0,0,2*(len-d),2*(len-d));
        println("mayday");
    } else {
        println("d angles",d,p(stuff[c],stuff[1-c],c), stuff[1-c]);
        //println(points[0]);
        arc(0, 0, len*2, len*2, p(stuff[c],stuff[1-c],c), stuff[1-c]);
        float angle = stuff[1];
        translate(d*cos(angle), d*sin(angle));
        println("Translated", d*cos(angle), d*sin(angle));
        println("angle",angle);
        float[][]temp=new float[points.length][2];
        for(int i=0;i<temp.length;i++){
            temp[i][0]=points[i][0]-d*cos(angle);
            temp[i][1]=points[i][1]-d*sin(angle);
            println(temp[i]);
        }
        println(d*sin(angle));
        pushMatrix();
        println();
        f(temp, (len-d)*cos(angle), (len-d)*sin(angle), (len-d), c, index);
        popMatrix();
        //f(temp, (len-d)*cos(angle), (len-d)*sin(angle), (len-d), 0, index);
    }
}

इसे शीघ्र ही डालने के लिए, कार्यक्रम दो "चाहने वालों" को भेजता है, एक विरोधी दक्षिणावर्त और दूसरा दक्षिणावर्त। इनमें से प्रत्येक साधक निकटतम ध्रुव को पाता है और एक चाप खींचता है यदि श्रृंखला काफी लंबी है, तो अन्य बुद्धिमान इसे एक चक्र खींचते हैं। एक बार जब यह एक चाप खींचता है, तो यह उस ध्रुव पर एक और साधक भेजता है और यह प्रक्रिया जारी रहती है। f()प्रत्येक साधक की प्रक्रिया शामिल है। जैसे ही मैं इसे और अधिक विस्तृत करूंगा, एक और विस्तृत विवरण आएगा।


क्या आपको लास्ट के आसपास पैरेंस की जरूरत है L-d?
Zacharý

@ZacharyT मुझे नहीं पता कि मैं कैसे चूक गया, धन्यवाद।
कृति लिथोस

5

लोगो, 305 298 297 293 बाइट्स

FMSLogo पर कोड का प्रयास करें।

एक फ़ंक्शन को परिभाषित करें draw(जैसे dकि गोल्फ में ), जो कि पोल समन्वय की सूची के रूप में इनपुट दिया गया है (उदाहरण के लिए draw [[0 100] [100 100] [-200 100] [-100 -50][0 0]], परिणाम स्क्रीन पर आ जाएगा।

आवश्यकताएँ:

  1. प्रारंभिक रस्सी की लंबाई = 300 पिक्सेल। (3 पिक्सेल बहुत छोटा है)
  2. [0 0]पोल सूची में शामिल होना चाहिए। यदि डिबग कोड (ड्रा पोल) चालू है, तो [0 0]अंतिम आइटम होना चाहिए।
  3. कुत्ते समन्वय शुरू करते हैं x=0, y=-300(समस्या वर्णन में)

संभावित अनुकूलन:

  1. -1 बाइट यदि असाधारण स्थिति (कुत्ते को एक पोल में चलाया जाता है) के >=साथ बदलकर गणितीय रूप से सही होने की आवश्यकता नहीं है>

गोल्फ कोड:

to f
op(if ?=pos 360 modulo :m*(180+heading-towards ?)360)
end
to x :m[:1 300]
home
forever[make 2 filter[:1>=u ?](sort :p[(u ?)<u ?2])invoke[pd
arc -:m*f :1
pu
if 360=f[stop]make 1 :1-u ?
lt :m*f
setpos ?]reduce[if f<invoke[f]?2[?][?2]]:2]
end
to d :p
copydef "u "distance
foreach[1 -1]"x
end

Ungolfed कोड ( ;एक इनलाइन टिप्पणी (स्पष्टीकरण के लिए उपयोग किया जाता है), और :एक चर नाम शुरू होता है):

to f
    op ifelse ? = pos 360 modulo :m*(180 + heading - towards ?) 360
end

to x
    home
    foreach :poles [pu setpos ? pd circle 5] ; debug code
    make "length 300 ; initial length of rope
    forever [
        make "tmp filter [:length >= distance ?] ; floating point error makes > and >= similar,  ~
            ; but >= is correct mathematically ~
            (sort :poles [(distance ?) < distance ?2])
         ; the last = longest element will be rotated
        invoke [
            pd
            arc -:m*f :length
            pu
            if 360=f [stop]
            make "length :length - distance ?
            lt :m*f
            setpos ?
        ] reduce [
            if f < invoke[f]?2 [?] [?2]
        ] :tmp ; apply to use ? instead of :pos
    ]
end

to draw :poles
    foreach [1 -1] [[m]
        x
    ]
end

1

पायथन 2 + पीआईएल, 310 बाइट्स

from PIL import Image
from cmath import*
I,_,X,P=Image.new('1',(300,300),'white'),abs,polar,input()
def r(s):
 a,C,l=0,0,3
 while _(a)<99:
  c=C+l*exp(1j*a);I.load()[c.real*30+150,150-c.imag*30]=0
  for p in P+[0]:
   N,E=X(C-c);n,e=X(C-p)
   if n<=N and _(E-e)<.1:l-=_(p-C);C=p
  a+=s
r(.01)
r(-.01)
I.show()

स्क्रिप्ट स्टैड से बिंदुओं की सूची को जटिल संख्याओं की सूची के रूप में पढ़ती है।

printf '[complex(0,0.5)]' | python2 snippet.py

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

printf '[complex(0,1), complex(1,1)]' | python2 snippet.py

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.