Skip to content

Instantly share code, notes, and snippets.

@gabegaster
Created May 5, 2015 20:25
Show Gist options
  • Save gabegaster/904e34a68f4e1893b0e0 to your computer and use it in GitHub Desktop.
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.
"""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