Compute the Hausdorff Distance Introduction

The Hausdorff distance measures the difference between two subsets of a metric space.
Intuitively, a metric space is just some set with a built-in distance function; in this challenge, we will use natural numbers with the ordinary distance d(a, b) := abs(a - b).
The Hausdorff distance between two non-empty finite sets A and B is given by

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))


in Python-like notation.
The Hausdorff distance can be computed by finding the element of A for which the distance to the nearest element of B is maximal, and the element of B for which the distance to the nearest element of A is maximal, and then taking the maximum of these distances.
In other words, if the Hausdorff distance is d, then every element of A is within distance d of some element of B, and vice versa.

Input

Your input is a single list of integers.
It only contains the elements 0,1,2,3, which signify whether the given index of the list is an element of neither A nor B, only A, only B, or both A and B.
For example, the input [0,1,1,0,2,3] means that A = {1,2,5} and B = {4,5}, if we use 0-based indexing (which makes no difference, as our metrics are translation invariant).

Output

Your output is the Hausdorff distance between A and B; in the above example, it is 3.
If either set is empty, then the distance is not defined, and you shall return -1.

Rules

You can write a full program or a function.
The lowest byte count wins, and standard loopholes are disallowed.

Test Cases

[] -&gt; -1
[0] -&gt; -1
[0,1,0] -&gt; -1
[2,0,0,2] -&gt; -1
[0,1,2,3] -&gt; 1
[0,3,3,0,0,0,0,3] -&gt; 0
[1,0,0,1,0,0,1,3,1] -&gt; 7
[1,0,0,0,0,3,0,0,0,0,2] -&gt; 5
[0,1,1,3,1,3,2,1,1,3,0,3] -&gt; 2
[2,2,2,1,2,0,3,1,3,1,0,3] -&gt; 3
[1,3,0,2,0,2,2,1,0,3,2,1,1,2,2] -&gt; 2
[1,0,1,1,2,0,1,2,3,1,0,0,0,1,2,0] -&gt; 4
CJam, 53 52 46 38 37 bytes

3,q~f{f&amp;:L,{L=},}$~ff{-z}_z+::e&lt;W+:e&gt;


Takes input on STDIN as a CJam style array:

[0 1 2 3]


Here is a test harness which converts all the test cases to this format and runs the code on them. Although the results are in the input field, they are not used by the code (remove them if you don't trust me :)).

Explanation

First, we parse the input to get the two sets A and B:

3,q~f{f&amp;: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&amp;: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.";


And now we find the absolute differences and select the max of the mins:

ff{-z}_z+::e&lt;W+:e&gt;
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&lt;      "Find the minimum of each row.";
             W+    "Add a -1 in case one set was empty.";
               :e&gt; "Get the overall maximum.";


Note that we've kept the empty array resulting from the initial 0 at the bottom of the stack all the time, but empty arrays don't contribute anything to the output.