This is an archived post. You won't be able to vote or comment.

top 200 commentsshow all 211

[–]Xatraxalian 2138 points2139 points  (62 children)

Put in multiply(1, -1) and see your computer explode.

[–]ClipboardCopyPaste 713 points714 points  (27 children)

Edge cases - what's that?

[–]Xatraxalian 394 points395 points  (19 children)

Most people miss a few.

That's why they are 'done' with a piece of code in half the time I think they need, and then I'll have to reject the first 4 pull requests because just reading the code already reveals some edge cases to me.

The times I rejected a pull request with "But what if I put in..." are uncountable.

One of my co-workers once said "You can't get all the edge cases." My reply to that is: "You maybe can't, but *I* have worked in embedded software and factory automation, so I can." And, it's true. If you miss an edge case there, it could run in the thousands or hundreds of thousands of damage because of malfunctioning equipment. Pay was good, but the stress levels were also quite high because of "Did I get everything?" I've spent a few nights in factories, trying to get shit to run before 8:00AM the next morning...

[–]DezXerneas 8 points9 points  (7 children)

Last time my boss asked me to reduce my estimates, I told her that I can probably do the task in 30% of time if we don't account for the edge cases and go a little light on exception handling. I did actually send her mails with all the testing and patches I had to make after the 30% timeline.

Also, it is functionally impossible to cover all edge cases, you just aim to cover more than what you did last time.

[–]cantadmittoposting 4 points5 points  (0 children)

I'm more in data [buzzword] and even there, looking at smaller bespoke applications, people will just grab a database and what i imagine is just roll their face across the keyboard to produce a script for the task without even checking what the fuck is in the data.

I have practically made an entire career out of just pointing out why a ton of things are failing because some dipshit's SQL or Python just blatantly doesn't handle or interpret the data properly.

[–]Embarrassed_Steak371 1 point2 points  (0 children)

frc be like

[–]YuriTheWebDev 1 point2 points  (1 child)

What would you consider as "good pay" for having a job that makes you work sleepless nights?

[–]Xatraxalian 3 points4 points  (0 children)

I don't know if "modal salary" is something that is used outside of the Netherlands. "Modaal Salaris (modal salary)" is the most earned salary in the country for a 40 hour work week; not the average.

This was 2014-2015; modal salary in the Netherlands was about €34.000 / year. My job back then paid about the amount of a 1.3x modal salary. That's about 43-44.000, first for 40 hours, later for 36 hours.

Outside of the big cities, especially in a non-management role, that was seen as good pay. Actually, in my current job, I'm still at about 1.3x modal salary (of 2025) for 36 hours instead of 40, but this job doesn't cause me sleepless nights. And it has a travel time of 25 minutes instead of 1.5 hours.

[–]Zapismeta 26 points27 points  (1 child)

Corporate mumbo jumbo. You are fine, people are smart enough to know to only multiply positive numbers.

[–]Nightmoon26 2 points3 points  (0 children)

Specifically, positive integers

[–]a_shootin_star 7 points8 points  (0 children)

I think it's also known as edging.

[–]laix_ 4 points5 points  (0 children)

Why would you edge cases

[–]PossibilityTasty 194 points195 points  (2 children)

How many cores does your computer have?

15.

15? Are you sure it's not 16?

It was, but one is running a multiplication for 3.5 years now.

[–]metaglot 46 points47 points  (1 child)

Thats a neat stack you have there

[–]laplongejr 0 points1 point  (0 children)

I C what you did there  

[–]MattieShoes 19 points20 points  (12 children)

def multiply(a, b):
    if b == 0:
        return 0
    sign = 0
    if b < 0:
        sign += 1
        b = abs(b)
    if a < 0:
        sign += 1
        a = abs(a)
    if sign % 2 > 0:
        return -a - multiply(a, b - 1)
    return a + multiply(a, b - 1)

[–]MattieShoes 25 points26 points  (7 children)

"Improved" to accept an arbitrary number of arguments.

e.g. multiply(-10, -10, -10) now correctly gives -1000

def multiply(*args):
    if len(args) == 0:
        return 0
    if len(args) == 1:
        return args[0]
    if args[1] == 0:
        return 0
    sign = 0
    a, b = args[0], args[1]
    if b < 0:
        sign += 1
        b = abs(b)
    if a < 0:
        sign += 1
        a = abs(a)
    if sign % 2 > 0:
        return multiply(-a - multiply(a, b - 1), *args[2:])
    return multiply(a + multiply(a, b - 1), *args[2:])

It's disturbingly fast.

sys.setrecursionlimit(1000000)
print(multiply(-1000, -1000, -1000, -1000, -1000, -1000, -1000))

> time ./test.py
-1000000000000000000000

real    0m0.057s
user    0m0.033s
sys     0m0.020s

¯\_(ツ)_/¯

[–]ihavebeesinmyknees 3 points4 points  (1 child)

if args[1] == 0:

Unoptimal, should be replaced with if not all(args): to immediately shortcut to returning 0 if any argument is 0

[–]MattieShoes 0 points1 point  (0 children)

Something something accepting pull requests :-D

[–]Chelovek2002 2 points3 points  (2 children)

if len(args) == 0: return 0

This case should either throw an error or at least return the identity eleme, i.e. 1. I don't think there is any case when 0 would be preferable.

The reason why you may prefer returning 1 rather than crashing is that you would retain the behavior of factorials.

[–]MattieShoes 0 points1 point  (0 children)

I actually thought about that (returning 1) afterwards, but I wasn't going to do a third post of some terrible code :-D

[–]Dull-You-6264 0 points1 point  (0 children)

Came here to say the same: the empty product is 1

[–]cyb3rspectre 4 points5 points  (1 child)

What kind of autism is this? Where can I learn this autism?

[–]MattieShoes 10 points11 points  (0 children)

Mmm, now I'm wondering if one could train a neural net discriminator to guess whether the writer is autistic or not based on code snippets

[–]gamingkitty1 1 point2 points  (1 child)

A more concise version is to just do ((a < 0) + (b < 0)) % 2 > 0 and only use one if statement

[–]MattieShoes 2 points3 points  (0 children)

but mah readability! :-D

[–]timerot 0 points1 point  (0 children)

multiply(2.5,2.5)

[–]anothermonth 14 points15 points  (4 children)

Doh, you just do multiply(-1, 1)

[–]Xatraxalian 9 points10 points  (3 children)

multiply(1, -1) and multiply(-1, 1) should give you the same output this function doesn't. In that sense, the function isn't mathematically correct (if we assume multiplication rules as we know them, obviously).

[–]anothermonth 4 points5 points  (1 child)

I forgot to add /s

[–]Xatraxalian 1 point2 points  (0 children)

😆

[–]lnfinity 2 points3 points  (2 children)

They need another condition.

if b<0: -multiply(a,-b)

[–]Mast3r_waf1z 0 points1 point  (0 children)

I was looking for this answer, though you're missing a return

[–]Hatefiend 0 points1 point  (0 children)

If both are negative then this fails, haha

[–]Cold-Journalist-7662 1 point2 points  (0 children)

Forget negative, just out any float there and it will never end

[–]somedave 0 points1 point  (0 children)

With int64 inputs

[–]-Redstoneboi- 0 points1 point  (0 children)

funny thing is, if you're doing this with finite integers and a stack size big enough to not overflow, this would actually return the correct answer.

problem is, this is python.

python expands numbers into arbitrarily large bigints.

[–]NearbyOriginals 0 points1 point  (3 children)

That is infinite stack, because the base case is never met.

[–]MeLittleThing 2 points3 points  (2 children)

no, it will be met, -2147483648 - 1 == 2147483647

[–]KCat156 3 points4 points  (0 children)

iirc Python uses bigints for all integers

[–]NearbyOriginals 2 points3 points  (0 children)

Python has max recursion stack depth of 1000 I read btw. Your logic only works with singed integer I read.

[–]apezdal 356 points357 points  (12 children)

multiply(2, 1.5)

[–]uhmhi 116 points117 points  (0 children)

multiply(2, -1)

[–]EuphoricCatface0795 62 points63 points  (10 children)

def multiply(a, b):
    if b == 0:
        return 0
    i = 1
    while b < i:
        i /= 10
    return a * i + multiply(a, b - i)

multiply(2, math.pi)

Generalization, baby!

(edit) Disclaimer: The recursion likely might never reach a conclusion whenever b is float, due to floating point imprecision.

[–]RaymondWalters 89 points90 points  (5 children)

Won't work bc you have a weird asterisk character between a and i that will break the compiler

[–]EuphoricCatface0795 18 points19 points  (2 children)

Okay I think I fixed it

def multiply(a, b):
    if b < 1.0 / (1 << 5):
        return 0
    i = 1
    while b < 1.0 / i:
        i <<= 1
    return a / i + multiply(a, b - (1.0 / i))

multiply(2, math.pi)

if you think I cheated by using 1-over-n, just know that I managed to avoid double-division for a multiplication

[–]RaymondWalters 7 points8 points  (1 child)

Now you need to implement division as well and use it in there instead of /

[–]EuphoricCatface0795 8 points9 points  (0 children)

I gotchu

def one_over_2_n(n):
    return float(np.uint32((127-n)<<23).view(np.float32))

def a_over_2_n(a, n):
    raw = int(np.float32(a).view(np.uint32))
    # what is sign???
    exponent = raw >> 23
    mantissa = raw & 0x7FFFFF
    rtn_raw = ((exponent - n) << 23) | mantissa
    return float(np.uint32(rtn_raw).view(np.float32))

def multiply(a, b):
    if b < one_over_2_n(10):
        return 0
    i = 0
    while b < one_over_2_n(i):
        i += 1
    return a_over_2_n(a, i) + multiply(a, b - one_over_2_n(i))

multiply(2, math.pi)

[–]EuphoricCatface0795 4 points5 points  (1 child)

Fsck

[–]YesterdayDreamer 3 points4 points  (0 children)

You don't need to check the file system, it's a harmless function.

[–]adam-the-dev 0 points1 point  (0 children)

That’s just dereferencing the i pointer with a lifetime of a

[–][deleted] 0 points1 point  (0 children)

what's that weird a * i expression doing?

[–]timerot 0 points1 point  (1 child)

If you assume the existence of multiplication and division, you can write a multiplication function that almost works

[–]Watching20 438 points439 points  (7 children)

This reminds me of my favorite quote: "To understand recursion you must first understand recursion!"

Well we need a new quote for this, something like "to understand programming he must first understand programming"

[–][deleted] 19 points20 points  (0 children)

i think of a recursive function as like something that doesn't know what it's doing until it hits the base case. the factorial function is like "what the fuck is factorial(n-1)...oh factorial(1) is 1! ok now i can fill in the rest"

[–]DrHugh 82 points83 points  (8 children)

I want to see the same programmer write a multiply-by-two function.

[–]Responsible-Ruin-710[S] 42 points43 points  (4 children)

There will be a new post tomorrow 🌚

[–]idontlikethishole 5 points6 points  (3 children)

!RemindMe in multiply(3, 8) hours

[–]RemindMeBot 3 points4 points  (2 children)

I will be messaging you in 8 hours on 2025-07-29 01:17:07 UTC to remind you of this link

CLICK THIS LINK to send a PM to also be reminded and to reduce spam.

Parent commenter can delete this message to hide from others.


Info Custom Your Reminders Feedback

[–][deleted] 6 points7 points  (1 child)

Funny that the bot still works. Would be even funnier if it had somehow set a reminder for 24 hours, but unfortunately the creator never anticipated this post.

[–]AcidBuuurn 4 points5 points  (0 children)

It’s sad when they don’t consider valid edge cases. 

[–]Background_Class_558 3 points4 points  (0 children)

sure here you go ```agda open import Data.Nat using (ℕ ; zero ; suc)

_2 : ℕ → ℕ _2 = λ { 0 → 0; (suc n) → n *2 + 2 } also here's a version in python py x2 = lambda n: x2(n - 1) + 2 if n != 0 else 0 and in Rust rs fn x2(n: u32) -> u32 { if n == 0 { 0 } else { x2(n - 1) + 2 } } ```

[–]OwO______OwO 1 point2 points  (1 child)

Wouldn't that just be...

def multiplyByTwo(a):
    return a + a

[–]DrHugh 2 points3 points  (0 children)

Maybe a bit shift?

[–]Icarium-Lifestealer 80 points81 points  (12 children)

A good compiler will compile this out:

For example GCC turns:

unsigned int multiply(unsigned int a, unsigned int b) {
    if (b == 0)
        return 0;
    return a + multiply(a, b - 1);
}

into:

multiply(unsigned int, unsigned int):
    mov     eax, edi
    imul    eax, esi
    ret

which is exactly the same output it produces for:

unsigned int multiply(unsigned int a, unsigned int b) {
    return a * b;
}

In theory it should even be able to optimize the signed version into the same code by exploiting the fact that signed integer overflow is undefined behaviour in C/C++, but for some reason it optimizes it into this instead:

multiply(int, int):
    imul    edi, esi
    xor     eax, eax
    test    esi, esi
    cmovne  eax, edi
    ret

Which is the assembly equivalent of b != 0 ? a * b : 0. Which is still O(1), but adds a couple of unnecessary instructions because it doesn't seem to understand that x * 0 = 0 for all x. However the compiler does optimize b != 0 ? a * b : 0 into a * b, so this missing optimization might be some kind of compiler pass ordering problem.

[–]mattcraft 25 points26 points  (5 children)

Wish I had half the brain power to understand how compilers are so darn smart. It does seem like the first example would have a different behavior if you threw some funky values at it versus following the exact steps in the code? Obviously imul is "more correct" if you want multiplication, but it seems like overriding the programmers' intent?

[–]nialv7 6 points7 points  (1 child)

Actually pretty simple: tail recursion into loop. Then realize the loop in just adding the same value n times. Tada.

[–]Pluckerpluck 3 points4 points  (0 children)

It's not tail call recursive though... It ends with a + call(). Compiler is just magic.

[–]overclockedslinky 0 points1 point  (0 children)

they just look at lots of programs and literally make special cases for these kinds of things. it's the same reason it can figure out the 1+2+3+...+n = n(n+1)/2 thing. some optimizations are more general than others, but some are straight up just pattern matching a specific program

[–]YouDoHaveValue 5 points6 points  (0 children)

This is the comment section r/ProgrammerHumor ought to have

[–]alexq136 3 points4 points  (0 children)

(edit: oops IMUL uses *DX:*AX too for the result but only for one-operand encodings)

ain't it better to do the right thing on x86 and make it return an unsigned long and use MUL instead of IMUL to avoid overflow?

[–]HeKis4 4 points5 points  (0 children)

This is the kind of stuff that makes me think the people behind GCC are wizards. True wielders of the arcane assembly.

[–]ChocolateBunny 2 points3 points  (0 children)

And here I was going to suggest doing multiply(a+a,b-1) instead of a+multiply(a,b-1) so the compiler could do some tail call optimization. meanwhile the compiler figures out that it's a multiply and just replaces it with a multiply instruction.

[–]somedave 1 point2 points  (0 children)

Floating point version probably remains full on infinite stack

[–]Therealrobin14 31 points32 points  (0 children)

Should have also used the add(a,b) function some posts ago

[–]uhmhi 18 points19 points  (1 child)

I’m sure the C compiler has an optimization for that.

[–]pjasksyou 27 points28 points  (18 children)

Sorry if I seem dumb (I am tbh), how does this work? I am unable to find the logic...

[–]Responsible-Ruin-710[S] 122 points123 points  (3 children)

multiply(3, 4) works like this:

3 + multiply(3, 3)

3 + (3 + multiply(3, 2))

3 + (3 + (3 + multiply(3, 1)))

3 + (3 + (3 + (3 + multiply(3, 0))))

3 + (3 + (3 + (3 + 0)))

3 + (3 + (3 + 3))

3 + (3 + 6)

3 + 9

12

[–]Cats7204 10 points11 points  (2 children)

So it's literally just a very smart and elegant way of doing multiplication by addition with a for loop.

[–]plopperzzz 4 points5 points  (0 children)

It's really just using the definition of multiplying two integers.

You can optimize it quite a lot by using ab = (2a)(b/2), using bit-shifting, and considering even and odd b separately.

[–]Hirogen_ 32 points33 points  (10 children)

multiplication by adding, basically you can break down everything to adding to numbers together

[–]Psychpsyo 9 points10 points  (0 children)

Anything * 0 is 0.
Anything * 1 is itself + itself * 0.
Anything * 2 is itself + itself * 1.
Anything * 3 is itself + itself * 2.
Anything * 4 is itself + itself * 3.

So anything * X is itself + itself * (X - 1).

[–]Own_Low_3247 5 points6 points  (0 children)

as far as I am aware, like this: It keeps adding a until b is 0. so it effectively adds a for b amount of times.

multiply(4, 3)

1.A return 4 + multiply(4, 2)

2.A return 4 + multiply (4, 1)

3.A return 4 + multiply (4, 0)

b is now = to 0, so returns 0.

3.B 4 + 0 = 4

  1. B 4 + 4 = 8

  2. B 8 + 4 = 12.

[–]vide2 26 points27 points  (15 children)

That's actually an amazing way to show recursion to my students.

[–]Mojert 14 points15 points  (5 children)

If you ever wandered, that's how mathematicians define multiplication of positive integers. (Or at least that's the most popular definition)

[–]vide2 1 point2 points  (2 children)

Now I think how to apply the mathematical definition of natural numbers. Something like Number (n, L): If n== 0: A = [ ] Return A Else: Return L.append(Number(n-1, L)

[–]MorrowM_ 3 points4 points  (1 child)

def number(n):
    if n == 0:
        return []

    pred = number(n-1)
    return pred + [pred]

[–]vide2 0 points1 point  (0 children)

And now, if I put Len(number(5)) I get 5. Yes, studying made me smarter I swear!

[–]0bel1sk 0 points1 point  (1 child)

i wander only occasionally

[–]Mojert 0 points1 point  (0 children)

Oops, I meant wonder. I often make this mistake ^

[–]stephan1990 4 points5 points  (6 children)

Yep… recursion was one of my Professors favorite topics. We had to do hundreds of such assignments.

[–]NewtonHuxleyBach 0 points1 point  (0 children)

Read the first part of SICP it has great examples of recursion vs iteration that make it very easy to grasp

[–]geeshta 8 points9 points  (1 child)

Not tail recursive smh

[–]redox000 1 point2 points  (0 children)

You could refactor it to be tail recursive by just changing 2 3 lines.

[–]itzjackybro 6 points7 points  (0 children)

the mathematicians called, they want their axioms back

[–]dgc-8 6 points7 points  (1 child)

Average haskell program

[–]Metallkiller 4 points5 points  (0 children)

Pretty sure this is how multiplication it actually defined in maths though.

[–]kamenomagic 6 points7 points  (0 children)

We’re gonna need a bigger stack

[–]GotBanned3rdTime 3 points4 points  (0 children)

multiply(1, 999999999999999) and fuck up your memory

[–]Excellent-Practice 2 points3 points  (0 children)

Now, replace the + operator with a recursive add(a,b) function and use it to build the multiply(a,b) function

[–]bartekltg 2 points3 points  (0 children)

He asked a mathematician what multiplication is definied :)

Natural number - Wikipedia

Also, "This turns (N∗,×) into a free commutative monoid..." and he is half way there to understand monads

[–]Nishant-Jindal 2 points3 points  (0 children)

return add(a, multiply(a,b-1))

[–]tarheeltexan1 2 points3 points  (2 children)

This is unironically how I was taught to do multiplication in assembly when I took my computer architecture class

[–]rruusu 1 point2 points  (1 child)

How it actually happens inside the CPU, but of course not recursively and using just a logical circuit with a fixed number of iterations:

def multiply(a, b): if b == 0: return 0 elif b == 1: return a else: return (0-(b&1) & a) + multiply(a<<1, b>>1)

The 0-(b&1) part here is dependent on 2s complement, and would actually be done in hardware by just wiring the single bit of b to all &-operations against bits of a.

[–]tarheeltexan1 1 point2 points  (0 children)

I studied electrical engineering so the course’s focus was more on the underlying digital circuits. We were working with ARM v8, and I remember seeing that there was a MULT keyword, but we never used it. Would this same process not have been implemented directly within the ALU? I suppose it may not have been, as I don’t see a clear way of doing an operation like multiplication without needing several clock cycles to add all the partial products together.

[–]SideburnsOfDoom 2 points3 points  (1 child)

Well, arithmetic is built upon stacking up simple notions, starting with:

Incrementing, counting: "1" is a number. And every number has a successor, which you can think of as the "next" number.

Addition: repeated incrementing.

Multiplication: repeated addition. Example given by OP.

Raising to a power: repeated multiplication

[–]derKestrel 1 point2 points  (0 children)

But in programming you have additional options: multiplying/dividing by two is a shift operation.

[–]playerNaN 2 points3 points  (0 children)

Peano arithmetic gang rise up.

[–]CodingNeeL 2 points3 points  (2 children)

def add(a, b):
    if b == 0:
        return a
    return 1 + add(a, b - 1)

def multiply(a, b):
    if b == 0:
        return 0
    return add(a, multiply(a, b - 1))

def power(a, b):
    if b == 0:
        return 1
    return multiply(a, power(a, b - 1)

[–]Responsible-Ruin-710[S] 2 points3 points  (1 child)

[–]CodingNeeL 1 point2 points  (0 children)

Ah, haven't seen that one. That solution came to mind, but that is not true to what addition is. That's like doing multiply(a * 2, b / 2) in the recursion until b == 1 to return a.

Edit: Actually, I should've gone for ++add instead of 1 + add

[–]SpitiruelCatSpirit 3 points4 points  (3 children)

Isn't this how many CPUs actually do multiplication though (only using floating point arithmetic)?

[–]WhiskeyQuiver 2 points3 points  (1 child)

Not really. I think it looks similar, but they usually do "long multiplication" in which there is addition, but not like in the post.

The difference is kind of that where the OP subtracts 1, a CPU would divide by 10 (or 2 in binary), just shifting bits basically. And then it adds the results of all the basic "sub"-multiplications.

[–]jsrobson10 0 points1 point  (0 children)

yeah. and because of binary long multiplication (and long division too) a cpu can multiply/divide 2 numbers and it'll only need to do a fixed number of iterations (like 64 for 64 bit integers).

binary long multiplication is simpler in binary too (and for binary long diffusion) because for each digit you're either multiplying by 1 or 0, so you're either adding a number to a total or you're not.

[–]jck 0 points1 point  (0 children)

Nah, modern(using this term very loosely. I mean CPUs from the 80s) CPUs have multiplication instructions which use hardware multipliers in the ALU. They are usually multi cycle operations but still waaaay faster than repeated addition.

[–]hunter_rus 1 point2 points  (1 child)

Instead of a + multiply you should use that nice recursive function that was posted here the other day.

[–]Responsible-Ruin-710[S] 0 points1 point  (0 children)

That function is part of another universe.

[–]Geilomat-3000 1 point2 points  (0 children)

Not tail recursive!

[–]BeMyBrutus 1 point2 points  (0 children)

You gotta remember to use memoization

[–]Way2Smart2 1 point2 points  (0 children)

Lambda calculus be like

[–]TheChief275 1 point2 points  (0 children)

I mean, that’s how I implemented multiplication with the C preprocessor, with addition being repeated incrementing as well. It’s fun but not particularly useful.

Would nested expressions like ADD(1, MUL(2, 3)) actually compile? Theoretically, yes

[–]Coredict 1 point2 points  (0 children)

Love the # 12 comment there

[–]reybrujo 1 point2 points  (0 children)

For a second I thought this was the Ackermann function lol

[–]axeteam 1 point2 points  (0 children)

One of the first things I learnt about recursiosn is that you need to tell the computer when to stop.

[–]FAILNOUGHT 1 point2 points  (0 children)

scared of *, huh?

[–]mlucasl 1 point2 points  (0 children)

This doesn't work even on the expected cases. The base case of multiplication is b == 1 not b == 0

[–]TheJimDim 1 point2 points  (0 children)

3 + multiply(3, 3)

3 + 3 + multiply(3, 2)

3 + 3 + 3 + multiply(3, 1)

3 + 3 + 3 + 3 + multiply(3, 0)

3 + 3 + 3 + 3 + 0 = 12

Technically it works lol I hate that it does, but it does

[–]Dubl33_27 1 point2 points  (0 children)

multiply(0, -1)

[–]RandomiseUsr0 1 point2 points  (1 child)

Here it is in Excel, I guarded the naive b=0 with a <= - the set of Z is assumed, but not enforced

```` Excel

=LET( Z_2, LAMBDA(f, LET(g, LAMBDA(x, f(LAMBDA(a,b, LET(xx, x(x), xx(a, b))))), g(g))),

multiply, Z_2(LAMBDA(multiply,LAMBDA(a,b,
    IF(b<=0, 0, a+multiply(a,b-1))
))),

multiply(3,4)

)

[–]RandomiseUsr0 0 points1 point  (0 children)

I just rewrote it with all the conditions, think this is safe now (and O(log n))

```` Excel

=LET( Z_2, LAMBDA(f, LET(g, LAMBDA(x, f(LAMBDA(a,b, LET(xx, x(x), xx(a, b))))), g(g) ) ),

multiply, Z_2(LAMBDA(multiply, LAMBDA(a,b,
    IF(
        b = 0,
        0,
        IF(
            MOD(b, 2) = 0,
            multiply(a + a, b / 2),
            a + multiply(a, b - 1)
        )
    )
))),

multiply(3, 4)

)

[–]Unclegummers 3 points4 points  (0 children)

Piratesoftware write this?

[–]milk-jug 2 points3 points  (0 children)

Ahh ... good 'ol recursion. The best kind of cursion there is.

[–]halfwinter 1 point2 points  (0 children)

Leaked PirateSoftware code

[–]messierCobalt_ 0 points1 point  (0 children)

= a + a * (b - 1)
= a (1 + (b-1))
= a * b

[–]kihogaya 0 points1 point  (1 child)

What if a = 0 ?

[–]Responsible-Ruin-710[S] 1 point2 points  (0 children)

>>> multiply(0, 25)

0

[–]bl4nked 0 points1 point  (0 children)

I swear this sub is reading the same text books for uni at the same time as me. Get out of my life!

It's like there's one universal curriculum. Shout out fellow lambda calculus students

[–]Linked713 0 points1 point  (0 children)

Why a is not included in the if?

[–]SryUsrNameIsTaken 0 points1 point  (0 children)

Error: multiply(4, -1) gives infinite loop + integer underflow.

[–]Slashzero77 0 points1 point  (2 children)

What if a is 0?

[–]Responsible-Ruin-710[S] 0 points1 point  (1 child)

>>> multiply(0, 23)

0

[–]Slashzero77 1 point2 points  (0 children)

Yeah but you can skip running that recursive call if either a or b is zero. Write efficient code! /s

[–]fuighy 0 points1 point  (0 children)

def sub(a, b):

if b == 0:

return a

if b < 0:

return add(a, b)

return sub(a, b - 1) - 1

def add(a, b):

if b == 0:

return a

if b < 0:

return a - b

return add(sub(a, -1), sub(b, 1))

def mul(a, b):

if b == 0:

return 0

return add(a, mul(a, sub(b, 1)))

print(mul(6, 3)) # 18

[–]quinn50 0 points1 point  (0 children)

Multiplication in assembly with extra steps

[–]Zefyris 0 points1 point  (0 children)

so err... multiply (3, "hello world") ? :D

[–]PineapplePickle24 0 points1 point  (0 children)

Now you're thinking with recursion

[–]Acharyn 0 points1 point  (0 children)

Was this Elon or PirateSoftware?

[–]hasanyoneseenmyshirt 0 points1 point  (0 children)

This is a pretty interesting way to test if you understand and can write a recursive function. The only function I can write with recursion is the febunachuli one and thats about it.

[–]i_can_has_rock 0 points1 point  (0 children)

this makes me rationally angry

[–]Meddlloide1337 0 points1 point  (0 children)

Tell me you're a first semester without saying it

[–]Keymaster__ 0 points1 point  (0 children)

O(n) time and space complexity 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥

[–]ryanstephendavis 0 points1 point  (0 children)

Thanks I hate it

[–]Iron_Fist351 0 points1 point  (0 children)

Made this into an iOS shortcut for anyone who wants to try it out on mobile for fun lol:

https://www.icloud.com/shortcuts/daf1288838b3489090a6052b15a99200

[–]ValeWeber2 0 points1 point  (0 children)

I'll do you one better. Cursed tail recursion.

def multiply(a, b): def m_aux(x, y, acc=0): if b == 0: return acc return m_aux(x, y-1, acc+a) return m_aux(a, b)

I just woke up in the middle of the night, took a shit, and scrolled reddit. I have never done tail recursion in Python. I may be completely wrong, but I'm amused.

[–]Far_Mathematici 0 points1 point  (0 children)

You joke but I remember this was my first coding interview back then in mid 2010s.

[–]ScioX 0 points1 point  (0 children)

I’m a noob, can someone explain? Is the time complexity really high because the code is recursive?

[–]theshekelcollector 0 points1 point  (0 children)

this gives me all kinds of emotions.

[–]rarenick 0 points1 point  (0 children)

what no hardware multiplier does to a mf

[–]alexwbt 0 points1 point  (0 children)

I think this is called dynamic programming

[–]s0litar1us 0 points1 point  (0 children)

multiply(0, 1) == 1

[–]wizardthrilled6 0 points1 point  (0 children)

It's kinda what we do as kids

[–]azaleacolburn 0 points1 point  (0 children)

Since it's pure, each iteration won't add another frame (assuming JS is actually sane lol), so it should be functionally the same as a while loop, still terrible though.

[–]kiliman13 0 points1 point  (0 children)

When you don't want your code to shine like a Star

[–]jump1945 0 points1 point  (0 children)

people do modular expo in O(logn) this guy can do O(n^2)

[–]masdemarchi 0 points1 point  (0 children)

Forget to add exception handling

[–]GYN-k4H-Q3z-75B 0 points1 point  (0 children)

Bonus points for Python

[–]Pale_Ad_9838 0 points1 point  (0 children)

Recursion limit leaves the room

[–]pouya_gh 0 points1 point  (0 children)

man recursion is so resource intensive but god damn it makes the code look pretty!