हॉसडॉर्फ दूरी की गणना करें


21

परिचय

हॉसडॉर्फ़ दूरी एक मीट्रिक स्पेस की दो उप-समूहों के बीच अंतर को मापता है। सहज रूप से, एक मीट्रिक स्पेस बिल्ट-इन डिस्टेंस फ़ंक्शन के साथ कुछ सेट है; इस चुनौती में, हम साधारण दूरी के साथ प्राकृतिक संख्याओं का उपयोग करेंगे d(a, b) := abs(a - b)। दो गैर-खाली परिमित सेटों के बीच हॉसडॉर्फ दूरी Aऔर Bद्वारा दी गई है

max(max(min(d(a, b) for b in B) for a in A),
    max(min(d(a, b) for a in A) for b in B))

पायथन की तरह संकेतन में। हॉसडॉर्फ दूरी की गणना उस तत्व के द्वारा की जा सकती है Aजिसके लिए निकटतम तत्व के लिए दूरी Bअधिकतम है, और जिस तत्व के Bलिए निकटतम तत्व की दूरी Aअधिकतम है, और फिर इन दूरी का अधिकतम ले। दूसरे शब्दों में, यदि हॉसडॉर्फ दूरी है d, तो प्रत्येक तत्व कुछ तत्व की Aदूरी dके भीतर है B, और इसके विपरीत।

इनपुट

आपका इनपुट पूर्णांकों की एकल सूची है। यह केवल तत्व शामिल हैं 0,1,2,3, जो दर्शाता है कि क्या इस सूची के दिए गए इंडेक्स का एक तत्व न है Aऔर न ही B, केवल A, केवल B, या दोनों Aऔर B। उदाहरण के लिए, इनपुट का [0,1,1,0,2,3]मतलब है कि A = {1,2,5}और B = {4,5}, अगर हम 0-आधारित इंडेक्सिंग का उपयोग करते हैं (जिससे कोई फर्क नहीं पड़ता है, क्योंकि हमारे मैट्रिक्स अनुवाद इनवॉइस हैं)।

उत्पादन

आपका आउटपुट हौसडॉर्फ दूरी Aऔर के बीच की दूरी है B; उपरोक्त उदाहरण में, यह है 3। यदि कोई सेट खाली है, तो दूरी निर्धारित नहीं है, और आप वापस आ जाएंगे -1

नियम

आप एक पूर्ण कार्यक्रम या एक फ़ंक्शन लिख सकते हैं। सबसे कम बाइट गिनती जीतता है, और मानक खामियों को रोक दिया जाता है।

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

[] -> -1
[0] -> -1
[0,1,0] -> -1
[2,0,0,2] -> -1
[0,1,2,3] -> 1
[0,3,3,0,0,0,0,3] -> 0
[1,0,0,1,0,0,1,3,1] -> 7
[1,0,0,0,0,3,0,0,0,0,2] -> 5
[0,1,1,3,1,3,2,1,1,3,0,3] -> 2
[2,2,2,1,2,0,3,1,3,1,0,3] -> 3
[1,3,0,2,0,2,2,1,0,3,2,1,1,2,2] -> 2
[1,0,1,1,2,0,1,2,3,1,0,0,0,1,2,0] -> 4

आपके समीकरण में, मेरा मानना ​​है कि यह बहुत लंबा है, जैसा max(max(min(d(a, b) for b in B) for a in A))कि पर्याप्त होना चाहिए। ऐसा इसलिए है क्योंकि d(a,b)पूर्ण मान लौटाता है, और इसलिए दोनों अधिकतम फ़ंक्शन हर बार एक ही संख्या वापस करेंगे।
नाथन मेरिल

6
@NathanMerrill यह हो सकता है कि प्रत्येक तत्व Aकिसी एक के बहुत करीब है B, लेकिन इसमें से Bबहुत दूर के तत्व हैं A(उदाहरण के लिए, यदि Aएक उपसमूह है B)। उस स्थिति में, लघु सूत्र गलत है।
ज़र्गब

जवाबों:


7

CJam, 53 52 46 38 37 बाइट्स

3,q~f{f&:L,{L=},}$~ff{-z}_z+::e<W+:e>

STDIN पर CJam शैली सरणी के रूप में इनपुट लेता है:

[0 1 2 3]

यहां एक परीक्षण हार्नेस है जो सभी परीक्षण मामलों को इस प्रारूप में परिवर्तित करता है और उन पर कोड चलाता है। हालांकि परिणाम इनपुट क्षेत्र में हैं, वे कोड द्वारा उपयोग नहीं किए जाते हैं (यदि आप मुझ पर भरोसा नहीं करते हैं तो उन्हें हटा दें :))।

व्याख्या

सबसे पहले, हम दो सेट A और B प्राप्त करने के लिए इनपुट को पार्स करते हैं:

3,q~f{f&:L,{L=},}$~
3,                  "Push [0 1 2]. 1 is for A, 2 is for B, and 0 we can luckily ignore
                     as we'll see later.";
  q~                "Read and evaluate the input.";
    f{          }   "Map this block onto the [0 1 2] array, copying in the input for
                     each iteration.";
      f&:L          "Take the bitwise AND with each element of the input and store the
                     result in L.";
          ,{  },    "Get the length N, and filter the range [0 .. N-1] by evaluating
                     the block for each element.";
            L=      "Check if the bitwise AND at that index yielded something non-zero.
                     This gives an empty array for 0, A for 1 and B for 2.";
                 $  "Sort the three arrays. This has two important effects: a) it moves
                     the empty array resulting from 0 to the front, and b) if only one
                     of A and B is empty, it moves the non-empty one to the end.";
                  ~ "Unwrap the array, dumping all three sets on the stack.";

और अब हम पूर्ण अंतर पाते हैं और अधिकतम टकसालों का चयन करते हैं:

ff{-z}_z+::e<W+:e>
ff{-z}             "Turn A and B into a matrix of absolute differences.";
      _z           "Duplicate and transpose.";
        +          "Add the two together, so I've got one row of distances for
                    each element in either A or B.";
         ::e<      "Find the minimum of each row.";
             W+    "Add a -1 in case one set was empty.";
               :e> "Get the overall maximum.";

ध्यान दें कि हमने खाली सरणी को 0हर समय स्टैक के निचले भाग के परिणामस्वरूप रखा है , लेकिन खाली सरणियाँ आउटपुट में कुछ भी योगदान नहीं देती हैं।


5

CJam, 57 56 52 बाइट्स

मुझे लगता है कि यह थोड़ा गोल्फ हो सकता है, लेकिन यहाँ जाता है:

q~ee_{W=2%},\{W=1>},]0ff=_W%]{~ff-{:z$1<~}%W+$W=}/e>

इनपुट CJam स्टाइल सूची की तरह है, जैसे।

[1 0 0 0 0 3 0 0 0 0 2]

5

यह कैसे काम करता है :

कोड दो भागों में विभाजित है:

सूचियों में इनपुट पार्स करना Aऔर B:

q~ee_{W=2%},\{W=1>},]0ff=_W%]
q~                               "Eval the input array";
  ee                             "Enumerate and prepend index with each element. For ex:
                                  [5 3 6]ee gives [[0 5] [1 3] [2 6]]";
    _{W=2%},                     "Make a copy and filter out elements with value 1 or 3";
            \{W=1>},             "On the original, filter elements with value 2 or 3";
                    ]            "Wrap stack in an array. Stack right now contains
                                  enumerated A and B in an array";
                     0ff=        "Get the index of the enumerated arrays. Stack is [A B]";
                         _W%     "Make a copy and swap order. Stack is now [A B] [B A]";
                            ]    "Wrap this in an array";

की दो जोड़ियों पर आवश्यक कार्यवाही करना Aऔर B:

{~ff-{:z$1<~}%W+$W=}/e>
{                  }/            "Run this loop for both the pairs, [A B] and [B A]"
 ~ff-                            "Unwrap [A B] and take difference of every pair";
     {      }%                   "For each row in the matrix difference";
      :z$                        "abs each term and then sort";
         1<~                     "Take only the first element of the array";
              W+                 "Add -1 to compensate for an empty array";
                $W=              "Take max";
                     e>          "Take max of the two maximums";

इसे यहाँ ऑनलाइन आज़माएँ


5

लुआ, 235 बाइट्स

निश्चित रूप से विजेता नहीं, लेकिन कम से कम एक मजेदार चुनौती।

A={}B={}c={}d={}m=math p=m.min q=m.max u=unpack for k=1,#arg do for h=0,1 do if
arg[k]/2^h%2>=1 then A[#A+1]=k for i=1,#B do l=m.abs(B[i]-k)d[i]=p(d[i]or
l,l)c[#A]=p(c[#A]or l,l)end end A,B=B,A c,d=d,c end end
print(q(q(-1,u(c)),u(d)))

इनपुट काम करता है:

lua hausdorff.lua <space-separated-sequence>

... और यहाँ एक परीक्षण स्क्रिप्ट है:

local testcase = arg[1] or 'hausdorff.lua'
print('testing '..testcase)
local function run(args) 
    return function(expected)
        local result = tonumber(
            io.popen('lua.exe '..testcase..' '..args):read'*a':match'%S+')
        print(args..' -> '..expected..' :: '..result)
        assert(result == expected,
            ("for input %q expected %s but got %s"):format(
                args, expected, result))
    end
end
run''(-1)
run'0'(-1)
run'0 1 0'(-1)
run'2 0 0 2'(-1)
run'0 1 2 3'(1)
run'0 3 3 0 0 0 0 3'(0)
run'1 0 0 1 0 0 1 3 1'(7)
run'1 0 0 0 0 3 0 0 0 0 2'(5)
run'0 1 1 3 1 3 2 1 1 3 0 3'(2)
run'2 2 2 1 2 0 3 1 3 1 0 3'(3)
run'1 3 0 2 0 2 2 1 0 3 2 1 1 2 2'(2)
run'1 0 1 1 2 0 1 2 3 1 0 0 0 1 2 0'(4)

... पैदा करता है ...

testing hausdorff.lua
 -> -1 :: -1
0 -> -1 :: -1
0 1 0 -> -1 :: -1
2 0 0 2 -> -1 :: -1
0 1 2 3 -> 1 :: 1
0 3 3 0 0 0 0 3 -> 0 :: 0
1 0 0 1 0 0 1 3 1 -> 7 :: 7
1 0 0 0 0 3 0 0 0 0 2 -> 5 :: 5
0 1 1 3 1 3 2 1 1 3 0 3 -> 2 :: 2
2 2 2 1 2 0 3 1 3 1 0 3 -> 3 :: 3
1 3 0 2 0 2 2 1 0 3 2 1 1 2 2 -> 2 :: 2
1 0 1 1 2 0 1 2 3 1 0 0 0 1 2 0 -> 4 :: 4

4

पायथ, 43 40 39 38 बाइट्स

J+m0yQQLq3.|Fb?eS.e&Yfy:J-kT+hkT0JyJ_1

मेरा एल्गोरिथ्म सीधे इनपुट स्ट्रिंग पर काम करता है और इन नंबरों को कभी नहीं बदलता है। यह केवल एक बार अधिकतम की गणना करता है और एक न्यूनतम कभी नहीं।

एक बाइट बचाने के लिए @isaacg को धन्यवाद।

इसे ऑनलाइन आज़माएं: पायथ कंपाइलर / एक्ज़ीक्यूटर

स्पष्टीकरण:

पहले मैं इनपुट के सामने बहुत सारे शून्य डालूँगा।

          implicit: Q = input()
    yQ    powerset(Q)
  m0yQ    map each element of the powerset to 0 (creates 2^Q zeros, I said lots)
 +    Q   zeros + Q
J         assign to J

फिर मैं एक सहायक फ़ंक्शन को परिभाषित करता हूं y, जो बताता है कि क्या सूची के इनपुट (जैसे इनपुट एक) दोनों सेट ए और बीईजी में दिखाई देते हैं y([0, 1, 0, 0, 1, 1]) = False, लेकिन y([0, 1, 0, 2]) = y([3]) = True

Lq3.|Fb
L          define a function y(b), which returns _
   .|Fb       fold b by bitwise or
 q3            == 3

बाद में मैं पहले जांच करता हूं कि परिणाम क्या है -1

?...yJ_1   print ... if numbers appear in both sets (`yJ`) else -1   

अब दिलचस्प सामग्री के लिए:

  .e              J    map each pair k,Y in enumerate(J) to:
    &Y                   Y and ... (acts as 0 if Y == 0 else ...)
      f          0       find the first number T >= 0, where:
       y                    indices appear in both sets in the substring
        :J-kT+hkT           J[k-T:k+T+1]
eS                     sort and take last element (maximum)

ध्यान दें, कि मुझे हमेशा एक नंबर मिलेगा T, क्योंकि मुझे पहले से ही पता है कि जे। सूची में दोनों सेट में सूचकांक दिखाई देते हैं। संख्या अधिकतम है length(Q)। यह भी शून्य डालने का कारण है। यदि कम से कम length(Q)शून्य डाला जाता है, k-Tतो हमेशा होता है >= 0, जो सूची के लिए आवश्यक है। तो मैं 2^length(Q)शून्य के बजाय शून्य क्यों सम्मिलित करता हूं length(Q)? परीक्षण-मामले में []मुझे कम से कम 1 शून्य की आवश्यकता है, अन्यथा yJएक त्रुटि वापस आ जाएगी।


><Cabके रूप में ही है :Cba
isaacg

यह अच्छी बात है कि परीक्षण के मामलों में एक बड़ा इनपुट शामिल नहीं है ...
टीएलडब्ल्यू

3

गणितज्ञ, 88 बाइट्स

Max[Min/@#,Min/@Thread@#,-1]/.∞->-1&@Outer[Abs[#-#2]&,p=Position;p[#,1|3],p[#,2|3],1]&

1
बहुत अच्छा जवाब। हौसडॉर्फ दूरी की अधिक सामान्य खोज के लिए, कोई भी उपयोग कर सकता है m=MaxValue;Max[m[RegionDistance[#[[1]],s],s\[Element]#[[2]]]/.m[__]->-1&/@{#,Reverse@c}]& जिसे तब बहुआयामी वस्तुओं पर लागू किया जा सकता है जैसे%@{Sphere[],Line[{{1,1,0},{3,3,3}}]}
केली लोवेर

3

हास्केल, 145 126 124 बाइट्स

s t x=[e|(e,i)<-zip[0..]x,t i]
d#e=maximum[minimum[abs$i-j|j<-e]|i<-d]
[]%_= -1
_%[]= -1
d%e=max(d#e)$e#d
f x=s(>1)x%s odd x

परीक्षण चालन:

*Main> map f [[], [0], [0,1,0], [2,0,0,2], [0,1,2,3],
              [0,3,3,0,0,0,0,3], [1,0,0,1,0,0,1,3,1],
              [1,0,0,0,0,3,0,0,0,0,2], [0,1,1,3,1,3,2,1,1,3,0,3],
              [2,2,2,1,2,0,3,1,3,1,0,3],
              [1,3,0,2,0,2,2,1,0,3,2,1,1,2,2],
              [1,0,1,1,2,0,1,2,3,1,0,0,0,1,2,0]]

[-1,-1,-1,-1,1,0,7,5,2,3,2,4]

sएक विधेय tऔर इनपुट सूची के अनुसार प्राकृतिक संख्याओं को फ़िल्टर करता है x#यह मापदंडों की अधिकतम दूरी की गणना करता है dऔर e%खाली सेट A या B पकड़ता है या अंतिम अधिकतम लेता है d#eऔर e#dfमुख्य कार्य है जो %सेट ए और बी के साथ कॉल करता है ।

संपादित करें: @Zgarb को बचाने के लिए बहुत सारे बाइट्स मिले; @ ali0sha एक और 2. धन्यवाद!


mod 2अनावश्यक लगता है। आप परिभाषित नहीं aऔर bस्पष्ट रूप से भी लाभ उठा सकते हैं ।
जर्गर्ब

आप के साथ 2 बाइट्स बचा सकते हैं []%_= -1- लेकिन आप इस पर मेरी कोशिश नीचे हाथ हराया :)
अलेक्जेंडर-ब्रेट

3

पर्ल, ५६ ५५

के लिए +2 जोड़ा गया -lp

इनपुट सूची स्टड पर रिक्त स्थान के बिना दी जानी चाहिए, जैसे:

echo 1011201231000120 | perl -lp hausdorf.pl

hausdorf.pl:

s%%$z=$_&=$p|=$'|P.$p;$q+=!!y/12/3/%eg;$_=$z=~3?$q:-1

इनपुट सूची के तत्वों के बीच रिक्त स्थान का समर्थन करने के $qलिए 2 स्ट्रोक की लागत के लिए फाइनल को 2 से विभाजित करें


2

अजगर 2, 124

यह निश्चित रूप से उप-रूपी लगता है। ओह अच्छा।

lambda a,E=enumerate:-min([1]+[~l*(n<3)for i,n in E(a)for l,_ in E(a)if{0}|set(n*a+n/3*[5])>{0,n}>=set(a[max(i-l,0):i-~l])])

1

एपीएल (49)

{(⊂⍬)∊∆←(↓2 2⊤⍵)/¨⊂⍳⍴⍵:¯1⋄⌈/{⌈/⌊/⍵}¨(+,⍉¨)|∘.-/∆}

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

      ({(⊂⍬)∊∆←(↓2 2⊤⍵)/¨⊂⍳⍴⍵:¯1⋄⌈/{⌈/⌊/⍵}¨(+,⍉¨)|∘.-/∆} ¨ testcases) ,⍨ '→',⍨ ↑ ⍕¨testcases
                               → ¯1
0                              → ¯1
0 1 0                          → ¯1
2 0 0 2                        → ¯1
0 1 2 3                        →  1
0 3 3 0 0 0 0 3                →  0
1 0 0 1 0 0 1 3 1              →  7
1 0 0 0 0 3 0 0 0 0 2          →  5
0 1 1 3 1 3 2 1 1 3 0 3        →  2
2 2 2 1 2 0 3 1 3 1 0 3        →  3
1 3 0 2 0 2 2 1 0 3 2 1 1 2 2  →  2
1 0 1 1 2 0 1 2 3 1 0 0 0 1 2 0→  4

स्पष्टीकरण:

  • ⍳⍴⍵: 1 की संख्या से इनपुट सूची की संख्या प्राप्त करें
  • ↓2 2⊤⍵: इनपुट सूची में प्रत्येक मान के लिए, पहली बाइट और दूसरी बाइट प्राप्त करें
  • ∆←(... )/⊂⍳⍴⍵: बाइट्स की दोनों सूचियों के लिए, से संबंधित मानों का चयन करें ⍳⍴⍵। इनको स्टोर करें
  • (⊂⍬)∊∆... :¯1: यदि इस सूची में रिक्त सूची है, तो वापस लौटें -1। अन्यथा:

  • |∘.-/∆: हर जोड़ी मूल्यों के बीच पूर्ण अंतर प्राप्त करें, मैट्रिक्स दे

  • (+,⍉¨): उस मैट्रिक्स की एक घुमाया और एक गैर-घुमाया गया प्रति प्राप्त करें
  • {⌈/⌊/⍵}: दोनों मैट्रिसेस के लिए, पंक्तियों के न्यूनतम हिस्से का अधिकतम लाभ लें
  • ⌈/: तो उस का अधिकतम लाभ उठाएं

@ ऑप्टिमाइज़र: मैं किसी तरह पहले वाले संस्करण से परीक्षण आउटपुट को कॉपी करने में कामयाब रहा जिसमें बग था। कोड ही सही था और अभी भी है। यदि आप मुझ पर विश्वास नहीं करते हैं, तो यहां प्रयास करें । (ध्यान दें कि आपको ,Xस्केलर से अलग करने के लिए एक तत्व सूची में प्रवेश करना होगा X।)
मरीनस

ओह समझा। आलसी मुझे एक ऑनलाइन कंपाइलर और टेस्ट में न जाने के लिए ..
ऑप्टिमाइज़र

1

पर्ल, 189 176 157B

अब 500% अधिक राज्य के साथ।

use List::Util qw'max min';@I=<>;sub f{$n=($n%2)+1;map{$I[$_]&$n?$_:()}0..$#I}sub i{@t=f;max map{$b=$_;min map{abs$_-$b}@t}f}$r=max i,i;print defined$r?$r:-1

सुपाठ्य:

use List::Util qw'max min';
@I=<>;
sub f {
    $n = ($n%2) + 1;
    map { $I[$_] & $n ? $_ : () } 0..$#I
}
sub i {
    @t = f;
    max map {
        $b = $_;
        min map { abs $_ - $b } @t
    } f
}
$r = max i,i;
print defined $r ? $r : -1

उदाहरण का उपयोग:

इनपुट

0
1
2
3

perl golf.pl < input


0

क्लोजर, 167 बाइट्स

#(let[P apply F(fn[I](filter(fn[i](I(% i)))(range(count %))))A(F #{1 3})B(F #{2 3})d(fn[X Y](P min(for[x X](P max(for[y Y](P -(sort[x y])))))))](-(min(d A B)(d B A))))

वहाँ एक छोटा रास्ता होना चाहिए ... वहाँ है?

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