त्रिकोणीय युद्धपोत (एक कम्प्यूटेशनल ज्यामिति समस्या)


18

आप एक युद्धपोत के कप्तान हैं। इंजीनियरिंग विभाग इस साल डिजाइन के साथ कोनों को काट रहा है, इसलिए आप जिस जहाज पर हैं वह एक साधारण त्रिकोण का आकार लेता है।

आप डेक पर चलते हैं और समुद्री हवा का आनंद लेते हैं ... हालांकि लंबे समय तक नहीं। एक दुश्मन ने तुम पर गोली चलाई है! - लेकिन क्या गोली चलेगी?

इनपुट

आप इस चुनौती के लिए एक फ़ंक्शन या पूर्ण प्रोग्राम लिख सकते हैं।

आपका कार्यक्रम 11 पूर्णांक में होगा, जिनमें से दस जोड़े हैं:

  • पूर्णांक के पहले तीन जोड़े (x 1 , y 1 ), (x 2 , y 2 ), (x 3 , y 3 ) आपके जहाज के शीर्ष को निर्दिष्ट करेंगे। गठित त्रिकोण में गैर-अक्षीय क्षेत्र होगा।

  • पूर्णांक की अगली जोड़ी (e x , e y ) दुश्मन की तोप के स्थान को निर्दिष्ट करती है। दुश्मन तोप कभी भी, या आपके जहाज की सीमा के भीतर नहीं होगी। *

  • उसके बाद जोड़ी (एक एक्स , एक वाई ) निर्दिष्ट करती है कि दुश्मन का उद्देश्य कहां है। यह (e x , e y ) से अलग होगा ।

  • अंतिम सकारात्मक पूर्णांक आर दुश्मन के शॉट की सीमा को निर्दिष्ट करता है

* यदि आप ऐसा नहीं करते तो आप एक भयानक कप्तान होंगे!

उत्पादन

प्रिंट करें / एक वापसी truthy मूल्य (जैसे सच है, 1) युद्धपोत मारा जाएगा अगर, अन्यथा एक falsy मूल्य (जैसे झूठे, 0)।

हिट क्या है?

दुश्मन शॉट एक सीधी रेखा से (ड लंबाई आर के खंड है एक्स , ई y के (एक दिशा में) एक्स , एक y )। यदि यह रेखा खंड आपके त्रिकोणीय युद्धपोत के इंटीरियर के किसी भी हिस्से को ओवरलैप करता है , तो यह हिट के रूप में गिना जाता है। अन्यथा यह हिट नहीं है।

शॉट्स जो केवल साथ-साथ या त्रिकोण की सीमा तक पहुँचते हैं, हिट के रूप में नहीं गिने जाते हैं।

उदाहरण

0 0 0 1 1 0
1 1
0 0
2

test1

हिट: दुश्मन ने अपने जहाज के केंद्र के माध्यम से सही गोली मार दी है!


2 0 0 2 4 4
0 0
1 1
1

test2

कोई हिट नहीं: दुश्मन की सीमा बहुत कम है, इसलिए आप सुरक्षित हैं।


0 0 1 2 3 0
-4 0
0 0
8

test3

कोई हिट नहीं: दुश्मन ने आपके जहाज के किनारे को पकड़ लिया है, इसलिए यह हिट के रूप में नहीं गिना जाता है। सौभाग्यशाली!


0 0 -1 3 4 -1
-3 -4
3 4
5

test4

कोई हिट नहीं: दुश्मन का शॉट सिर्फ जहाज की कमी को रोकता है, इसलिए आप सुरक्षित हैं। अगर दुश्मन की तोप थोड़ी और भी बेहतर रेंज की होती, तो आप हिट हो जाते! ओह!


-2 -3 -3 6 7 -2
-6 2
1 -4
7

test5

हिट: भले ही शॉट दूसरी तरफ नहीं घुसा, लेकिन यह अभी भी एक हिट है।


-3 2 2 -4 7 -3
-3 -4
-3 0
10

test6

कोई हिट नहीं: रिकॉर्ड के लिए, यह एक और करीबी मिस है।


अतिरिक्त परीक्षण के मामले

0 0 6 0 6 8
-6 -8
6 8
20

test7

कोई हिट नहीं: यह एक और ग्रेड है, लेकिन एक कोण पर।


0 0 -2 -5 5 3
-3 4
0 0
6

test8

हिट: शॉट जहाज के एक शीर्ष के माध्यम से प्रवेश किया।

स्कोरिंग

यह , इसलिए बाइट्स में सबसे छोटा कोड जीत जाता है। मानक खामियां लागू होती हैं।


बस यह सुनिश्चित करने के लिए कि हम नहीं कर सकते हैं: क्या हम मान सकते हैं कि जहाज में कोई नीचे नहीं है और प्रत्येक दो पक्षों के बीच एक छोटा सा अंतर है, ताकि अगर शॉट अपने कोने से जहाज में प्रवेश करने का प्रबंधन करता है, तो हम इसे एक मिस के रूप में गिनते हैं?
जॉन ड्वोरक

@JDDvorak यदि जहाज से एक शॉट चोटी के माध्यम से प्रवेश करके कटता है, तो यह एक हिट होगा क्योंकि लाइन खंड जहाज के इंटीरियर को ओवरलैप करता है। तो 4 वें उदाहरण में, यदि सीमा 5 से अधिक थी, तो यह एक हिट होगी।
Sp3000

हमें तर्कों के साथ खेलने की कितनी अनुमति है? क्या हमें उन्हें समूह बनाने, आदेश बदलने या उन्हें तैरने की आवश्यकता है?
FryAmTheEggman

@FryAmTheEggman आप आवश्यक के रूप में तर्कों को समूह या फिर से व्यवस्थित कर सकते हैं। आप झांकियों का उपयोग कर सकते हैं, लेकिन कार्यक्रम को सटीकता के बारे में चिंता किए बिना छोटे ग्रिड (जैसे, 20x20 तक) के लिए सही ढंग से काम करने की आवश्यकता है।
21338 पर Sp3000

मुझे लगता है कि उदाहरण एक महत्वपूर्ण मामले को याद कर रहे हैं जो मेरे इच्छित समाधान को विफल कर देते हैं: जब जहाज को एक कोने से घुसना होता है, उदाहरण के लिए 0 0 -1 3 4 -1 -3 -4 3 4 6
नटकी

जवाबों:


3

पायथन 3, 252 बाइट्स

यह निश्चित रूप से सबसे अधिक चर है जो मैंने कभी कोड गोल्फ में उपयोग किया है। : ^ पी

from math import*;A=atan2
def h(a,b,c,d,e,f,g,h,i,j,R):
 r=R;_=0
 while r>0:Q=A(j-h,i-g);k,l=g+r*cos(Q),h+r*sin(Q);D=A(d-b,c-a);E=A(f-b,e-a);F=A(l-b,k-a);G=A(b-d,a-c);H=A(f-d,e-c);I=A(l-d,k-c);_=_ or(D<F<E or E<F<D)and(G<I<H or H<I<G);r-=.001
 return _

टिप्पणियों के साथ थोड़ा असंतुष्ट:

from math import*
# Parameters:
#  (a,b) (c,d) (e,f) - vertices of the triangle
#  (g,h) - location of cannon
#  (i,j) - aim of cannon
#  R - range of cannon
# Variables within function:
#  _ - was this shot a hit?
#  r - distance 0 < r <= R that we're testing
#  Q - angle between cannon source and destination
#  (k,l) - point that we're testing
#  D,E,F - angles between point 1 and 2,3,test
#  G,H,I - angles between point 2 and 1,3,test
def h(a,b,c,d,e,f,g,h,i,j,R):
    r=R;_=0
    while r>0:
        Q=atan2(j-h,i-g)
        k,l=g+r*cos(Q),h+r*sin(Q)
        D=atan2(d-b,c-a)
        E=atan2(f-b,e-a)
        F=atan2(l-b,k-a)
        G=atan2(b-d,a-c)
        H=atan2(f-d,e-c)
        I=atan2(l-d,k-c)
        _=_ or(D<F<E or E<F<D)and(G<I<H or H<I<G)
        r-=.001
    return _

यह काम किस प्रकार करता है:

  • शॉट के समापन बिंदु की गणना करें।
  • समापन बिंदु से तोप के स्थान तक लाइन के साथ बहुत सारे बिंदुओं का परीक्षण करें:
    • शीर्ष 1 से अन्य दो कोने तक और परीक्षण बिंदु पर कोणों की गणना करें;
    • शीर्ष 2 से अन्य दो कोने तक और परीक्षण बिंदु पर कोणों की गणना करें;
    • यदि परीक्षण बिंदु कोण दोनों मामलों में अन्य दो कोणों के बीच है, तो परीक्षण बिंदु त्रिकोण के भीतर है और जहाज को हिट किया गया है।

नमूना चलता है:

>>> h(0,0,0,1,1,0,1,1,0,0,2)
True
>>> h(0,0,1,2,3,0,-4,0,0,0,8)
False
>>> h(0,0,-1,3,4,-1,-3,-4,3,4,5)
False
>>> h(-2,-3,-3,6,7,-2,-6,2,1,-4,7)
True

2

पायथन 2.7, 235 बाइट्स

from numpy import*
X=cross
h=lambda q,w,a,s,y,x,c,v,d,f,r:max([(X([a-q,s-w],[c+k*(d-c)-q,v+k*(f-v)-w])>0)==(X([y-a,x-s],[c+k*(d-c)-a,v+k*(f-v)-s])>0)==(X([q-y,w-x],[c+k*(d-c)-y,v+k*(f-v)-x])>0)for k in arange(0,r/hypot(d-c,f-v),1e-4)])

AB x APकोनों A, B और बिंदु P के बीच के क्रॉस उत्पाद की गणना करता है । यदि तीनों का चिन्ह समान है, तो बिंदु त्रिभुज के अंदर है।

Ungolfed:

from numpy import *
def i(q,w,a,s,y,x,e,r): # helper-function, checks whether ER is inside the triangle QW-AS-YX
  t=cross([a-q,s-w],[e-q,r-w])>0
  g=cross([y-a,x-s],[e-a,r-s])>0
  b=cross([q-y,w-x],[e-y,r-x])>0
  return t==g==b

def h(q,w,a,s,y,x,c,v,d,f,r):
  R=arange(0,r/hypot(d-c,f-v),1e-3)
  return max([i(q,w,a,s,y,x,c+k*(d-c),v+k*(f-v)) for k in R])

टेस्ट:

In : h(0,0,0,1,1,0,1,1,0,0,2)
Out: True

In : h(-3,2,2,-4,7,-3,-3,-4,-3,0,10)
Out: False

In : h(0,0,1,2,3,0,-4,0,0,0,8)
Out: True
     Grazes may count as hits...
In : h(1,2,0,0,3,0,-4,0,0,0,8)
Out: False
     ...or not, depending on the order of edges

1

सी, 247 बाइट्स

निश्चित रूप से अभी तक काफी गोल्फ नहीं हुई है।

#include<math.h>
int z(float*k){float s=1e-3,t=s,p=k[8]-k[6],q=k[9]-k[7],r=k[10]/hypot(p,q);int w=0;for(;t<1;t+=s){float x=k[6]-k[0]+p*r*t,y=k[7]-k[1]+q*r*t,b=k[2]*k[5]-k[3]*k[4],d=(x*k[5]-y*k[4])/b,e=(x*k[3]-y*k[2])/b;w|=d>0&e<0&d-e<1;}return w;}

वर्तमान में यह DLosc के समाधान के समान एक दृष्टिकोण का उपयोग करता है, अर्थात यह त्रिकोण के साथ अंतर करता है, यह निर्धारित करने के लिए लाइन खंड पर सभी संभव निर्देशांक के माध्यम से पुनरावृत्त करता है। (यदि यह सीमा 1000 से अधिक है तो यह विफल हो जाएगा) हालाँकि, यह सूत्र का उपयोग करता है कि क्या त्रिभुज के अंदर कोई बिंदु है , यह निर्धारित करने के लिए http://mathworld.wolfram.com/TriangleInterior.html । यह त्रिकोणमितीय कार्यों के एक समूह से बचा जाता है।


उदाहरण जाँच, प्रिंट होना चाहिए 1 0 0 0 1 0

#include <stdio.h>
int main() {
    {
        float arr[] = {0,0,0,1,1,0,1,1,0,0,2};
        printf("%d\n", z(arr));
    }

    {
        float arr[] = {2,0,0,2,4,4,0,0,1,1,1};
        printf("%d\n", z(arr));
    }

    {
        float arr[] = {0,0,1,2,3,0,-4,0,0,0,8};
        printf("%d\n", z(arr));
    }

    {
        float arr[] = {0,0,-1,3,4,-1,-3,-4,3,4,5};
        printf("%d\n", z(arr));
    }

    {
        float arr[] = {-2,-3,-3,6,7,-2,-6,2,1,-4,7};
        printf("%d\n", z(arr));
    }

    {
        float arr[] = {-3,2,2,-4,7,-3,-3,-4,-3,0,10};
        printf("%d\n", z(arr));
    }
}

1

जावास्क्रिप्ट (ईएस 6) 320 448 522 627

(अभी भी और अधिक गोल्फ हो सकता है?)

कदम:

  1. वास्तविक हिट लक्ष्य का पता लगाएं (दुश्मन से लाइन पर दूरी आर पर बिंदु)
  2. हिट: यदि लक्ष्य से दुश्मन का खंड जहाज के किसी भी पक्ष को काटता है, लेकिन समापन बिंदु पर नहीं
  3. हिट भी: यदि लक्ष्य जहाज के अंदर है - भले ही शॉट एक शीर्ष पर दर्ज किया गया हो - टेस्ट केस 8

Ref:
सेगमेंट चौराहे
प्वाइंट अंदर त्रिकोण
बिंदु एक खंड में दूरी दी

फ़ायरफ़ॉक्स में परीक्षण

C=(i,j,k,l,m,n,g,h,a,b,r,
  d=a-g,e=b-h,f=r/Math.sqrt(d*d+e*e),
  p=g+f*d,q=h+f*e,
  z=j*(m-k)+i*(l-n)+k*n-l*m,
  s=(j*m-i*n+(n-j)*p+(i-m)*q)/z,
  t=(i*l-j*k+(j-l)*p+(k-i)*q)/z,
  S=(i,j,k,l,
     a=k-i,b=l-j,c=p-g,d=q-h,e=i-g,f=j-h,
     s=a*f-b*e,t=c*f-d*e,m=a*d-c*b)=>
     m&&((s/=m)>0&s<1&(t/=m)>0&t<1)
)=>s>0&t>0&s+t<1|S(i,j,k,l)|S(i,j,m,n)|S(m,n,k,l)

// Test
MyOutput.innerHTML = ['Test1', C(0,0, 0,1, 1,0, 1,1, 0,0, 2),
'<br>Test2', C(2,0, 0,2, 4,4, 0,0, 1,1, 1),
'<br>Test3', C(0,0, 1,2, 3,0, -4,0, 0,0, 8),
'<br>Test4', C(0,0, -1,3, 4,-1, -3,-4, 3,4, 5),
'<br>Test5', C(-2,-3, -3,6, 7,-2, -6,2, 1,-4, 7),
'<br>Test6', C(-3,2, 2,-4, 7,-3, -3,-4, -3,0 ,10),
'<br>Test7', C(0,0, 6,0, 6,8, -6,-8, 6,8, 20),
'<br>Test8', C(0,0,-2,-5, 5,3, -3,4, 0,0, 6)];
<div id="MyOutput"></div>

Ungolfed

function check(p0x, p0y, p1x, p1y, p2x, p2y, ex, ey, ax, xy, r)
{
  var sec = function(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y)
  {
      var s10x = p1x - p0x, s10y = p1y - p0y, 
          s32x = p3x - p2x, s32y = p3y - p2y,
          s02x = p0x - p2x, s02y = p0y - p2y,
          s = s10x * s02y - s10y * s02x, t = s32x * s02y - s32y * s02x,
          d = s10x * s32y - s32x * s10y;
      return d && (s/=d) > 0 && s<1 && (t/=d) > 0 && t < 1 && [p0x + (t * s10x), p0y + (t * s10y)];
  }
  var pr = function(p0x, p0y, p1x, p1y, r)
  {
      var dx = (p1x-p0x), dy = (p1y-p0y), f = r/Math.sqrt(dx*dx+dy*dy);
      return [p0x + f*dx, p0y+f*dy];
  }
  var inside = function(p0x, p0y, p1x, p1y, p2x, p2y, px, py)
  {
      var area2 = (-p1y*p2x + p0y*(-p1x + p2x) + p0x*(p1y - p2y) + p1x*p2y),
          s = (p0y*p2x - p0x*p2y + (p2y - p0y)*px + (p0x - p2x)*py)/area2,
          t = (p0x*p1y - p0y*p1x + (p0y - p1y)*px + (p1x - p0x)*py)/area2;
      return s > 0 && t > 0 && s+t < 1;
  }
  var tx, xy;
  [tx, ty] = pr(ex, ey, ax, ay, r);

  return inside(p0x, p0y, p1x, p1y, p2x, p2y, tx,ty)
  || sec(p0x, p0y, p1x, p1y, ex, ey, tx, ty)
  || sec(p0x, p0y, p2x, p2y, ex, ey, tx, ty)
  || sec(p2x, p2y, p1x, p1y, ex, ey, tx, ty);
}  
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.