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

44

3

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

Calvin's Hobbies

Posted 2017-03-08T22:10:15.960

Reputation: 84 000

Answers

44

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.

xnor

Posted 2017-03-08T22:10:15.960

Reputation: 115 687

10

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

Dennis

Posted 2017-03-08T22:10:15.960

Reputation: 196 637

8

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

Adnan

Posted 2017-03-08T22:10:15.960

Reputation: 41 965

1@Okx The CMC asked for a Boolean. – Dennis – 2017-03-09T02:45:18.493

6

PHP, 58 Bytes

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

Jörg Hülsermann

Posted 2017-03-08T22:10:15.960

Reputation: 13 026

1The $b assignment needs no parentheses. – Titus – 2017-03-09T02:23:19.960

6

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

alebianco

Posted 2017-03-08T22:10:15.960

Reputation: 171

4

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.

Yytsi

Posted 2017-03-08T22:10:15.960

Reputation: 3 582

4

Python 2, 37 bytes

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

Invoke as f(B, A).

Lynn

Posted 2017-03-08T22:10:15.960

Reputation: 55 648

4

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();

Tom

Posted 2017-03-08T22:10:15.960

Reputation: 3 078

3

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.

Greg Martin

Posted 2017-03-08T22:10:15.960

Reputation: 13 940

2

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.

BLT

Posted 2017-03-08T22:10:15.960

Reputation: 931

unnamed functions are generally allowed – MickyT – 2017-03-09T01:09:17.443

You can lose another 3 bytes using pryr::f(match(a-b,a:b,b)) – mnel – 2017-03-09T11:20:40.640

@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 – 2017-03-09T18:20:00.117

Indeed. `pryr::f(match(a-b,a:b,0)+b) fixes that (and still saves a byte. – mnel – 2017-03-10T09:29:26.993

2

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

Carcigenicate

Posted 2017-03-08T22:10:15.960

Reputation: 3 295

2

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.

Titus

Posted 2017-03-08T22:10:15.960

Reputation: 13 814

2

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.

AdmBorkBork

Posted 2017-03-08T22:10:15.960

Reputation: 41 581

1

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%

Neil

Posted 2017-03-08T22:10:15.960

Reputation: 95 035

1

Pyth - 9 bytes

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

@Q!}-FQ}F

Try it online here.

Maltysen

Posted 2017-03-08T22:10:15.960

Reputation: 25 023

1

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!

fergusq

Posted 2017-03-08T22:10:15.960

Reputation: 4 867

1

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.

Kevin Cruijssen

Posted 2017-03-08T22:10:15.960

Reputation: 67 575

1

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

PidgeyUsedGust

Posted 2017-03-08T22:10:15.960

Reputation: 631

1

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.

Mr. Xcoder

Posted 2017-03-08T22:10:15.960

Reputation: 39 774

Why not put the ternary inside the print like print(a...b~=a-b ? a : b) – Matt – 2017-03-09T17:19:43.660

Oh, yes, good ideA. Thanks @Matt – Mr. Xcoder – 2017-03-09T17:20:20.420

1

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.

G B

Posted 2017-03-08T22:10:15.960

Reputation: 11 099

1

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.

Brian

Posted 2017-03-08T22:10:15.960

Reputation: 1 209

1

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.

Eisfunke

Posted 2017-03-08T22:10:15.960

Reputation: 101

1

PHP 7 - 45 Bytes

echo(in_array($a-$b,range($a,$b))?$a:$b)==$c;

PerQsive

Posted 2017-03-08T22:10:15.960

Reputation: 29

Welcome to the site! – James – 2017-03-09T19:42:27.450

1

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)

Bergi

Posted 2017-03-08T22:10:15.960

Reputation: 967

1

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.

Tom Carpenter

Posted 2017-03-08T22:10:15.960

Reputation: 3 990

A simpler approach. +1 for all the "crazy stuff" in there though :P – Stewie Griffin – 2017-03-20T10:38:20.560

1

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.

syril

Posted 2017-03-08T22:10:15.960

Reputation: 11

1

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

pizzapants184

Posted 2017-03-08T22:10:15.960

Reputation: 3 174

You can save two bytes by not storing the third line to Y and just using Ans in the fourth line. – Scott Milner – 2017-05-15T17:52:06.027

1

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)

mudkip201

Posted 2017-03-08T22:10:15.960

Reputation: 833

0

Ohm, 10 bytes (CP437)

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

G┼┘-îε?┼¿┘

Nick Clifford

Posted 2017-03-08T22:10:15.960

Reputation: 1 184

0

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

Brad Gilbert b2gills

Posted 2017-03-08T22:10:15.960

Reputation: 12 713

0

Kotlin, 43 bytes

{a,b->if(a-b in a..b||a-b in b..a)a else b}

This is the one time that I am grateful that kotlin ranges are inclusive.

You could alternatively do it using xnor's algorithm with 28 bytes:

{a,b->if(2*b*b>a*b)b else a}

Test Suite

TheNumberOne

Posted 2017-03-08T22:10:15.960

Reputation: 10 855

0

MATL, 13 bytes

tPdGSl&)&:mo)

Try it at MATL Online

Explanation

    % Implicitly grab input as a 2-element array
t   % Duplicate the input
Pd  % Flip the order and compute the difference
GS  % Grab the input again and sort it
l&) % Break the two elements of the array into two stack elements
&:  % Create the array from the smaller to the larger element
m   % Check for membership (returns FALSE or TRUE)
o   % Convert FALSE to 0 and TRUE to 1
)   % Use this as a modular index into the initial array
    % Implicitly display the result

Suever

Posted 2017-03-08T22:10:15.960

Reputation: 10 257

0

Japt, 14 bytes

òV bU-V ¨0?U:V

Try it online!

Tom

Posted 2017-03-08T22:10:15.960

Reputation: 3 078

0

Ohm, 25 bytes

IIGÉ┼┘-E;?┼¿┘;,

Expanation:

IIGÉ┼┘-E;?┼¿┘;,
II              ■Inputs twice
  G             ■Range a..b
   É            ■any {
    ┼┘-E        ■  firstInput-secondInput==element
        ;       ■}
         ? ¿ ;  ■if {
          ┼     ■  firstinput
           ¿    ■}else{
            ┘   ■  secondinput
             ;  ■}
              , ■Print

Roman Gräf

Posted 2017-03-08T22:10:15.960

Reputation: 2 915

0

Google Sheets, 49 bytes

-2 bytes because Google Sheets automatically closes brackets

=MINUS(A1,A2
=IF(AND(GTE(A1,A3),LTE(A2,A3)),A1,A2

Inputs are in the cells A1 and A2. Assumes cell A3 is selected after input is recieved.

The newline isn't actually a newline, it's just pressing enter.

The code is pretty readable, so I doubt an explanation is needed.

Okx

Posted 2017-03-08T22:10:15.960

Reputation: 15 025

0

Octave, 37 34 bytes

@(a)a(2-ismember(-diff(a),a:a(2)))

This is an anonymous function that takes the input values as an array of two elements: [-90, 30].

Breakdown:

@(a)a(                           )  % Function that takes a variable a as input
                                    % and returns the x'th element (dependent on what's
                                    % inside the parentheses.
                 -diff(a)           % Takes the negative difference between the two

                          a:a(2)))  % A vector: -3 -2 -1 0 1 2 ...
        ismember(-diff(a),a:a(2)))  % Checks if the negative difference (a-b)
                                       % is part of the range. Returns 1 for true
    a(2-ismember(-diff(a),a:a(2)))  % Return the 2-ismember() element of the input
@(a)a(2-ismember(-diff(a),a:a(2)))  % Everything put together

a(1):a(2) is the same as a:a(2) since Octave automatically assumes you want the first element. That saved an additional two bytes.

I could save one more byte by taking the input in the different order [b, a], but I figured it was cleaner this way.

Stewie Griffin

Posted 2017-03-08T22:10:15.960

Reputation: 43 471

0

Ly, 39 bytes

nn&s<l>>lRy![plfR11$]p<-s>l~[<<pu;]<<u;

Try it online!

LyricLy

Posted 2017-03-08T22:10:15.960

Reputation: 3 313