If A-B be in A-B A else B eh?

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

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.

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


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

• @Okx The CMC asked for a Boolean. Mar 9 '17 at 2:45

PHP, 58 Bytes

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


Python 2, 37 bytes

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


Invoke as f(B, A).

Python2, 5552 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.

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(); 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. R, 4930 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. • unnamed functions are generally allowed Mar 9 '17 at 1:09 • You can lose another 3 bytes using pryr::f(match(a-b,a:b,b)) – mnel Mar 9 '17 at 11:20 • @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 – BLT Mar 9 '17 at 18:20 • Indeed. pryr::f(match(a-b,a:b,0)+b) fixes that (and still saves a byte. – mnel Mar 10 '17 at 9:29 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))  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.

PowerShell, 3735 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. 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. 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%  Pyth - 9 bytes Was hoping to use more implicit input... :( @Q!}-FQ}F  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! ><>, 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.  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. 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. 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. 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)  PHP 7 - 45 Bytes echo(in_array($a-$b,range($a,$b))?$a:$b)==$c;

• Welcome to the site! Mar 9 '17 at 19:42

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.

• A simpler approach. +1 for all the "crazy stuff" in there though :P Mar 20 '17 at 10:38

Swift - 3830 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.

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

Java 7, 8460 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.

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

• You can save two bytes by not storing the third line to Y and just using Ans in the fourth line. May 15 '17 at 17:52

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)

Ohm, 10 bytes (CP437)

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

G┼┘-îε?┼¿┘


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