35
\$\begingroup\$

Your task is to write some code in Python 2 or 3 such that this expression:

(a+b)(c+d) == a*c + b*c + a*d + b*d

will evaluate to True without raising any exceptions.

To clarify, I will copy your code into a file, then from the file import *. Then I will type the expression into the console and verify that it is True.

This is code-golf, so the answer with the shortest length (in bytes) wins.

\$\endgroup\$
20
\$\begingroup\$

54 52 50 49 48 45 39 bytes

Removed 4 bytes thanks to Dennis.

The latest version is inspired by the "some reason" in xnor's answer.

class t(int):__add__=type
a=b=t()
c=d=0
\$\endgroup\$
  • \$\begingroup\$ Nice! There's 0 .__mul__ for lambda y:0 but it's the same length. \$\endgroup\$ – xnor Oct 28 '16 at 23:28
  • \$\begingroup\$ x.count saves a byte. \$\endgroup\$ – Dennis Oct 28 '16 at 23:36
  • 1
    \$\begingroup\$ I don't get it... type(t(), t()) or t().type(t()) throws an exception, so what is happening when you do t() + t()? \$\endgroup\$ – feersum Oct 29 '16 at 3:56
  • 1
    \$\begingroup\$ @feersum __add__ is called with two, but the first is interpreted as self, only other is passed to type. Weird, yes. \$\endgroup\$ – Jonathan Allan Oct 29 '16 at 10:12
  • 1
    \$\begingroup\$ @feersum: a + b first tries a.__add__(b). a.__add__ is type, so that becomes type(b). The key difference between this case and the usual case for methods is that usually, a.__add__ would be a different object from the thing you set __add__ to in the class definition, due to the descriptor protocol, which ordinary function objects implement. (There are also a few other tricky bits that aren't relevant here.) \$\endgroup\$ – user2357112 Oct 29 '16 at 18:25
10
\$\begingroup\$

54 bytes

class m(int):__call__=__add__=lambda*x:m()
a=b=c=d=m()

Make an object that inherits from int, except adding or calling just returns a copy of itself.

Same length:

class m(int):__call__=__add__=lambda a,b:a
a=b=c=d=m()

I thought min or {}.get would work in place of lambda a,b:a, but for some reason they act only on the second argument.

\$\endgroup\$
  • 1
    \$\begingroup\$ (it's code-golf) \$\endgroup\$ – Addison Crump Oct 28 '16 at 23:10
  • 1
    \$\begingroup\$ Oops, I only saw programming-puzzle, will golf. \$\endgroup\$ – xnor Oct 28 '16 at 23:11
  • 3
    \$\begingroup\$ That was quite a reduction o-o \$\endgroup\$ – Addison Crump Oct 28 '16 at 23:19
  • \$\begingroup\$ @xnor It doesn't work because min already has a __self__ attribute, so the class skips binding its own self. Why min has __self__ is another question... \$\endgroup\$ – matsjoyce Oct 29 '16 at 19:00
  • \$\begingroup\$ @matsjoyce: No, it doesn't have anything to do with the fact that min has a __self__. min.__self__ is just an artifact of how built-in functions and built-in methods are implemented as the same type. min doesn't work here because unlike functions written in Python, built-in functions don't support the descriptor protocol, which is responsible for binding the first argument. \$\endgroup\$ – user2357112 Oct 30 '16 at 1:07
3
\$\begingroup\$

81 66 bytes

class e:__mul__=lambda*o:0;__add__=lambda*o:lambda x:0
a=b=c=d=e()
\$\endgroup\$
1
\$\begingroup\$

68 bytes

While it cannot really compete with the existing answers, this one actually performs the calculation in question:

from sympy.abc import*
type(a+b).__call__=lambda x,y:(x*y).expand()

Explanation:

  • SymPy is a module for symbolic computations.
  • sympy.abc contains all single-letter symbols, in particular ones named a, b, c, and d.
  • a+b is an Add object, which represents a general sum.
  • type(a+b).__call__= […] monkey-patches the Add class to give it evaluation capabilities, in this case enabling it to work like a multiplication of caller and callee.
  • expand is necessary to make the expressions actually equal (since SymPy only performs thorough equality checks on demand).
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.