FOIL Python frappe fort!

35

Votre tâche consiste à écrire du code en Python 2 ou 3 tel que cette expression:

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

évaluera à Truesans lever aucune exception.

Pour clarifier, je vais copier votre code dans un fichier, puis fromle fichier import *. Ensuite, je vais taper l'expression dans la console et vérifier que c'est bien le cas True.

C'est du code-golf, donc la réponse avec la longueur la plus courte (en octets) est gagnante.

Fruit d'esolanging
la source

Réponses:

20

54 52 50 49 48 45 39 octets

Suppression de 4 octets grâce à Dennis.

La dernière version est inspirée par "la raison" de la réponse de xnor.

class t(int):__add__=type
a=b=t()
c=d=0
jimmy23013
la source
Agréable! Il y a 0 .__mul__pour lambda y:0mais c'est la même longueur.
xnor
x.countenregistre un octet.
Dennis
1
Je ne comprends pas ... type(t(), t())ou t().type(t())jette une exception, alors qu'est-ce qui se passe quand vous faites t() + t()?
Feersum
1
@feersum __add__est appelé avec deux, mais le premier est interprété comme étant selfuniquement othertransmis à type. Bizarre, oui.
Jonathan Allan
1
@feersum: a + bpremiers essais a.__add__(b). a.__add__est type, alors ça devient type(b). La principale différence entre ce cas et le cas habituel pour les méthodes est qu'habituellement, il a.__add__s'agirait d'un objet différent de ce que vous avez défini __add__dans la définition de classe, en raison du protocole de descripteur , que les objets fonction ordinaires implémentent. (Il existe également quelques autres éléments délicats qui ne sont pas pertinents ici.)
user2357112 prend en charge Monica
10

54 octets

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

Faire un objet qui hérite de int, sauf que l'ajout ou l'appelant renvoie simplement une copie de lui-même.

Même longueur:

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

J'ai pensé minou {}.gettravaillerais à la place de lambda a,b:a, mais pour une raison quelconque, ils agissent uniquement sur le deuxième argument.

Xnor
la source
1
(c'est du code-golf )
Addison Crump
1
Oups, j'ai seulement vu programmation-puzzle , va jouer au golf.
xnor
3
C'était vraiment une réduction oo
Addison Crump
@xnor Cela ne fonctionne pas car il a mindéjà un __self__attribut, donc la classe ignore la liaison elle-même. Pourquoi mina- t __self__-il une autre question ...
matsjoyce
@matsjoyce: Non, ça n'a rien à voir avec le fait qu'il y mina un __self__. min.__self__est juste un artefact de la façon dont les fonctions intégrées et les méthodes intégrées sont implémentées dans le même type. minne fonctionne pas ici car, contrairement aux fonctions écrites en Python, les fonctions intégrées ne prennent pas en charge le protocole de descripteur, qui est responsable de la liaison du premier argument.
user2357112 prend en charge Monica
3

81 66 octets

class e:__mul__=lambda*o:0;__add__=lambda*o:lambda x:0
a=b=c=d=e()
Jonathan Allan
la source
1

68 octets

Bien qu'il ne puisse pas vraiment concurrencer les réponses existantes, celle-ci effectue le calcul en question:

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

Explication:

  • SymPy est un module de calcul symbolique.
  • sympy.abccontient tous les symboles d'une seule lettre, en particulier celles nommées a, b, cet d.
  • a+best un Addobjet qui représente une somme générale.
  • type(a+b).__call__= […]monkey corrige la Addclasse pour lui donner des capacités d'évaluation, lui permettant dans ce cas de fonctionner comme une multiplication de l'appelant et de l'appelé.
  • expand est nécessaire pour rendre les expressions réellement égales (puisque SymPy effectue uniquement des contrôles d’égalité approfondis à la demande).
Wrzlprmft
la source