When learning to factorise quadratics in the form $$\x^2 + ax + b\$$, a common technique is to find two numbers, $$\p, q\$$ such that

$$pq = b \\ p + q = a$$

as, for such numbers, $$\x^2 + ax + b = (x + p)(x + q)\$$

You are to take two integers $$\a, b \in (-\infty, +\infty)\$$ and output the two integers $$\p, q\$$ such that

$$pq = b \\ p + q = a$$

You may take input in any convenient method and you may assume that a solution always exists.

This is so the shortest code in bytes wins

Test cases

2, -15 -> 5, -3
-22, 85 -> -5, -17
6, -16 -> -2, 8
-8, -240 -> -20, 12
-1, -272 -> 16, -17
17, 16 -> 1, 16
-4, 0 -> 0, -4
3, -54 -> 9, -6
13, 40 -> 8, 5
-29, 198 -> -11, -18
11, -12 -> -1, 12
4, -320 -> 20, -16
4, 4 -> 2, 2

• Dec 12 '20 at 22:33
• Imaginary brownies for beating my 5 byte Jelly answer Dec 12 '20 at 22:40

Scala 3, 49 44 bytes

a=>b=>(-b*b to b*b)map(p=>a-p->p)find(_*_==b)


Try it onlne!

Takes (a)(b) and returns an Option[(Int, Int)]. It's now a little more inefficient since it goes from $$\-b^2\$$ to $$\b^2\$$ instead of $$\-|b|\$$ to $$\|b|\$$, including values that $$\p\$$ and $$\q\$$ could never be, but it saves 4 bytes.

a => b =>
(-b*b to b*b)              //Make a range of all possible q's and then some
map(q => (a - q, q))     //Make a tuple of (p, q)
find(_ * _ == b)         //Find a pair such that p * q = b

• Why doesn't the range -b*b to b work (I tried it on your link and it failed, but without knowing Scala I'm puzzled what could be wrong...)? Dec 13 '20 at 17:25
• @DominicvanEssen -b*b is guaranteed to be negative, but b could be negative too (Scala doesn't adjust step automatically, it's +1 by default)
– user
Dec 13 '20 at 17:31
• Ah, of course! Sorry for the stupid question! Dec 13 '20 at 17:38

JavaScript (ES7),  37 36 34  31 bytes

Saved 3 bytes thanks to @tsh

Expects (a)(b).

a=>b=>[b=a/2+(a*a/4-b)**.5,a-b]


Try it online!

• 31 bytes: a=>b=>[p=a/2+(a*a/4-b)**.5,a-p]
– tsh
Dec 13 '20 at 7:30
• @tsh Simpler is better. :-) Thank you. Dec 13 '20 at 19:58

Wolfram Language (Mathematica), 2321 18 bytes

Solve[x x+#2==x#]&


Try it online!

• The output format’s a little convoluted, but it looks like you can remove the x/. Dec 13 '20 at 7:06
• In addition, since you can take the input in any convenient format, why not choose the input format [x^2-a x+b] instead of [a,b]? Dec 13 '20 at 20:51
• @GregMartin That's a bit too finicky for my liking.
– att
Dec 13 '20 at 20:54
• I get that for sure ... it seems that people here say "any convenient format" but then are put off by formats like that ... would be nice to have it clarified (for that matter, the same issue for output already came up in earlier comments on this answer!) Dec 13 '20 at 23:36
• @GregMartin FWIW, I wouldn't consider it valid either; it's like saying "input is in format <full program>" and the solution is just eval. Note that "convenient format" is precisely specified as per the link... Dec 14 '20 at 11:22

Jelly, 5 bytes

1ṭÆrN


Try it online!

Input as a list [b, a].

1ṭ       Append 1 to the input, (resulting in [b, a, 1])
Ær     find roots of polynomial from little-endian coefficient list,
N    negate each root.

• Mine was the same, but with ;1 at the start instead Dec 12 '20 at 23:40
• why 1 instead of 0? Dec 14 '20 at 15:02
• @MadPhysicist The 1 is the coefficient of the $x^2$ term--if it was 0, I'd be left with just a linear function. Dec 14 '20 at 18:34
• OIC. I misread/didn't think it through Dec 14 '20 at 18:38

Retina 0.8.2, 94 bytes

\d+
$* ^(-?)(1*)(,(-)(?<2>\2(1(1)*))|(?<5>(?<6>1)*),)(?<-6>\2)*$(?(6)1)
$1$.2,$4$1$.5 -- -0 0  Try it online! Link includes test cases. Explanation: $$\|p|\$$ is captured in $2 and $$\|q|\$$ is captured in $5, with $6 being a helper balancing group used to verify the multiplication.

\d+
$*  Convert to unary. ^(-?)(1*)  Start by matching the sign of $$\a\$$, then initially assume $$\|p|\$$ is no greater than $$\|a|\$$. (,(-)(?<2>\2(1(1)*))  If $$\b\$$ is negative, then we actually end up matching $$\|a|\$$, and choose $$\|q|\$$ and overwrite $2 with $$\|p|=|a|+|q|\$$, so $$\|a|=|p|+|q|\operatorname{sgn}(b)\$$.

|(?<5>(?<6>1)*),)


Otherwise $$\b\$$ is positive, so overwrite $5 with $$\|q|\$$ such that $$\|a|=|p|+|q|\operatorname{sgn}(b)\$$. (?<-6>\2)*$(?(6)1)


Ensure $$\|b|=|pq|\$$.

$1$.2,$4$1\$.5


Output $$\p = |p|\operatorname{sgn}(a)\$$ and $$\q = |q|\operatorname{sgn}(ab)\$$. We then have $$\p+q=|p|\operatorname{sgn}(a)+|q|\operatorname{sgn}(ab)=(|p|+|q|\operatorname{sgn}(b))\operatorname{sgn}(a)=|a|\operatorname{sgn}(a)=a\$$ while $$\pq=|p|\operatorname{sgn}(a)|q|\operatorname{sgn}(ab)=|pq|\operatorname{sgn}(b)=|b|\operatorname{sgn}(b)=b\$$ as desired (where $$\\operatorname{sgn}(0)=1\$$).

--

-0
0


Fix up extraneous -s.

Charcoal, 25 bytes

ＮθＮηＩ⊟ΦＥ…·±↔η↔η⟦ι⁻θι⟧⁼ηΠι


Try it online! Link is to verbose version of code. Same idea as @user's Scala solution. Explanation:

ＮθＮη


Input $$\a\$$ and $$\b\$$.

Ｅ…·±↔η↔η


Loop $$\p\$$ over $$\[-|b|,|b|]\$$.

⟦ι⁻θι⟧


For each $$\p\$$ create a list $$\(p,q)\$$ where $$\q=a-p\$$.

Ｉ⊟Φ...⁼ηΠι


Output the one with the highest $$\p\$$ where $$\pq=b\$$.

Octave, 17 bytes

@(x)-roots([1 x])


Try it online!

You simply need to solve $$\x^2 + ax + b = (x + p)(x + q) = 0\$$, and $$\x_1=-p\$$, $$\x_2=-q\$$.

Python 3.8, 42 39 37 bytes

Saved 2 bytes thanks to Danis!!!

lambda a,b:[c:=a/2+(a*a/4-b)**.5,a-c]


Try it online!

• you can save two bytes by removing the parentheses 37 bytes Dec 13 '20 at 20:42
• @Danis Nice one - thanks! :-) Dec 13 '20 at 23:22

05AB1E, 17 16 bytes

(Dn4I*-t‚DOsÆ);(


Try it online!

Why oh why aren't there any built-ins for this? This solves the quadratic equation to get the two roots. -1 thanks to @ovs

• D(sn can be (Dn or (¹n for -1 byte.
– ovs
Dec 13 '20 at 9:41
• Wow, there is a winking sad face at the end. Dec 13 '20 at 9:51
• Alternative 17-byter. Maybe someone sees a way to golf it further. If outputting an infinite list of pairs is valid (which contains a single pair most likely), I guess it could be 16 bytes. Dec 14 '20 at 8:47

Brachylog, 8 bytes

~+ʰ⟨≜×⟩Ċ


Try it online!

Takes input as a list [a,b].

  ʰ         For the first element of the input,
~+          get a list of integers which sum to it
≜       (in order of least absolute value of the first element).
⟨ ×⟩     Its product is the second element,
Ċ    its length is 2,
and it's the output.


I'm not entirely sure why this needs ≜, but it comes at no cost because the "sandwich" construct ⟨~+×⟩ won't parse without braces around ~+ anyhow (and both ⟨{~+}×⟩Ċ and ~+ʰ⟨≡×⟩Ċ would still come out to 8).

Wolfram Language (Mathematica), 28 bytes 24 bytes

thanks to att

#&@@Solve[#-b==a==#2/b]&


Try it online!

• 24 bytes
– att
Dec 13 '20 at 1:39

dc, 24 bytes

Input is a line of two numbers from STDIN. Output is to STDOUT.

?rdsad*r4*-vla+2/dlar-rf


Try it online!

Explanation

?                        # Read a line of input
r                       # Swap the two numbers
dsa                    # Store to a w/o popping
d*                  # Square the 1st input
r                 # Swap up the second input
4*               # Multiply by four
-              # Second-to-top - TOS
v             # Square root
la+          # Add by a
2/        # Halve
d       # Duplicate
lar-   # Push a - TOS
r  # Swap the top 2 items
f # Print entire stack


Python 3.8 (pre-release), 37 bytes

lambda a,b:[p:=a/2+(a*a/4-b)**.5,a-p]


Try it online!

Python 2, 42 bytes

def f(a,b):p=a/2+(a*a/4-b)**.5;print p,a-p


Try it online!

Takes input as float, and prints the output.

Husk, 12 bytes

ḟo=¹ΠmSe-²ṡ


Try it online!

           ṡ    # range of integers from -arg1 to +arg1
m          # map over each of them
S         # combining itself
e        # into a 2-element list with
-²     # arg2 minus this;
ḟ               # now find the first element that satisfies
o              # combine 2 functions:
Π           # product
=¹            # equals arg1


R, 36 35 bytes

function(b,c)b/2+-.5:1*(b^2-4*c)^.5


Try it online!

Uses the Quadratic formula with a=1.

• polyroot(c(b,a,1)) seems shorter. Dec 14 '20 at 10:32
• @Xi'an - Really nice! Thanks for introducing me to polyroot and you should post this as your own answer! You can shorten it even more by taking input as a 2-element vector, too: try it... Dec 14 '20 at 10:58
• @Xi'an i don't think it's acceptable, since you still have to specify a=1 Dec 14 '20 at 11:34
• @Xi'an - I agree with ASCII-only. You need to be able to 'call' or run your answer using only the input specified in the question. Dec 14 '20 at 12:31
• R 4.1 (r-devel) would allow lambda syntax \(x) polyroot(c(1,x)) Dec 15 '20 at 21:42

C (gcc)-lm, 45 bytes

f(int*a){*a-=a[1]=(*a+sqrt(*a**a-4*a[1]))/2;}


Try it online!

Modifies an input array of 2 ints.

C (gcc), 53 bytes

i;f(int*a){for(i=*a/2;(*a-i)*i-a[1];i--);*a-=a[1]=i;}


Try it online!

Doesn't use sqrt.

APL (Dyalog Unicode), 28 26 bytes

-2 thanks to Razetime.

{⍺-⎕←(⍺÷2)+.5*⍨⍵-⍨⍺×⍺÷4}


Try it online!

• -2 Dec 14 '20 at 7:35

APL (Dyalog Extended), 19 bytes

-2 thanks to @Bubbler

÷∘2⍛{⍺(+,-)√⍵-⍨⍺*2}


Try it online!

• 19 bytes Dec 15 '20 at 2:32

a!b=[(k,b-k)|k<-[-a*a..],k*b-k*k==a]!!0


Try it online!

Kind of boring, but short.

• a!b=[(x,b-x)|x<-[-aa..aa],x*(b-x)==a]!!0 is shorter
– user100177
Jan 3 at 20:41
• @user100177 a!b=[(k,b-k)|k<-[-a*a..],k*b-k*k==a]!!0 is even shorter. Jan 4 at 0:09
• Good find, I didn't think about an infinite list. It's just as short as mine now, actually.
– user100177
Jan 7 at 15:16

convey, 113 bytes

v<1
>>>v 0
{?>*"-"v
4*  "vvv
v  >*vv
v#<<<<vv
-<    vv
*%2   v>v
.1    v}>v
v     v%2v}%2
">>>>>-^>+>^
>>>>>>>>^


Try it online!

Julia 1.0, 34 bytes

(a,b)->(d=(a*a-4b)^.5;[a+d,a-d]/2)


Try it online!

MathGolf, 13 bytes

_½\²¼k-√+-αÞ


I/O as floats.

Try it online.

I have the feeling this can be a byte shorter with some smart stack manipulations, but I've been unable to find anything yet. An equal-bytes alternative could be ²¼k-√;½+-αÞ.

Explanation:

_             # Duplicate the first (implicit) input-float
½            # Halve it
\           # Swap so the first input is at the top of the stack again
²          # Square it
¼         # Divide it by 4
k-       # Subtract the second input-float
√      # Take the square-root of that
+     # Add it to the halved first input that's still on the stack
# Duplicate the top two values (since the stack only contains a single
# item, this will first add the first input-float implicitly as leading
# item, and then duplicate both items)
-   # Subtract the top two items from one another
α  # Pair the top two items
Þ # Only leave the top item of the stack, and discard everything else
# (after which the entire stack is output implicitly as result)


Ruby, 4137 35 bytes

A port of Arnauld's answer in Ruby!

->a,b{[b=a/2r+(a*a/4r-b)**0.5,a-b]}


Try it online!

05AB1E, 10 9 bytes

D(Ÿʒ-y*¹Q


Try it online!

Takes input as

b
a


In case $$\p=q\$$ it returns only a single value. In case that's not allowed, it's +5 bytes for appending }Ðgi«

Explanation:

D              duplicate
)              negate
Ÿ              range, so [-b,.. , b]
ʒ              filter
-             minus the implicit a
y            the current number
*           multiply
¹          the first item from the input history - b
Q         is equals


Vyxal, 3 bytes

∆QN


Try it Online!

Solve for the roots and then negate

Whispers v2, 110 92 bytes

Edit: -18 bytes (within less than 2 minutes of submission!) thanks to caird coinheringaahing and the ± operator

> Input
> Input
> 2
> 4
>> 1*3
>> 2⋅4
>> 5-6
>> √7
>> 8÷3
>> 1÷3
>> 10±9
>> Output 11


Try it online!

My first Whispers program.
Uses the Quadratic formula with a=1.

• 92 bytes Feb 7 at 23:07
• @cairdcoinheringaahing - Thanks! I should have guessed that ± would exist. That must be a contender for one of the fastest upgolfs yet... Feb 7 at 23:12

Pari/GP, 33 bytes

f(a,b)=round(polroots(x^2+a*x+b))


Try it online!

f a b=let c=a/2+(a*a/4-b)**0.5in[c,a-c]

• Some simple improvements bring it down to 33: a!b|c<-a/2+(a*a/4-b)**0.5=[c,a-c] Jan 7 at 23:29