Created
May 5, 2015 20:25
-
-
Save gabegaster/904e34a68f4e1893b0e0 to your computer and use it in GitHub Desktop.
Mr S and Mr P: From http://programmingpraxis.com/2009/10/23/mr-s-and-mr-p/ and told to me by Mike Stringer. My answer in pure python.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""From http://programmingpraxis.com/2009/10/23/mr-s-and-mr-p/ and | |
told to me by Mike Stringer. John McCarthy, who discovered Lisp, | |
attributes this puzzle to Hans Freudenthal: | |
We pick two numbers a and b, so that 100>a,b>1. We tell | |
Mr. P. the product ab and Mr. S. the sum a+b. Then Mr. S. and | |
Mr. P. engage in the following dialog: | |
Mr. P.: I don't know the numbers. | |
Mr. S.: I knew you didn't know. I don't know either. | |
Mr. P.: Now I know the numbers. | |
Mr. S.: Now I know them too. | |
Find the numbers a and b. | |
Here is my answer -- in pure python. | |
Gabriel Gaster, 2015 | |
""" | |
def products(n, N=100): | |
return set(tuple(sorted((i,n/i))) for i in xrange(2,n/2+1) | |
if (n%i == 0) and 1<i<N and 1<n/i<N) | |
def sums(n, N=100): | |
return set(tuple(sorted((i,n-i))) for i in xrange(n) | |
if 1<i<N and 1<n-i<N) | |
def know(possibilities): | |
return len(possibilities)==1 | |
def a_and_b(N=100): | |
first = ((a,b) for a in xrange(2,N) for b in xrange(a,N) | |
if statement1(a*b, N=N)) | |
second = set((a,b) for a,b in first if statement2(a+b, N)) | |
third = set((a,b) for a,b in second | |
if statement3(a*b, second, N=N)) | |
fourth = [(a,b) for a,b in third | |
if statement4(a+b, third, N=N)] | |
return fourth | |
def statement1(p, N=100): | |
return not know(products(p, N=N)) | |
def statement2(s, N=100): | |
return not know(sums(s, N)) and all(statement1(a*b, N=N) | |
for a,b in | |
sums(s, N=N)) | |
def statement3(p, second, N=100): | |
return know(products(p, N=N) & second) | |
def statement4(s, third, N=100): | |
return know(sums(s, N=N) & third) | |
if __name__=="__main__": | |
N = 100 | |
the_numbers = a_and_b(N=N) | |
msg = "do" if know(the_numbers) else "do not" | |
print "we %s know the numbers <%i" % (msg, N) | |
print the_numbers | |
if know(the_numbers): | |
a,b = the_numbers.pop() | |
print "Nums:",a,b | |
print "Mr S: %i" % (a+b) | |
print "Mr P: %i" % (a*b) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment