44
\$\begingroup\$

Given two integers, A and B, output A if A-B (A minus B) is in A-B (A to B), otherwise output B.

"A minus B" is standard subtraction.

"A to B" is the range of integers starting at A and ending at B, including both A and B. For example:

1 to 4: 1, 2, 3, 4
-2 to 5: -2, -1, 0, 1, 2, 3, 4, 5
3 to -1: 3, 2, 1, 0, -1
7 to 7: 7

The shortest code in bytes wins.

Test Cases

A B Output
1 4 4
-2 5 5
3 -1 -1
7 7 7
90 30 90
90 -30 -30
-90 30 30
-90 -30 -90
-2 -2 -2
-2 -1 -2
-2 0 -2
-2 1 1
-2 2 2
-1 -2 -2
-1 -1 -1
-1 0 -1
-1 1 1
-1 2 2
0 -2 -2
0 -1 -1
0 0 0
0 1 1
0 2 2
1 -2 -2
1 -1 -1
1 0 1
1 1 1
1 2 2
2 -2 -2
2 -1 -1
2 0 2
2 1 2
2 2 2

Original Chat-Mini-Challenge

\$\endgroup\$

37 Answers 37

44
\$\begingroup\$

Python, 27 bytes

lambda a,b:[a,b][2*b*b>a*b]

Try it online!

An arithmetic formula. Why is the negation of 2*b*b>a*b equivalent to the problem condition a-b in symrange(a,b)?

Note that x in symrange(a,b) is equivalent to 0 in symrange(a-x,b-x). Applying this to x=a-b gives 0 in symrange(b,2*b-a). The value 0 is included in the interval unless it stretches between two positive values or two negative values. This can be stated arithmetically as "their product b*(2*b-a) is not positive.

Finally, take b*(2*b-a)<=0, and rewrite to 2*b*b<=a*b. A byte is saved by flipping <= to > and switching the cases.

\$\endgroup\$
10
\$\begingroup\$

Jelly, 5 bytes

_erị,

Try it online!

How it works

_erị,  Main link. Arguments: a, b

_      Subtraction; Yield a-b.
  r    Range; yield [a, ..., b].
 e     Exists; yield 1 if a-b belongs to [a, ..., b], 0 if not.
    ,  Pair; yield [a, b].
   ị   At-index; yield the element of [a, b] at index 1 (a) or index 0 (b).
\$\endgroup\$
8
\$\begingroup\$

05AB1E, 7 bytes

Code:

DŸ¹Æå_è

Uses the CP-1252 encoding. Try it online!

Explanation:

D         # Duplicate the input.
 Ÿ        # Inclusive range.
  ¹Æ      # Push the input [a, b] and compute a - b.
    å     # Check if the number exists in the range.
     _    # Boolean negate
      è   # Index at the first input
\$\endgroup\$
  • 1
    \$\begingroup\$ @Okx The CMC asked for a Boolean. \$\endgroup\$ – Dennis Mar 9 '17 at 2:45
6
\$\begingroup\$

PHP, 58 Bytes

<?=in_array(($a=$argv[1])-$b=$argv[2],range($a,$b))?$a:$b;
\$\endgroup\$
  • 1
    \$\begingroup\$ The $b assignment needs no parentheses. \$\endgroup\$ – Titus Mar 9 '17 at 2:23
6
\$\begingroup\$

JavaScript (ES6), 24 bytes

a=>b=>[a,b][2*b*b>a*b|0]

Test cases

let f = a=>b=>[a,b][2*b*b>a*b|0]
let tests = [[1,4,4],[-2,5,5],[3,-1,-1],[7,7,7],[90,30,90],[90,-30,-30],[-90,30,30],[-90,-30,-90],[-2,-2,-2],[-2,-1,-2],[-2,0,-2],[-2,1,1],[-2,2,2],[-1,-2,-2],[-1,-1,-1],[-1,0,-1],[-1,1,1],[-1,2,2],[0,-2,-2],[0,-1,-1],[0,0,0],[0,1,1],[0,2,2],[1,-2,-2],[1,-1,-1],[1,0,1],[1,1,1],[1,2,2],[2,-2,-2],[2,-1,-1],[2,0,2],[2,1,2],[2,2,2]]
tests.map(test => `f(${test[0]})(${test[1]}) == ${test[2]}`).forEach(test => console.log(test, eval(test)))

\$\endgroup\$
4
\$\begingroup\$

Python 2, 37 bytes

lambda*s:s[min(s)<=s[1]-s[0]<=max(s)]

Invoke as f(B, A).

\$\endgroup\$
4
\$\begingroup\$

Python2, 55 52 51 bytes

lambda A,B:[B,A][A-B in range(min(A,B),max(A,B)+1)]

Try it online!

Handles every test case OP has mentioned (at the time of posting this), as the TIO suggests.

\$\endgroup\$
4
\$\begingroup\$

JavaScript ES6, 40 37 bytes

a=>b=>a-b<(a<b?a:b)|a-b>(a<b?b:a)?b:a

Explained:

a=>b=>                                   take a and b as inputs
      a-b<(a<b?a:b)                      if a-b is less than the lowest of a and b
                   |a-b>(a<b?b:a)        or a-b is greater than the largest of a and b
                                 ?b      return b
                                   :a    else return a

Saved 3 bytes thanks to Arnauld.

f=a=>b=>a-b<(a<b?a:b)|a-b>(a<b?b:a)?b:a

function t(){
    var tests = [[1,4,4],[-2,5,5],[3,-1,-1],[7,7,7],[90,30,90],[90,-30,-30],[-90,30,30],[-90,-30,-90],[-2,-2,-2],[-2,-1,-2],[-2,0,-2],[-2,1,1],[-2,2,2],[-1,-2,-2],[-1,-1,-1],[-1,0,-1],[-1,1,1],[-1,2,2],[0,-2,-2],[0,-1,-1],[0,0,0],[0,1,1],[0,2,2],[1,-2,-2],[1,-1,-1],[1,0,1],[1,1,1],[1,2,2],[2,-2,-2],[2,-1,-1],[2,0,2],[2,1,2],[2,2,2]];
    for (var test of tests) {
        console.log(`f(${test[0]},${test[1]}) == ${test[2]}`, f(test[0])(test[1])==test[2]);
    }
}

t();

\$\endgroup\$
3
\$\begingroup\$

Mathematica, 16 bytes

If[2#^2>1##,##]&

Pure function taking two arguments in the opposite order as the OP (for example, If[2#^2>1##,##]&[B,A]). A port of xnor's Python answer.

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

R, 49 30 28 bytes

pryr::f("if"(2*b*b>a*b,b,a))

Uses @xnor's logic for determining whether a-b is in a:b.

\$\endgroup\$
  • \$\begingroup\$ unnamed functions are generally allowed \$\endgroup\$ – MickyT Mar 9 '17 at 1:09
  • \$\begingroup\$ You can lose another 3 bytes using pryr::f(match(a-b,a:b,b)) \$\endgroup\$ – mnel Mar 9 '17 at 11:20
  • \$\begingroup\$ @mnel thanks for sharing that, I didn't know how %in% worked before; but that fails whenever a-b is in a:b. f(-90,-30) = 31 \$\endgroup\$ – BLT Mar 9 '17 at 18:20
  • \$\begingroup\$ Indeed. `pryr::f(match(a-b,a:b,0)+b) fixes that (and still saves a byte. \$\endgroup\$ – mnel Mar 10 '17 at 9:29
2
\$\begingroup\$

Clojure, 71 41 bytes

-30 bytes by using <= and min/max instead of ranges.

#(if(<=(min % %2)(- % %2)(max % %2))% %2)

Checks if (a - b) is in the range from a to b, dispatching a return accordingly.

(defn eh [a b]
  ; <= accepts any number of argments, and ensures all fall within the range
    (if (<= (min a b) (- a b) (max a b))
      a
      b))
\$\endgroup\$
2
\$\begingroup\$

PHP (7.1), 55 bytes

uses the new array destructuring syntax:

[,$a,$b]=$argv;echo in_array($a-$b,range($a,$b))?$a:$b;

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

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

PowerShell, 37 35 32 bytes

($a,$b=$args)[$a-$b-notin$a..$b]

Try it online!

Literal translation of the problem into PowerShell using the -notin operator. Saved three bytes by using multiple assignment and encapsulation. This works because - has a higher operator precedence than -notin, and the ( ) portion of the code is executed first and returned as an array @($a,$b). However, since it's $a,$b rather than $b,$a, we need to use -notin to flip/flop the output result.

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

Batch, 107 bytes

@set/aa=%1,r=b=%2,x=a-b
@if %a% gtr %b% set/aa=b,b=%1
@if %a% leq %x% if %x% leq %b% set/ar=%1
@echo %r%
\$\endgroup\$
1
\$\begingroup\$

Pyth - 9 bytes

Was hoping to use more implicit input... :(

@Q!}-FQ}F

Try it online here.

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

Röda, 30 bytes

f a,b{[b]if[2*b*b>a*b]else[a]}

Try it online!

It uses the formula used in xnor's answer.

Another solution (37 bytes):

f a,b{[a]if[a-b in[seq(a,b)]]else[b]}

Try it online!

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

><>, 21 bytes

Makes use of @xnor's trick. We use -v B A to prepopulate the stack. (-v A B is +1 byte).

:01pr:11p::2**r*)1gn;

Try it online!

Explanation

                        Input: [B, A] on stack.
:01pr:11p::2**r*)1gn;
:                       Duplicate.           [B, A, A]
 01p                    Push A to [0,1].     [B, A]
    r                   Reverse              [A, B]
     :                  Duplicate.           [A, B, B]
      11p               Push B to [1,1].     [A, B]
         ::             Duplicate x 2.       [A, B, B, B]
           2            Push 2.              [A, B, B, B, 2]
           2**          Compute 2*B*B.       [A, B, 2*B*B]
              r         Reverse.             [2*B*B, B, A]
               *        Compute A*B.         [2*B*B, A*B]
                )       >                    [2*B*B > A*B]
                 1      Push 1.              [2*B*B > A*B, 1]
                  g     If 2*B*B > A*B
                         get B, else get A.  [2*B*B > A*B ? B : A]
                   n    Output as number.
                    ;   Terminate.
\$\endgroup\$
1
\$\begingroup\$

Ruby, 27 22 bytes

->a,b{(b*a<2*b*b)?b:a}

Try it online!

Nothing innovative here. The simple math behind it:

(A<=A-B<=B or B<=A-B<=A)

can be written as

(B>=0 and A>=2B) or (B<=0 and A<=2B)

that is: if A-2B has the same sign as B, we are in the range.

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

SpecBAS - 38 btes

1 INPUT a,b: ?IIF(a-b IN [a TO b],a,b)

IIF is an inline-IF-THEN-ELSE, to print the correct value.

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

Haskell, 21 bytes

a!b|b*a<2*b*b=b|0<1=a

Try it online!

Readable

func :: Int -> Int -> Int
func a b
    | b*a < 2*b*b = b
    | otherwise = a

Explanation

Uses @xnor's formula to check whether a-b is in range. Nothing special besides that.

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

Haskell, 58 bytes

Just recently I fell in love with arrows again. Unfortunately they require us to work with tuples instead of binary functions. And of course Haskell does not have a symmetrical range function.

import Control.Arrow
u=uncurry
app<<<elem.u(-)&&&(u enumFromTo<<<u min&&&u max)
\$\endgroup\$
1
\$\begingroup\$

PHP 7 - 45 Bytes

echo(in_array($a-$b,range($a,$b))?$a:$b)==$c;
\$\endgroup\$
  • \$\begingroup\$ Welcome to the site! \$\endgroup\$ – DJMcMayhem Mar 9 '17 at 19:42
1
\$\begingroup\$

Octave, 55bytes

@(a,b)(c=b*~[find((a:1-2*(b<a):b)==(a-b)) 0](1))+(a*~c)

This could probably be optimised further. I'll add an explanation later.

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

Nim, 60 bytes

proc f(a,b:int):int=
  if a-b in min(a,b)..max(a,b):a else:b

Try it online!

Pretty standard as far as answers go, no big tricks in this one.

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

Swift - 38 30 22 bytes

Saved 8 bytes thanks to @Matt

print(a...b~=a-b ?a:b)

Try it at IBM Swift Sandbox online!


Or 21 bytes:

(thanks to @xnor's formula) and saved 8 bytes thanks to @Matt

print(2*b*b>a*b ?a:b)

Swift is not the best language for golfing (it's very rigid), so if you see any other golfing opportunity, I'll totally edit the answer.

\$\endgroup\$
  • \$\begingroup\$ Why not put the ternary inside the print like print(a...b~=a-b ? a : b) \$\endgroup\$ – Matt Mar 9 '17 at 17:19
  • \$\begingroup\$ Oh, yes, good ideA. Thanks @Matt \$\endgroup\$ – Mr. Xcoder Mar 9 '17 at 17:20
1
\$\begingroup\$

Java 7, 84 60 58 bytes

int c(int a,int b){return(a<b?a:b)>a-b|(a<b?b:a)<a-b?b:a;}

Java 8, 37 bytes

a->b->(a<b?a:b)>a-b|(a<b?b:a)<a-b?b:a

Explanation:

int c(int a, int b){          // method with two integer parameters and integer return-type
  return (a<b ? a : b) > a-b  //  if smallest of the input is larger than a-b
       | (a<b ? b : a) < a-b  //    or if the largest of the input is smaller than a-b
    ? b                       //   return b
    :                         //  else
      a                       //   return a
}                             // end of method

Test code: Try it here.

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

Ti-Basic (TI-84 Plus CE), 26 24 23 bytes

Prompt A,B
A-B≥A and A-B≤B
AAns+Bnot(Ans

TI-Basic is a tokenized language; all tokens used are one-byte tokens.

Prompt prompts you for the two numbers.

A-B≥A and A-B≤B checks if A-B is between A and B (inclusive); this returns a 1 if true and a zero if false, which is stored to Ans.

Since we are returning A if A-B is between A and B, we multiply A by Ans, which will be A if we are supposed to return A, and 0 otherwise.

Next, we add Bnot(Ans to it. If Ans was 1 (truthy), we not( it and get 0, thus our sum is A. If Ans was 0 (falsy), we not( it to get 1, which we multiply by B and add to 0 to get B.

The last evaluation in TI-Basic is implicitly returned.

-2 bytes thanks to Scott Milner

\$\endgroup\$
  • \$\begingroup\$ You can save two bytes by not storing the third line to Y and just using Ans in the fourth line. \$\endgroup\$ – Scott Milner May 15 '17 at 17:52
1
\$\begingroup\$

Pyt, 32 bytes

←Đ←Đ3Ș⇹Đ3ȘĐ4Ș3Ș-3Ș⇹Ř∈Đ3Ș⇹¢*3Ș⇹*+

Takes A and B from stdin as two separate inputs

Explanation:

AABB -> ABBA -> ABAB -> ABABB -> ABBBA -> ABBBAA -> ABAABB -> ABABBA -> ABABC -> ABCBA -> ABCAB -> ABC[A,...,B] -> ABD -> ABDD -> ADDB -> ADBD -> AD{B*(1-D)} -> {B*(1-D)}AD -> {B*(1-D)}+{A*D}

where: C=B-A and D=C∈[A,...,B] (1 if true, 0 if false)

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

Ohm, 10 bytes (CP437)

There's probably a golfier way to do this, but the strictly-typed nature of Ruby makes this difficult.

G┼┘-îε?┼¿┘
\$\endgroup\$
0
\$\begingroup\$

Perl 6,  31 29  24 bytes

{$^a-$^b==any($a...$b)??$a!!$b}

Try it

{$^a-$^b∈($a...$b)??$a!!$b}

Try it

->\a,\b{2*b*b>a*b??b!!a}
->\a,\b{2*b²>a*b??b!!a}

Try it

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