Reng v.3.3, 33 bytes
Takes input like
a c b. Try it here!
The calculation is simple.
i gets input, so
a + c, and
i- is then
(a + c) - b. Very simple stuff.
The hard part is taking the max with
0. "What!? How could it be that hard?" Well, I didn't implement inequality in Reng. So we'll have to use math!
max(a,b) = (a+b+|a-b|)/2
max(a,0) = (a+|a|)/2
|a| = Sqrt[a^2]
Observation 4: Reng doesn't have square roots, either. Nor does it have power. But knowing that we'll only be taking the square roots of perfect squares, we can use trial and error, starting at 1. That is, our algorithm can look like this:
x = 1 to a, iterate:
if x * x == a break, return X
Since we always have
k being a perfect square, this algorithm always terminates.
So, into the rest of the code explanation!
part 1: initialization
I've already explained how
ii+i- works, so let's look at the rest of the line.
: duplicates this number. The bottom number will be
(a + |a|)/2. Now, we need to take the absolute value of the top value. We can do this using observations 3 and 4.
² squares the top value, and
1#x initializes our counter
1. Then we go to the next line with
part 2: square root loop
: duplicates our maximum value
a from the top of the stack (for the equality check).
x² squares our counter
e pushes a Boolean representing the equality of
a. If they are equal,
q! breaks out of the loop by going down (
|a| on the stack. Otherwise, we increment
x1+) and set
x to that value (
< redirects the program to look left. shhh it saves bytes. It's equivalent to this series of steps:
+ adds the top two of the stack, thus implementing the first part of
(a + |a|)/2.
2% divides that sum by two (
% is division here because
/ is a mirror). Lastly, we output this as a number (
n) and terminates the program (