GOPHERSPACE.DE - P H O X Y
gophering on sdf.org
Sum And Product Puzzle
======================
Knowing something just because someone says you don't. Isn't it amazing?
Two mathematicians are playing a game. P know the product of twdifferent
numbers both greater than 1 whose sum is no greater than 100. S knows
their sum.
S says: P does not know the numbers.
P says: Now I know.
S says: Now I also know the numbers.
Well, what are the numbers?

How to solve?
Here's a little Python script that solves the puzzle
# First step: create a dictionary of pairs grouped by their product

possiblePairsByProduct = {}

for i in range(2,50):
for j in range(i+1, 101-i):
if i==j:
continue
p=i*j
if p not in possiblePairsByProduct:
possiblePairsByProduct[p]={(i,j)}
else:

# S says that P doesn't know the numbers.

# Second step: remove products that has 1 pair of factors only

countPairsBySum = {}

for i in possiblePairsByProduct.keys():
if len(possiblePairsByProduct[i])==1:
possiblePairsByProduct.pop(i)

# Third step: create sums from the pairs in possiblePairsByProduct
for curSet in possiblePairsByProduct.values():
for pair in curSet:
sum = pair[0]+pair[1]
if sum not in countPairsBySum:
countPairsBySum[sum]=1
else:
countPairsBySum[sum]+=1

# Check from which of the sum S can tell that P
#   does not know the two numbers
for i in countPairsBySum.keys():
if i % 2:
results = i/2 - 1
else:
results = i/2 - 2
if countPairsBySum[i]!=results:
countPairsBySum.pop(i)

# Get  products for whose pairs only one sum exists,
#  and vice versa
pairsBySum={}

for i in possiblePairsByProduct.keys():
curSet=possiblePairsByProduct[i]
curSum = None
productRemoved=False
for pair in curSet.copy():
sum =pair[0]+pair[1]
if sum in countPairsBySum:
if curSum:
if not productRemoved:
possiblePairsByProduct.pop(i)
productRemoved=True
else:
curSum=sum
else:
curSet.remove(pair)
if not curSum:
possiblePairsByProduct.pop(i)
productRemoved=True
if not productRemoved:
if curSum not in pairsBySum:
pairsBySum[curSum]=curSet.copy()
else:
pairsBySum[curSum].update(curSet)

# There's only one sum for which there's one pair.
for sum in pairsBySum:
if len(pairsBySum[sum])==1:
print pairsBySum[sum]

This will print:
set([(4, 13)])