4
\$\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
    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
    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
    Mar 4, 2017 at 19:13
  • 1
    \$\begingroup\$ I made the count input optional. \$\endgroup\$
    – xnor
    Mar 4, 2017 at 22:20

36 Answers 36

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\$ 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\$ 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
    Mar 5, 2017 at 23:18
  • 3
    \$\begingroup\$ And ADMM once again solves an minimization problem. \$\endgroup\$ 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
    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
    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
    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
    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
    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_
    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\$ 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
    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
    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
    Apr 12, 2018 at 23:30
  • \$\begingroup\$ You don't need the 1. \$\endgroup\$
    – Shaggy
    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\$ 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
    Apr 13, 2018 at 14:41
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\$ 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\$ 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
    Oct 17, 2019 at 16:11
  • \$\begingroup\$ Why fail [-273, 43] \$\endgroup\$
    – l4m2
    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\$

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\$
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
    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
    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_
    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\$ Jan 31, 2021 at 15:43
0
\$\begingroup\$

Avail, 88 bytes

Method"f_«_»"is[c:[1..∞),t:integer*|quicksort a,b in t[1..c] by[|a-0.1|<|b-0.1|][1]]

Approximate deobfuscation:

Method "nearest to zero among first _ of «_»" is
[
    count : natural number,
    temps : integer*
|
    (quicksort a, b in temps[1..count] by [|a-0.1| < |b-0.1|])[1]
]

The pattern syntax in the method's name, f_«_», will read the initial count as a natural number (whose type is abbreviated above as the range type [1..∞)) separate from the collected tuple of subsequent integers.

All that remains for the body is to sort by a custom comparator. Here we escape the need for a second-level comparison between x and -x by shifting the values slightly towards -∞.

\$\endgroup\$
2
  • \$\begingroup\$ Welcome to the site! Could you perhaps edit in a link to a site where others can test your submission, such as an online IDE? \$\endgroup\$ Apr 13, 2018 at 7:55
  • \$\begingroup\$ I'm not sure an online sandbox is feasible quite yet (as I understand it, the expressiveness of the language requires different approaches to parsing and compilation), but point taken! Are there any site requirements for online reproducibility? I'm partaking as part of my learning, and to share what I've learned, not to "win" by any means. \$\endgroup\$
    – tdhsmith
    Apr 23, 2018 at 20:56
0
\$\begingroup\$

dc, 53 bytes

Fd^sr[d*v]sA[ddlr+0=Asr]sR[dlAxlrlAx!<Rs_z0<M]dsMxlrp

Try it online!

We're going to use the register r to hold our final result, so the first thing we need to do is put a too-big number in there so that our first comparison always succeeds. I think the largest number we can push in two bytes is 165 (which is less than the required 5526), but Fd^ gives us 15^15 which is plenty large. Macro A, [d*v]sA just does the square root of the square to give us absolute value.

Macro R handles putting a value into register r; we'll come back to it in a second. Macro M, [dlAxlrlAx!<Rs_z0<M]dsMx is our main macro. Duplicates the value on the stack, runs A to get ABS, then pushes the value in r and does the same. !<R checks to see if ABS(r) is greater than or equal to not less than ABS(top of stack), and if so it runs R. Since we had to leave behind a copy of the original top of stack for R to potentially use, we store to a useless register (s_) to pop it. z0<M just loops M until the stack is empty.

Macro R, [ddlr+0=Asr]sR duplicates the top of stack twice (we need to leave something behind for M to gobble up when we return). At this point we know that of the two absolute values, our new value is less than or equal to our old value. If they're equal, and one is positive and the other is negative, we always need the positive. Fortunately, knowing this we can easily check for the case of one being the inverse of the other by simply adding them and comparing to 0. If so, we run A, and no matter what else happened we know we're storing whatever is left in r.

After M has gone through the whole stack, we load r and print it.

\$\endgroup\$

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.