Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

In this code golf, you need to get the closest number from another one in a list.

The output may be the closest number to the input.

Example:

value: (Input) 5 --- [1,2,3] --- 3

And, the program may work with negative numbers.

Example:

value: (Input) 0 --- [-1,3,5] --- -1


value: (Input) 2 --- [1, 5, 3] --- 1 (Because it gives priority to lower numbers)

RULES:

As mentioned before, it has to work with negative numbers.

If there are two answers (Example: 0 -- [5,-5]), the program gives priority to the lowest number. (-5)

This is code golf so the shortest code wins!

share|improve this question
6  
it gives priority to lower numbers That should be mentioned in the rules. – Dennis Feb 14 at 17:05
    
If the target number is present in the list, should the output be that number or the closest other number from the list? – trichoplax Feb 14 at 17:08
    
I know, the accepted answer is temporal. – Alex82 Feb 14 at 17:16
4  
@Alex82 Sure, you know that you'll change the accepted answer if a better one comes in, but some people are put off by challenges that already have an accepted answer, because unfortunately not every challenge author is that attentive to late answers. So it's less about whether accepting early is actually bad but whether people will get the wrong impression. – Martin Ender Feb 14 at 17:23
1  
Are the input numbers integers? – randomra Feb 14 at 18:14

13 Answers 13

up vote 5 down vote accepted

Pyth, 6 bytes

haDQSE

Test suite

Input in the following form on STDIN:

num
array

Explanation:

haDQSE
          Implicit: Q = eval(input()) (num)
     E    Evaluate input (array)
    S     Sort (smaller values to the front)
 aDQ      Sort by absolute difference with Q.
h         Take the first element of the sorted list, the min.
          Print implicitly.
share|improve this answer

Ruby, 34 bytes

->n,a{a.sort.min_by{|x|(n-x).abs}}
a.sort       min_by tiebreaks by position in array, so put smaller numbers 1st
.min_by{|x|  select the element which returns the smallest val for predicate...
(n-x).abs}   (absolute) difference between input num and element
share|improve this answer

Mathematica, 12 bytes

Min@*Nearest

Built-ins FTW! Buettner's explanation: "Mathematica has a built-in Nearest for this, but it returns a list of all tied numbers. Hence, we need to compose it with Min to break the tie."

share|improve this answer
7  
That's what I get for writing an explanation... – Martin Ender Feb 14 at 16:57
1  
Could you add a "Try it online"? – Alex82 Feb 14 at 17:04
1  
@Alex82 Seems unlikely for Mathematica (which is proprietary). – Martin Ender Feb 14 at 17:07
    
@Alex82 Test it here: lab.open.wolframcloud.com/app/view/newNotebook?ext=nb – thedude Feb 14 at 18:25

Pyth, 8 bytes

hS.mabQE

Explanation

         - autoassign Q = eval(input())
  .m   E -   min_values([V for b in eval(input())])
    abQ  -    abs(b-Q)
 S       -  sorted(^)
h        - ^[0]

Try it online!

share|improve this answer

JavaScript ES6, 64 56 54 bytes

(i,a)=>a.sort((a,b)=>s(i-a)-s(i-b)||a-b,s=Math.abs)[0]

Try it online

Thanks to @Niel for saving two bytes

Test Snippet:

f=(i,a)=>a.sort((a,b)=>s(i-a)-s(i-b)||a-b,s=Math.abs)[0];

[
  [5, [1, 2, 3]],
  [2, [3, 5, 1]],
  [2, [1, 3, 5]],
  [0, [-1, 2, 3]],
  [5, [1, 2, 3]]
].map(v=>O.textContent+=JSON.stringify(v)+": "+f.apply(null,v)+"\n")
<pre id=O></pre>

share|improve this answer
    
Save 2 bytes by combining the sorts: (i,a)=>a.sort((a,b)=>s(i-a)-s(i-b)||a-b,s=Math.abs)[0] – Neil Feb 14 at 18:55
    
@Neil True, thanks! – andlrc Feb 14 at 19:07
    
You can save a byte by currying your function: i=>a=>... then f(i)(a) is how you call it. – Patrick Roberts Feb 15 at 22:00
    
@PatrickRoberts In this case I would say no, because OP is asking for a function (or simulere) that takes to values: input and a list/array/... as integers – andlrc Feb 15 at 22:03

Jelly, 7 6 bytes

ạżṛỤḢị

Try it online!

How it works

ạżṛỤḢị Main link. Left input: n (number). Right input: A (list)

ạ      Take the asbolute difference of n and the items of A.
  ṛ    Yield the right argument, A.
 ż     Zip the left result with the right one.
       This pairing causes ties in absolute value to be broken by initial value.
   Ụ   Grade up; sort the indices of the resulting list by their associated values.
    Ḣ  Retrieve the first index, which corresponds to the smallest value.
     ị Retrieve the item of A at that index.
share|improve this answer

Python 2, 56 bytes

a=input()
print sorted(input(),key=lambda x:abs(a-x))[0]

Gets the target number first a=input() - this has to be stored in a variable.

It then sorts the input with the function lambda x:abs(a-x) applied (think map(lambda x:abs(a-x), input()))

It then takes the minimum value in case of any duplicate values

share|improve this answer

MATL, 10 bytes

Sti-|4#X<)

Try it online!

S       % implicitly input array, and sort. This ensures smaller numbers have priority
t       % duplicate
i       % input number
-|      % compute array of absolute differences
4#X<    % arg min. If there are several minimizers, the position of the first is returned
)       % index into original array. Implicitly display
share|improve this answer

TeaScript, 10 bytes

T#(y-l)a)░

TeaScript doesn't support array input so in the console run: TeaScript("T#y-la)░", [[1, 2, 3], 1], {}, TEASCRIPT_PROPS) to runthis.

Explanation

T#  // Sort input by...
  (y-l)a // absolute difference with input
)░  // First item in array
share|improve this answer

R, 42 bytes

x=sort(scan());x[which.min(abs(x-scan()))]
share|improve this answer

Haskell, 38 bytes

e#l=snd$minimum$(zip=<<map(abs.(e-)))l

Usage example: 2 # [1,5,3]-> 1.

For each element in the input list l make a pair of the absolute difference of the element with the input number e and the element itself, e.g. e=2, l=[1,5,3] -> [(1,1),(3,5),(1,3)]. Find the minimum and discard the difference.

share|improve this answer

zsh, 75 73 71 70 67 bytes

for n in ${@:2};{echo "$[$1-n]    $n"}|tr -d -|sort -n|head -1|cut -f2

Expects input as command line arguments.

Note that the four spaces in the echo is actually supposed to be a tab, but Stack Exchange converts tabs to spaces in all posts.

Not Bash-compatible because of the for syntax.

for n in ${@:2};      for each argument except the first...
{echo "$[$1-n]\t$n"}  output the difference from the first argument
                        and then the original number
|tr -d -              poor man's abs()
|sort -n              sort by first num (difference), tiebreaking by second num
                        (original value)
|head -1              take the thing that sorted first
|cut -f2              print field 2 (aka discard the difference)

Thanks to dev-null for 2 bytes!

share|improve this answer

Perl 6, 31 bytes

{@^b.sort.sort((*-$^a).abs)[0]}

Usage:

my &code = {@^b.sort.sort((*-$^a).abs)[0]}

say code 5, [1,2,3];   # 3
say code 0, [-1,3,5];  # -1
say code 2, [1, 5, 3]; # 1
say code 0, [5,-5];    # -5
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.