5
\$\begingroup\$

In this exercise, you have to analyze records of temperature to find the closest to zero.

Write a program that prints the temperature closest to 0 among input data.

Input

  • N, the number of temperatures to analyse (optional). This will be nonzero.
  • The N temperatures expressed as integers ranging from -273 to 5526.

Output

Output the temperature closest to 0. If two temperatures are equally close, take the positive one. For instance, if the temperatures are -5 and 5, output 5.

Example

Input

    5
    1 -2 -8 4 5

Output

    1

This challenge is similar to this one on CodinGame, you can view the problem statement source here. Some modifications have been made to the text.

\$\endgroup\$
7
  • 22
    \$\begingroup\$ Mirror of CodinGame problem statement. The site might not appreciate having solutions be made publicly available. I'm not sure what our current consensus is on problems taken from elsewhere. The problem isn't copy-pasted but some of your text is taken verbatim. \$\endgroup\$
    – xnor
    Commented Mar 4, 2017 at 17:27
  • 4
  • \$\begingroup\$ I've edited in most of the original problem statement, it's probably best to include as much of the original text as possible. Also, if you could link directly to the problem (the interactive part), that would be great. \$\endgroup\$
    – Riker
    Commented Mar 4, 2017 at 19:11
  • \$\begingroup\$ @Riker that edit has changed the problem being asked. The input formats are stricter and there is a special case for no input \$\endgroup\$
    – Blue
    Commented Mar 4, 2017 at 19:13
  • 1
    \$\begingroup\$ I made the count input optional. \$\endgroup\$
    – xnor
    Commented Mar 4, 2017 at 22:20

39 Answers 39

10
\$\begingroup\$

Python, 35 bytes

lambda l:max((-x*x,x)for x in l)[1]

Try it online!

Narrowly beats:

lambda l:min(l,key=lambda x:2*x*x-x)
lambda l:min(sorted(l)[::-1],key=abs)
\$\endgroup\$
2
  • \$\begingroup\$ why would you need to sort l in the second narrowly beaten one? \$\endgroup\$ Commented Aug 29, 2023 at 16:22
  • 1
    \$\begingroup\$ sorting it into descending order ensures the positive values come first and that min favours a positive smallest absolute value over a negative one (e.g. to prevent cases like min([-1, 1],key=abs)) \$\endgroup\$ Commented Aug 29, 2023 at 17:52
9
\$\begingroup\$

JavaScript (ES6), 33 bytes

a=>a.reduce((m,n)=>n*n-n<m*m?n:m)

Demo

let f =

a=>a.reduce((m,n)=>n*n-n<m*m?n:m)

console.log(f([1, -2, -8, 4, 5]))

\$\endgroup\$
5
\$\begingroup\$

Jelly, 4 bytes

AÐṂṀ

Try it online!

How it works

AÐṂṀ  Main link. Argument: A (array)

AÐṂ   Take all elements with minimal absolute value.
   Ṁ  Take the maximum. Yields 0 for an empty list.
\$\endgroup\$
2
  • 14
    \$\begingroup\$ You called ???? \$\endgroup\$
    – Adám
    Commented Mar 5, 2017 at 23:18
  • 3
    \$\begingroup\$ And ADMM once again solves an minimization problem. \$\endgroup\$ Commented Mar 6, 2017 at 4:35
4
\$\begingroup\$

Brachylog (2), 5 or 2 bytes

~{≜∈}

Try it online!

It wouldn't surprise me if there were a shorter solution along the lines of the Jelly or Pyke, but I like this one because it's so weird.

This is simply Brachylog's "find a list containing the input" operator , with an evaluation strategy that simply tries explicit values for integers until it finds one that works (and it happens to try in the order 0, 1, -1, 2, -2, 3, etc., which is surprisingly handy for this problem!), and inverted ~ (so that instead of trying to find an output list containing the input, it's trying to find an output contained in the input list). Unfortunately, inverting an evaluation strategy along with the value itself costs 2 bytes, so this doesn't beat the Jelly or Pyke solutions.

There's also a dubious 2-byte solution ≜∈. All Brachylog predicates take exactly two arguments, which can each be inputs or outputs; by convention, the first is used as an input and the second is used as an output, but nothing actually enforces this, as the caller has complete control over the argument pattern used (and in Prolog, which Brachylog compiles to, there's no real convention about argument order). If a solution which takes input through its second argument and produces output through its first argument is acceptable, there's no requirement to do the inversion.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ I had written a meta posted about using Input as Output and vice-versa. My view is that it's kinda cheaty because ? and . are not exactly symetrical in the code (notably, one is available on the left and one on the right). Though in a Prolog sense there is really nothing wrong with it. \$\endgroup\$
    – Fatalize
    Commented Mar 7, 2017 at 7:42
4
\$\begingroup\$

R, 31 bytes

(l=scan())[order(abs(l),-l)][1]

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Pyke, 4 bytes

S_0^

Try it online!

S_   - reversed(sorted(input))
  0^ - closest_to(^, 0)
\$\endgroup\$
0
2
\$\begingroup\$

Mathematica, 21 19 bytes

Max@*MinimalBy[Abs]

Composition of functions. Takes a list of integers as input and returns an integer as output.

\$\endgroup\$
2
\$\begingroup\$

MATL, 9 6 bytes

0iSPYk

Try it online!

Thanks to Luis Mendo for pointing out there's actually a built-in for this in MATL, which is not present in MATLAB.

 i     % Take input
  S    % Sort
   P   % Reverse to have largest value first.
0   Yk % Closest value to zero, prioritizing the first match found

If you wish to follow the spec and also provide the number of temperatures to be read, this should be given as the second input, and will be silently discarded.

\$\endgroup\$
4
  • \$\begingroup\$ I think OiSPYk works for 6 bytes \$\endgroup\$
    – Luis Mendo
    Commented Mar 5, 2017 at 4:24
  • \$\begingroup\$ @LuisMendo Yes of course - no idea there was a built-in for that. I should really check the function table more often, perhaps highlight the things that ordinary MATLAB doesn't have. \$\endgroup\$
    – Sanchises
    Commented Mar 5, 2017 at 6:51
  • \$\begingroup\$ Most MATL functions actually are taken from Matlab. There are only a few that don't correspond to Matlab functions \$\endgroup\$
    – Luis Mendo
    Commented Mar 5, 2017 at 12:09
  • \$\begingroup\$ @LuisMendo I know - I usually write my MATL programs in MATLAB first because I find it more readable. But this is the second time I could have saved a lot with a built-in MATL-only function, so I should be careful not to write my programs too MATLAB-centric. Thanks for the tip, nonetheless. \$\endgroup\$
    – Sanchises
    Commented Mar 5, 2017 at 17:35
2
\$\begingroup\$

C++14, 64 bytes

As unnamed lambda, expecting first argument to be like vector<int> and returing via reference parameter.

[](auto L,int&r){r=L[0];for(int x:L)r=x*x<=r*r?r+x?x:x>r?x:r:r;}

Ungolfed and usage:

#include<iostream>
#include<vector>

auto f=
[](auto L,int&r){ 
  r=L[0];
  for(int x:L)
    r = x*x<=r*r ?   //x is absolute less or equal
      r+x ?          //r==-x?
        x :          //no, just take x
        x>r ?        //take the positive one
          x :
          r      :
      r              //x was absolute greater, so keep r
    ;
}
;

int main(){
 std::vector<int> v = {5, 2, -2, -8, 4, -1, 1};
 int r;
 f(v,r);
 std::cout << r << std::endl;
}
\$\endgroup\$
2
  • \$\begingroup\$ That might be the most beautiful C++ one-liner I've ever seen \$\endgroup\$
    – osuka_
    Commented Apr 12, 2018 at 16:34
  • \$\begingroup\$ Using the abs built-in function for ints, you can replace the for loop content with r=x*x<r*r|x==abs(r)?x:r; which is 5 characters shorter \$\endgroup\$ Commented Nov 30, 2023 at 14:29
2
\$\begingroup\$

Perl 5 -p, 21 bytes

Added +1 for -p since this challenge precedes "options don't count"

$G[abs]=$_}{$_+="@G"

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ This solution violates the condition "If two temperatures are equally close, take the positive one", it takes simply the last one instead. \$\endgroup\$
    – Erlik
    Commented Nov 16, 2020 at 23:36
2
\$\begingroup\$

Japt -g, 3 bytes

ña¼

Try it online!

Japt, 5 bytes

ña¼ v

Try it online!

\$\endgroup\$
6
  • \$\begingroup\$ Shouldn't the flag be added to the byte count? Especially since the answer doesn't work correctly without it? \$\endgroup\$
    – Etheryte
    Commented Apr 12, 2018 at 22:36
  • 2
    \$\begingroup\$ @Nit The recent consensus on Meta is that each invocation of a flag is considered a separate language. Thus, it is not counted towards the byte count. My submission is technically considered a Japt -g answer, not Japt. \$\endgroup\$
    – Oliver
    Commented Apr 12, 2018 at 23:30
  • \$\begingroup\$ You don't need the 1. \$\endgroup\$
    – Shaggy
    Commented Apr 13, 2018 at 14:25
  • \$\begingroup\$ @Shaggy Actually I don't think it's correct with or without the 1: with, it fails on [1, 0] (giving 1), without, it fails on [-1, 1] (giving -1). I believe ña¼ may be the most correct way to do it. \$\endgroup\$ Commented Apr 13, 2018 at 14:31
  • \$\begingroup\$ @ETHproductions, I'd missed the part about outputting a postive integer in the case of a tie. \$\endgroup\$
    – Shaggy
    Commented Apr 13, 2018 at 14:41
2
\$\begingroup\$

Ruby, 58 bytes#

    p ((gets;gets.split.map(&:to_i)).min_by{|x|[x.abs,-x]}||0)
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Welcome to Code Golf, and nice first answer! Be sure to check out our Tips for golfing in Ruby page for ways you can golf your program. You might want to add an ATO link so others can test your code themselves. Also, you can remove the first gets since taking the number is optional. \$\endgroup\$
    – emanresu A
    Commented May 19 at 10:42
1
\$\begingroup\$

05AB1E, 16 bytes

Îåà_Di¹{RDÄßs\kè

Explanation:

Î                 Push 0 and [implicit] input array
 å                For each element in the array, is it a 0?
  à               Find the greatest value (1 if there was a 0 in it, 0 otherwise)
   _              Negate boolean (0 -> 1, 1 -> 0)
    D             Duplicate
     i            If true, continue
      ¹           Push input
       R          Reversed
        D         Duplicated
         Ä        Absolute value
          ß       Greatest element
           s      Swap top two values in stack
            \     Delete topmost value in stack
             k    Index of greatest element in the array
              è   Value of the index in the input array

Try it online!

Not at short as I'd like, but at least it works.

\$\endgroup\$
1
\$\begingroup\$

Haskell, 29 bytes

snd.maximum.map(\x->(-x^2,x))

Usage example: snd.maximum.map(\x->(-x^2,x)) $ [1,-2,-8,4,5]-> 1.

Map each element x to a pair (-x^2,x). Find the maximum and pick the 2nd element from the pair.

\$\endgroup\$
1
\$\begingroup\$

PHP, 81 bytes

two solutions: the first one requires an upper bound; both require all temperatures nonzero.

for($r=9e9;$t=$argv[++$i];)abs($t)>abs($r)|abs($t)==abs($r)&&$t<$r?:$r=$t;echo$r;
for(;$t=$argv[++$i];)$r&&(abs($t)>abs($r)|abs($t)==abs($r)&&$t<$r)?:$r=$t;echo$r;

Run with -r, provide temperatures as command line arguments.

A lazy solution for 92 bytes:

$a=array_slice($argv,1);usort($a,function($a,$b){return abs($a)-abs($b)?:$b-$a;});echo$a[0];

defines a callback function for usort and uses it on a slice of $argv.

\$\endgroup\$
1
\$\begingroup\$

Perl 6, 15 bytes

*.min:{.²,-$_}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Java 8, 63 39 bytes

s->s.reduce(1<<15,(r,i)->r*r-r<i*i?r:i)

Port from @Arnauld's JavaScript answer. I couldn't find anything shorter..

-10 bytes converting Java 7 to 8,
and another -24 bytes thanks to @OlivierGrégoire.

Explanation:

Try it online.

s->                   // Method with IntStream parameter and int return-type
  s.reduce(1<<15,     //  Start `r` at 32768 (`32768^2` still fits inside a 32-bit integer)
     (r,i)->r*r-r<i*i?//  If `r^2 - r` is smaller than `i^2`:
       r              //   Leave `r` the same
      :               //  Else:
       i)             //   Replace the current `r` with `i`
                      //  Implicitly return the resulting `r`
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Given that there was a dupe of this question recently, time to undust this one with 39 bytes: s->s.reduce(1<<15,(a,b)->a*a-a<b*b?a:b) \$\endgroup\$ Commented Apr 12, 2018 at 13:04
  • \$\begingroup\$ @OlivierGrégoire Thanks. Was looking at this answer myself after it was closed as a dupe and noticed the reduce in Arnauld's JS answer, but you beat me to it (and I forgot about it again after come colleagues came asking questions ;) ). \$\endgroup\$ Commented Apr 12, 2018 at 13:18
1
\$\begingroup\$

JavaScript (Node.js), 30 bytes

a=>a.sort((a,b)=>a*a-a>b*b)[0]

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Why -a is there? \$\endgroup\$
    – Qwertiy
    Commented Oct 17, 2019 at 16:11
  • \$\begingroup\$ Why fail [-273, 43] \$\endgroup\$
    – l4m2
    Commented Feb 8, 2022 at 14:25
1
\$\begingroup\$

Octave, 28 bytes

@(x)max(x(min(a=abs(x))==a))

Try it online!

Finds the smallest absolute value (min(a=abs(x))), then maps it back to which elements have that smallest absolute value in case of a tie (x(...==a)). Finally takes the maximum value of the results (max(...)) to ensure that in the event of a tie we get one result which is the positive one.

\$\endgroup\$
1
\$\begingroup\$

PHP, 209 Bytes

Not really golfed, but wanted to try to use mostly array functions, avoiding loops

Try it Online!!

Code

function f($a){$a[]=0;sort($a);$k=array_search(0,$a);$o=array_slice($a,$k+1);$u=array_reverse(array_diff($a,$o));if($u[1]&&$o[0]){$r=(abs($u[1])<abs($o[0]))?$u[1]:$o[0];}else{$r=($u[1])?$u[1]:$o[0];}return$r;}

Explanation

function f($a){
$a[]=0;                                #As all nonzero values, 0 is pushed
sort($a);                              #Sorting the array
$k=array_search(0,$a);                 #Search where zero is
$o=array_slice($a,$k+1);               #Array with all values >0
$u=array_reverse(array_diff($a,$o));   #Array with all smaller than zero values
                                       #Array has ascending order so it gets reversed              
if($u[1]&&$o[0]){                      #if both are set we just compare the abs value
    $r=(abs($u[1])<abs($o[0]))?$u[1]:$o[0];
}else{
    $r=($u[1])?$u[1]:$o[0];            #al least one of them will allways be set
                                       #the first value is always returned
                                       #the 0 value on $u is not usetted that why $u[1]
}
return $r;
}
\$\endgroup\$
1
\$\begingroup\$

Julia 0.6, 29 bytes

x->sort(x,by=x->abs(x-.1))[1]

Sort by the absolute value of the temperature, but subtract .1 first to ensure positive temperatures always win.

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 25 bytes \$\endgroup\$
    – MarcMush
    Commented Feb 9, 2022 at 15:39
1
\$\begingroup\$

05AB1E, 5 bytes

{R0.x

Try it online.

Or alternatively:

ÄWQÏà

Try it online.

Explanation:

{      # Sort the (implicit) input-list lowest-to-highest
 R     # Reverse it to highest-to-lowest
  0.x  # Pop and push the item closest to 0
       # (after which the result is output implicitly)

Ä      # Get the absolute value of each in the (implicit) input-list
 W     # Push the minimum (without popping the list)
  Q    # Check which are equal to this minimum
   Ï   # Only keep the values in the (implicit) input-list at the truthy indices
    à  # Pop and push the maximum of the remaining values
       # (after which the result is output implicitly)
\$\endgroup\$
1
\$\begingroup\$

Thunno 2 h, 4 bytes

ṠrþA

Try it online!

Explanation

ṠrþA  # Implicit input
Ṡr    # Reverse-sort
  þA  # Sort by |x|
      # Take the first item
      # Implicit output
\$\endgroup\$
1
\$\begingroup\$

Vyxal G, 20 bitsv2, 2.5 bytes

⁽ȧP

Try it Online!

Finds the minimum in the list by absolute value

\$\endgroup\$
1
\$\begingroup\$

J-uby, 12 bytes

:min_by+:abs

Attempt This Online!

\$\endgroup\$
0
\$\begingroup\$

Python, 62 bytes

def f(n):
    r=min(map(abs,n))
    return r if r in n else -r

It feels like there is a much simpler/shorter solution.

\$\endgroup\$
1
  • \$\begingroup\$ Can be shortened to: def f(n):r=min(map(abs,n));return r if r in n else -r \$\endgroup\$
    – Mr. Xcoder
    Commented Apr 18, 2017 at 9:21
0
\$\begingroup\$

C (clang), 74 bytes

k,m;f(*i,n){for(k=*i;--n>0;k=(k*k>m*m||(k==-m&&k<m))?m:k)m=i[n];return k;}

Try it online!

\$\endgroup\$
1
0
\$\begingroup\$

Stax, 6 bytes

¢M║⌠§☺

Run and debug it at staxlang.xyz!

Unpacked (6 bytes) and explanation

{|a}eoH
{  }e      Get all elements of array producing the minimum value from a block.
 |a          Absolute value.
     o     Sort ascending.
      H    Take last. Implicit print.
\$\endgroup\$
0
\$\begingroup\$

Pyth, 4 bytes

.m.a

Try it online!

Explanation:
.m.a   #Code
.m.abQ #With implicit variables
.m   Q #Filter input list for values b with minimal value of the following:
  .ab  #Absolute value of b
\$\endgroup\$
0
\$\begingroup\$

Python 3, 31 bytes

a=lambda q:sorted(q,key=abs)[0]

Try it online!

Sorts items by absolute value and prints the first element.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ This appears to fail if the list has two values with the same abs, and the negative first (like [5,-2,2] which should return 2, but appears to return -2) \$\endgroup\$
    – brhfl
    Commented Apr 13, 2018 at 14:29
  • \$\begingroup\$ @brhfl I tested that and I got the positive number. I’ll try it again later today \$\endgroup\$
    – osuka_
    Commented Apr 14, 2018 at 19:48
  • \$\begingroup\$ Depends on the order in the original array. If -2 is befor 2 it will print -2 in the example of @mrhfl \$\endgroup\$ Commented Jan 31, 2021 at 15:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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