views:

408

answers:

6

Say I got a set of 10 random numbers between 0 and 100.

An operator gives me also a random number between 0 and 100. Then I got to find the number in the set that is the closest from the number the operator gave me.

example

set = {1,10,34,39,69,89,94,96,98,100}

operator number = 45

return = 39

And how do translate this into code? (javascript or something)

+1  A: 

How about this:

1) Put the set into a binary tree.
2) Insert the operator number into the tree
3) Return the Operators parent

yankee2905
+1  A: 
  • given an array called input, create another array of the same size
  • each element of this new array is the Math.abs(input[i] - operatorNumber)
  • select the index of the mininum element (let's call it k)
  • your answer is input[k]

NB

  • sorting is not needed
  • you can do it without the extra array

Sample implementation in JavaScript

function closestTo(number, set) {
    var closest = -1;
    var prev = Math.abs(set[0] - number);

    for (var i = 1; i < set.length; i++) {
        var diff = Math.abs(set[i] - number);

        if (diff < prev) {
            prev = diff;
            closest = set[i];
        }
    }

    return closest;
}
dfa
+1  A: 
  1. order the set
  2. binary search for the input
  3. if you end up between two elements, check the difference, and return the one with the smallest difference.
GSto
Sorting the set takes O(n log n). I think there's a O(n) solution
jpbochi
+5  A: 

if set is ordered, do a binary search to find the value, (or the 2 values) that are closest. Then distinguish which of 2 is closest by ... subtracting?

If set is not ordered, just iterate through the set, (Sorting it would itself take more than one pass), and for each member, check to see if the difference is smaller than the smallest difference you have seen so far, and if it is, record it as the new smallest difference, and that number as the new candidate answer. .

  public int FindClosest(int targetVal, int[] set)
  {
      int dif = 100, cand = 0;
      foreach(int x in set)
          if (Math.Abs(x-targetVal) < dif)
          {
              dif = Math.Abs(x-targetVal);
              cand = x;
          }
      return cand;
  }
Charles Bretana
If such search is performed often, it can pay off to sort the array, if it is not.
SebastianK
If set is unordered, won;t sorting the array take longer than making one pass through unordered list ?
Charles Bretana
@Charles Bretana: The key is that SebastianK said "if such search is performed often." Let's say that we have `n` numbers among which we are trying to find the closest and we are going to do this `m` times. If we don't sort, then the time complexity is `O(mn)`. If we do sort, then the complexity is `O(n log n + m log n)` because sorting is `O(n log n)` and binary searching is `O(log n)`. If `m >> n` then the time complexity is `O(m log n)` which is better than `O(mn)`.
Jason
@Jason, Assuming sorted array is persisted for next search, you are right, SebastianK is correct.
Charles Bretana
A: 

python example:

#!/usr/bin/env python
import random
from operator import itemgetter

sample = random.sample(range(100), 10)
pivot = random.randint(0, 100)

print 'sample: ', sample
print 'pivot:', pivot
print 'closest:', sample[
    sorted(
        map(lambda i, e: (i, abs(e - pivot)), range(10), sample), 
        key=itemgetter(1)
    )[1][0]]

# sample:  [61, 2, 3, 85, 15, 18, 19, 8, 66, 4]
# pivot: 51
# closest: 66
The MYYN
+1  A: 

Hi

Someone tagged this question Mathematica, so here's a Mathematica answer:

set = {1,10,34,39,69,89,94,96,98,100};

opno = 45;

set[[Flatten[ Position[set - opno, i_ /; Abs[i] == Min[Abs[set - opno]]]]]]

It works when there are multiple elements of set equally distant from the operator number.

Regards

Mark

High Performance Mark
Nice solution! (I removed the mathematica tag in the meantime, presuming that it was not intended. The original author can put it back if I presumed wrong.)
dreeves