16
\$\begingroup\$

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!

\$\endgroup\$
  • 6
    \$\begingroup\$ it gives priority to lower numbers That should be mentioned in the rules. \$\endgroup\$ – Dennis Feb 14 '16 at 17:05
  • \$\begingroup\$ If the target number is present in the list, should the output be that number or the closest other number from the list? \$\endgroup\$ – trichoplax Feb 14 '16 at 17:08
  • \$\begingroup\$ I know, the accepted answer is temporal. \$\endgroup\$ – AlexINF Feb 14 '16 at 17:16
  • 4
    \$\begingroup\$ @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. \$\endgroup\$ – Martin Ender Feb 14 '16 at 17:23
  • 1
    \$\begingroup\$ Are the input numbers integers? \$\endgroup\$ – randomra Feb 14 '16 at 18:14

13 Answers 13

6
\$\begingroup\$

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.
| improve this answer | |
\$\endgroup\$
6
\$\begingroup\$

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
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ I think you don't need #sort, since min_by will already sort it from min to max. So, it can be even shorter: ->n,a{a.min_by{|x|(n-x).abs}} \$\endgroup\$ – TiSer Feb 2 '18 at 18:20
4
\$\begingroup\$

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."

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

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!

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

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>

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ 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] \$\endgroup\$ – Neil Feb 14 '16 at 18:55
  • \$\begingroup\$ You can save a byte by currying your function: i=>a=>... then f(i)(a) is how you call it. \$\endgroup\$ – Patrick Roberts Feb 15 '16 at 22:00
  • \$\begingroup\$ @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 \$\endgroup\$ – andlrc Feb 15 '16 at 22:03
2
\$\begingroup\$

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.
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

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
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

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

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

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
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

R, 42 bytes

x=sort(scan());x[which.min(abs(x-scan()))]
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

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.

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

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!

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

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
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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