উত্তল হাল মধ্যে পয়েন্ট (2D)


10

পটভূমি

উত্তল জাহাজের কাঠাম পয়েন্ট একটি নির্দিষ্ট সংখ্যা নয় ক্ষুদ্রতম উত্তল বহুভুজ যে পয়েন্ট সব রয়েছে, নয়তো ছেদচিহ্ন হিসাবে অথবা অভ্যন্তর উপর। আরও তথ্যের জন্য, পিজিমে এই প্রশ্নটি দেখুন যা এটি খুব ভালভাবে সংজ্ঞায়িত করে

ইনপুট

N+12-ডি স্থানাঙ্কগুলি ( N >= 3) STDINঅন্যান্য বিন্যাসের (অন্যান্য স্বাভাবিক গল্ফ ইনপুটগুলির সাথে অনুমোদিতও) নীচের ফর্ম্যাটে (দশমিকের সংখ্যা পৃথক হতে পারে তবে আপনি এটি "যুক্তিসঙ্গত" বলে ধরে নিতে পারেন এবং প্রতিটি সংখ্যা একটি ভাসমান হিসাবে উপস্থাপিত হতে পারে):

0.00;0.00000
1;0.00
0.000;1.0000
-1.00;1.000000

আউটপুট

একজন truthy মান মুদ্রিত STDOUT(অথবা সমতুল্য) যদি তালিকার প্রথম পয়েন্ট ( (0.00;0.00000)উপরোক্ত উদাহরণের) অন্য এন পয়েন্ট উত্তল জাহাজের কাঠাম মধ্যে, এবং একটি falsy মান অন্যথায়।

এটি , তাই বাইটগুলির মধ্যে সংক্ষিপ্ততম সমাধানটি জিতে।

  • সীমান্ত ক্ষেত্রে : আপনি যদি কোনও মান (তবে ক্রাশ করবেন না) ফিরে দিতে পারেন তবে যদি বিন্দুটি উত্তল হলের সীমান্তে থাকে (যেমন একটি দিকের বা হলের বাইরের সীমান্তের একটি শীর্ষে), কারণ এটি শূন্যতার সম্ভাবনা ইভেন্ট (কোনও যুক্তিসঙ্গত সম্ভাবনার অধীনে)।

  • নিষিদ্ধ : যে কোনও কিছু (ভাষা, অপারেটর, ডেটা স্ট্রাকচার, অন্তর্নির্মিত বা প্যাকেজ) যা কেবল জ্যামিতিক সমস্যা সমাধানের জন্য বিদ্যমান (যেমন ম্যাথমেটিকার কনভেক্সহুল )। সাধারণ উদ্দেশ্যে গাণিতিক সরঞ্জামগুলি (ভেক্টর, ম্যাট্রিক্স, জটিল সংখ্যা ইত্যাদি) অনুমোদিত।

টেস্ট


3
"অ্যাডহক ডেটা স্ট্রাকচার" কী?
ডেভিডসি

"প্রাথমিক ফাংশন / অপারেটর" অনেকটা অস্পষ্ট।
xnor

@ ডেভিডকার্যাহার: বহুভুজ, ত্রিভুজ বা একটি বিভাগ (কিছু যা কেবল জ্যামিতিক সমস্যা সমাধানের জন্য বিদ্যমান)।
আলেকজান্দ্রির হালাম

2
@ আলেকজান্দ্রহালম আপনার সম্পাদনাটি অনেক সহায়তা করেছে। আমি মনে করি "প্রাথমিক" সঠিক শব্দ নয়। আমি ভেবেছিলাম এটি সাধারণ উদ্দেশ্যগুলি যেমন বিল্ট-ইনগুলি sortবা দূর করে দেবে round। আমি মনে করি জ্যামিতির জন্য বিশেষভাবে তৈরি কোনও কিছু অনুমোদিত নয় বলে কেবল এটি পরিষ্কার করা উচিত। তবে, ভেক্টর হিসাবে দুটি তালিকা যুক্ত করার জন্য একটি ফাংশন সম্পর্কে কী? অথবা জটিল সংখ্যার আর্গুমেন্ট (কোণ) সন্ধান করার জন্য একটি ফাংশন?
xnor

1
এই কারণেই ডায়মন্ডগুলি লোকেদের অনুরোধ করে নতুন চ্যালেঞ্জ পোস্ট করার আগে স্যান্ডবক্সটি ব্যবহার করুন
বিড়াল

উত্তর:


9

জে, 40 39 34 বাইট

3 :'(o.1)<(>./-<./)12 o.y*+{.y'@:-

একটি অনামী ডায়াডিক ফাংশন, তার একটি আর্গুমেন্ট হিসাবে একটি পয়েন্ট, পি গ্রহণ করে এবং পয়েন্টগুলির একটি তালিকা, পি , অন্য যুক্তি হিসাবে (এটি কোন যুক্তি কোন বিষয় তা বিবেচনা করে না), এবং ফিরে 0বা 1, যদি পি বাইরে থাকে বা পি এর উত্তল হাল এর ভিতরে যথাক্রমে। বিন্দু পি , এবং পয়েন্ট পি , জটিল সংখ্যা হিসেবে নেয়া হয়।

উদাহরণ

  is_inside =: 3 :'(o.1)<(>./-<./)12 o.y*+{.y'@:-

  0.5j0.5  is_inside  0j0 0j1 1j0 1j1
1
  1.5j0.5  is_inside  0j0 0j1 1j0 1j1
0

বা ...

পাইথন 2, ফাংশন, 121 103, সম্পূর্ণ প্রোগ্রাম, 162

পাইথন 3, 149 বাইট

import sys,cmath as C
p,q,*P=[complex(*eval(l.replace(*";,")))for l in sys.stdin]
A=[C.phase((r-p)/(q-p+(q==p)))for r in P]
print(max(A)-min(A)>C.pi)

এসটিডিআইএন এর মাধ্যমে মূল পোস্টের মতো একই ফর্ম্যাটে ইনপুট নেয় এবং একটি বুলিয়ান মান মুদ্রণ করে যা পি এর উত্তল হলের মধ্যে রয়েছে কিনা তা নির্দেশ করে


ব্যাখ্যা

প্রোগ্রাম পরীক্ষা সর্বোচ্চ এবং সর্বনিম্ন (স্বাক্ষরিত) মধ্যে পার্থক্য যে কোনো স্থানে মধ্যে angles কিনা R মধ্যে পি , পি , এবং একটি নির্দিষ্ট অবাধ বিন্দু কুই মধ্যে পি (আমরা শুধু প্রথম বিন্দু ব্যবহার পি ), 180 কম °। অন্য কথায়, এটা টেস্টে সব পয়েন্ট কিনা পি 180 এর একটি কোণের অন্তর্ভুক্ত করা হয় ° বা কম প্রায় পিপি এর উত্তল হালতে পি থাকে এবং যদি কেবল এই শর্তটি মিথ্যা থাকে।


মনে রাখবেন, উপরে শর্ত এই বলে যে সমতূল্য: আরো কয়েকটি বাইট খরচ এ, আমরা একটি অনুরূপ পদ্ধতি যা আমাদের কাছে স্পষ্টভাবে ক্যালকুলেট কোণ প্রয়োজন হয় না ব্যবহার করতে পারেন পি এর উত্তল জাহাজের কাঠাম বাইরে পি যদি এবং কেবল যদি অস্তিত্ব আছে একটি লাইন মাধ্যমে পি , এ সব পয়েন্ট যেমন যে পি একই দিকে হয় । যেমন একটি লাইন অস্তিত্ব থাকে, তাহলে এর রয়েছে যেমন একটি লাইন যে এক (বা তার বেশি) পয়েন্ট এর ঘটনা পি (আমরা যা করতে পারেন ঘোরান পর্যন্ত এটি পয়েন্ট এক স্পর্শ পি ।)

করার জন্য (সম্ভবত) এই লাইন খুঁজে, আমরা লেট করে শুরু মাধ্যমে লাইন হতে পি এবং প্রথম বিন্দু পি । এরপরে আমরা পি এর বাকি পয়েন্টগুলি নিয়ে পুনরাবৃত্তি করি ; পয়েন্ট এক বাঁদিকে হলে (আমরা, সর্বত্র কিছু অভিমুখ অনুমান বাম বা ডান, সত্যিই কোন ব্যাপার না) আমরা প্রতিস্থাপন লাইন মাধ্যমে ক্ষণস্থায়ী সঙ্গে পি এবং যে পয়েন্ট, এবং অবিরত। পরে আমরা সর্বাঙ্গে iterated পি , যদি (এবং কেবল যদি) পি উত্তল জাহাজের কাঠাম বাহিরে হয়, তাহলে সব পয়েন্ট পি (অথবা দিকে) ডানদিকে হওয়া উচিত । আমরা পরীক্ষা করে দেখি যে পি তে পয়েন্টগুলির উপর একটি দ্বিতীয় পাস ব্যবহার করে

পাইথন 2, 172 বাইট

import sys
P=[eval(l.replace(*";,"))for l in sys.stdin]
x,y=P.pop(0)
C=lambda(a,b),(c,d):(a-x)*(d-y)-(b-y)*(c-x)>0
l=reduce(lambda*x:x[C(*x)],P)
print any(C(l,q)for q in P)


অন্যথা, একটি একক পাস একই জিনিস করতে হবে, দিন টু--বাম-অফ কোনো দুই পয়েন্ট মধ্যে একটি realtion হতে কুই এবং , এ পি , যেমন যে কুই -এর বাঁদিক থেকে যদি কুই বাঁদিক থেকে লাইন মাধ্যমে ক্ষণস্থায়ী পি এবং । নোট যে-বাম-এর উপর একটি আদেশ সম্পর্ক নেই পি যদি এবং কেবল যদি এ সব পয়েন্ট পি কিছু লাইন মাধ্যমে ক্ষণস্থায়ী একই দিকে হয় পি যে, যদি, পি এর উত্তল জাহাজের কাঠাম বাইরে পি । উপরে বর্ণিত পদ্ধতিটি পি এর সর্বনিম্ন পয়েন্টটি সন্ধান করেএই অর্ডারটি ਆਰ্ট করুন, অর্থাত্ পি এর "বামতমতম" পয়েন্ট । দুটি পাস করার পরিবর্তে, আমরা সর্বাধিক (যেমন, "ডানদিকের" পয়েন্ট) পাশাপাশি সর্বনিম্ন, পি আর্টে একই পাসে একই পয়েন্টে পয়েন্ট পেতে পারি এবং যাচাই করি যে সর্বনিম্নের বাম দিকে রয়েছে সর্বাধিক, অর্থাত্ কার্যকরভাবে, যে-থেকে-বাম-এর ট্রানজিটিভ হয়।

এই ভাল কাজ করবে যদি পি এর উত্তল জাহাজের কাঠাম বাইরে পি , যে ক্ষেত্রে টু--বাম-অফ আসলে একটা অর্ডার সম্পর্ক নেই, কিন্তু ভঙ্গ করতে পারে পি (উদাহরণস্বরূপ উত্তল জাহাজের কাঠাম ভিতরে হয়, জিনিসটা কি হবে চেষ্টা যদি আমরা এই অ্যালগরিদম যেখানে পয়েন্ট দৌড়ে ঘটতে পি একটি নিয়মিত পঞ্চভূজ ছেদচিহ্ন হয়, ঘড়ির কাঁটার বিপরীতে দৌড়োনো এবং পি । কেন্দ্রবিন্দুর সাহায্যে নির্দেশিত হয়) মিটমাট করার জন্য, আমরা সামান্য অ্যালগরিদম পরিবর্তন: আমরা একটি বিন্দু নির্বাচন কুই মধ্যে পি , আর দ্বিখণ্ডিত করা P এবং q এর মধ্য দিয়ে অতিক্রমকারী রেখাটির সাথে পি (অর্থাত্, আমরা পি প্রায় Q এর কাছাকাছি ভাগ করে নিইটু-বাম-এর।) এখন আমাদের কাছে একটি "বাম অংশ" এবং পি এর একটি "ডান অংশ" রয়েছে , প্রতিটি অর্ধেক প্লেনের মধ্যে রয়েছে, যাতে বাম থেকে বামে প্রতিটিটির সাথে একটি ক্রমের সম্পর্ক থাকে; আমরা বাম অংশের সর্বনিম্ন এবং ডান অংশের সর্বাধিক সন্ধান করি এবং উপরে বর্ণিত হিসাবে সেগুলি তুলনা করি। অবশ্য, আমরা শারীরিকভাবে দ্বিখণ্ডিত করা হবে না পি , আমরা কেবল প্রতিটি বিন্দুতে শ্রেণীভুক্ত করতে পারেন পি হিসাবে আমরা একটি একক পাস, সর্বনিম্ন এবং সর্বোচ্চ জন্য, দেখুন।

পাইথন 2, 194 বাইট

import sys
P=[eval(l.replace(*";,"))for l in sys.stdin]
x,y=P.pop(0)
C=lambda(a,b),(c,d):(a-x)*(d-y)-(b-y)*(c-x)>0
l=r=P[0]
for q in P:
 if C(P[0],q):l=q*C(l,q)or l
 elif C(q,r):r=q
print C(l,r)

আপনি আপনার সমাধানগুলি তৈরি করতে পারেন এমন কোনও সুযোগ (কমপক্ষে পাইথন এক, জে তা করতে পারলে আমার কোনও ধারণা নেই) এসটিডিএন থেকে ইনপুট নেবে? আমি দেখতে পেলাম যে কোনও স্তরের খেলার ক্ষেত্রের সাথে সমাধানগুলি তুলনা করা আরও সহজ। ধরে নিই যে ইনপুটটি ইতিমধ্যে জটিল সংখ্যা বা পয়েন্টগুলির একটি পূর্বরূপযুক্ত সেট একটি প্রসারিত আইএমও এর কিছুটা।
আলেকজান্দ্রি হাল

অ্যালেক্সানড্রেহ্যালাম সম্পূর্ণ প্রোগ্রাম যুক্ত হয়েছে।
Ell

আপনার সমাধানগুলি ভাষার প্রতি একটি উত্তরে বিভক্ত করা উচিত।
মেগো

4

অক্টাভা, 82 72 বাইট

d=dlmread(0,";");i=2:rows(d);~isna(glpk(i,[d(i,:)';~~i],[d(1,:)';1]))&&1

লিনিয়ার প্রোগ্রামটি ন্যূনতম {সি'এক্স: এক্স = বি, ই'x = 1, এক্স> = 0 a এর সমাধান রয়েছে কিনা তা পরীক্ষা করে নেওয়ার জন্য ধারণাটি পাওয়া যায়, যেখানে e সবকটির ভেক্টর, A এর কলামগুলির স্থানাঙ্ক হয় বিন্দু মেঘ, এবং খ হল পরীক্ষার বিন্দু, এবং সিটি নির্বিচারে। অন্য কথায়, আমরা এ এর ​​কলামগুলির উত্তল সংমিশ্রণ হিসাবে খ উপস্থাপন করার চেষ্টা করি

স্ক্রিপ্টটি চালাতে, ব্যবহার করুন octave -f script.m <input.dat


2

আর, 207 বাইট

d=read.csv(file("stdin"),F,";")
q=function(i,j,k)abs(det(as.matrix(cbind(d[c(i,j,k),],1))))
t=function(i,j,k)q(i,j,k)==q(1,i,j)+q(1,i,k)+q(1,j,k)
any(apply(combn(2:nrow(d),3),2,function(v)t(v[1],v[2],v[3])))

স্ক্রিপ্টটি এর ইনপুটগুলি STDIN থেকে নেয়, যেমন Rscript script.R < inputFile

এটি Nসর্বশেষ পয়েন্টগুলি (শেষ লাইন, apply(combn(...) থেকে সমস্ত ত্রিভুজ তৈরি করে এবং tফাংশনটি ব্যবহার করে প্রথম পয়েন্টটি ত্রিভুজের মধ্যে রয়েছে কিনা তা পরীক্ষা করে ।

tযদি সিদ্ধান্ত নিতে এলাকা পদ্ধতি ব্যবহার Uহয় ABC(লিখছি: (ABC)এর এলাকার জন্য ABC) Uহয় ABCiff (ABC) == (ABU) + (ACU) + (BCU)। এছাড়াও, অঞ্চলগুলি নির্ধারক সূত্র ব্যবহার করে গণনা করা হয় ( ওল্ফ্রামের একটি দুর্দান্ত ডেমো জন্য এখানে দেখুন )।

আমি সন্দেহ করি যে এই সমাধানটি আমার অন্যান্য সমস্যার তুলনায় সংখ্যাসূচক ত্রুটিগুলির ঝুঁকিতে বেশি, তবে এটি আমার পরীক্ষার ক্ষেত্রে কাজ করে।


0

আর, 282 বাইট

d=read.csv(file("stdin"),F,";")
p=function(a,b)a[1]*b[1]+a[2]*b[2]
t=function(a,b,c){A=d[a,];
U=d[1,]-A
B=d[b,]-A
C=d[c,]-A
f=p(C,C)
g=p(B,C)
h=p(U,C)
i=p(B,B)
j=p(U,B)
k=f*i-g*g
u=i*h-g*j
v=f*j-g*h
min(u*k,v*k,k-u-v)>0}
any(apply(combn(2:nrow(d),3),2,function(v)t(v[1],v[2],v[3])))

স্ক্রিপ্টটি এর ইনপুটগুলি STDIN থেকে নেয়, যেমন Rscript script.R < inputFile

এটি Nসর্বশেষ পয়েন্টগুলি (শেষ লাইন, apply(combn(...) থেকে সমস্ত ত্রিভুজ তৈরি করে এবং tফাংশনটি ব্যবহার করে প্রথম পয়েন্টটি ত্রিভুজের মধ্যে রয়েছে কিনা তা পরীক্ষা করে ।

tযদি সিদ্ধান্ত নিতে barycentric পদ্ধতি ব্যবহার Uহয় ABC: (লেখার XYজন্য Xকরতে Yভেক্টর) যেহেতু (AB,AC)সমতল ভিত্তি (অধ: পতিত ক্ষেত্রে যেখানে এ, বি, সি সংযুক্ত করা হয় ছাড়া) হয়, AUহিসেবে লেখা যেতে পারে AU = u.AB + v.ACএবং Uত্রিভুজ iff হয় u > 0 && v > 0 && u+v < 1। আরও বিস্তারিত ব্যাখ্যা এবং একটি সুন্দর ইন্টারেক্টিভ চার্টের জন্য এখানে উদাহরণস্বরূপ দেখুন । বিশেষ দ্রষ্টব্য: কয়েকটি অক্ষর এবং এড়ানোর DIV0 ত্রুটি সংরক্ষণ করতে, আমরা কেবল একটি শর্টকাট গনা uএবং vএবং একটি পরিবর্তিত পরীক্ষা ( min(u*k,v*k,k-u-v)>0)।

শুধুমাত্র গাণিতিক ব্যবহৃত অপারেটার হয় +, -, *, min()>0

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.