2
\$\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\$
  • 18
    \$\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 '17 at 17:27
  • 3
  • \$\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\$ – Rɪᴋᴇʀ Mar 4 '17 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 '17 at 19:13
  • 1
    \$\begingroup\$ I made the count input optional. \$\endgroup\$ – xnor Mar 4 '17 at 22:20

31 Answers 31

6
\$\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\$
5
\$\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\$
4
\$\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\$
  • 11
    \$\begingroup\$ You called ???? \$\endgroup\$ – Adám Mar 5 '17 at 23:18
  • 3
    \$\begingroup\$ And ADMM once again solves an minimization problem. \$\endgroup\$ – NoSeatbelts Mar 6 '17 at 4:35
3
\$\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\$
  • 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 '17 at 7:42
3
\$\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\$
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\$
  • \$\begingroup\$ I think OiSPYk works for 6 bytes \$\endgroup\$ – Luis Mendo Mar 5 '17 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 '17 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 '17 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 '17 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\$
  • \$\begingroup\$ That might be the most beautiful C++ one-liner I've ever seen \$\endgroup\$ – osuka_ Apr 12 '18 at 16:34
2
\$\begingroup\$

Japt -g, 3 bytes

ña¼

Try it online!

Japt, 5 bytes

ña¼ v

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Shouldn't the flag be added to the byte count? Especially since the answer doesn't work correctly without it? \$\endgroup\$ – Nit Apr 12 '18 at 22:36
  • 1
    \$\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 '18 at 23:30
  • \$\begingroup\$ You don't need the 1. \$\endgroup\$ – Shaggy Apr 13 '18 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\$ – ETHproductions Apr 13 '18 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 '18 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\$

Ruby, 20 bytes

->n{n.min{|x|x.abs}}

Pretty straightforward solution. :)

\$\endgroup\$
  • \$\begingroup\$ You can even remove two bytes : ->n{n.min{|x|x*x}} \$\endgroup\$ – Faibbus Oct 28 '18 at 21:30
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\$

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\$
  • 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\$ – Olivier Grégoire Apr 12 '18 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\$ – Kevin Cruijssen Apr 12 '18 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\$
  • \$\begingroup\$ Why -a is there? \$\endgroup\$ – Qwertiy Oct 17 at 16:11
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\$
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\$
  • \$\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 '17 at 9:21
0
\$\begingroup\$

Perl 6, 15 bytes

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

Try it online!

\$\endgroup\$
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\$
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\$
  • \$\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 '18 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 '18 at 19:48
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\$
  • \$\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\$ – caird coinheringaahing Apr 13 '18 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 '18 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\$
0
\$\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\$
0
\$\begingroup\$

SmileBASIC, 56 bytes

DEF Z N,T
RSORT T
DIM V[N]ARYOP 2,V,T,T
SORT V,T?T[0]END

First, the input list is sorted, so the positive temperature will be chosen if there's a tie. Then each temperature is squared and stored in another array. The original array is sorted by this array, and the first item is printed.

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

Octave, 19 bytes

@(x)min(complex(x))

Try it online!

This exploits the fact that min with complex input compares by absolute value, then by angle:

For complex arguments, the magnitude of the elements are used for comparison. If the magnitudes are identical, then the results are ordered by phase angle in the range (-pi, pi].

\$\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.