Task[edit]
Solve the "Impossible Puzzle":


X and Y are two different whole numbers greater than 1. Their sum is no greater than 100, and Y is greater than X. S and P are two mathematicians (and consequently perfect logicians); S knows the sum X+Y and P knows the product X*Y. Both S and P know all the information in this paragraph.
The following conversation occurs:

 S says "P does not know X and Y."
 P says "Now I know X and Y."
 S says "Now I also know X and Y!"
What are X and Y?


Guidance
It can be hard to wrap one's head around what the three lines of dialog between S (the "sum guy") and P (the "product guy") convey about the values of X and Y.

So for your convenience, here's a break-down:





 Quote

 Implied fact


 1)

 S says "P does not know X and Y."

 For every possible sum decomposition of the number X+Y, the product has in turn more than one product decomposition.


 2)

 P says "Now I know X and Y."

 The number X*Y has only one product decomposition for which fact 1 is true.


 3)

 S says "Now I also know X and Y."

 The number X+Y has only one sum decomposition for which fact 2 is true.

Terminology:

 "sum decomposition" of a number = Any pair of positive integers (A, B) so that A+B equals the number. Here, with the additional constraint 2 ≤ A < B.
 "product decomposition" of a number = Any pair of positive integers (A, B) so that A*B equals the number. Here, with the additional constraint 2 ≤ A < B.


Your program can solve the puzzle by considering all possible pairs (X, Y) in the range 2 ≤ X < Y ≤ 98, and then successively eliminating candidates based on the three facts. It turns out only one solution remains!

See the Python example for an implementation that uses this approach with a few optimizations.

See also
   Wikipedia:   Sum and Product Puzzle

with javascript_semantics
function satisfies_statement1(integer s)
-- S says: P does not know the two numbers.
-- Given s, for /all/ pairs (a,b), a+b=s, 2<=a,b<=99, at least one of a or b is composite
    for a=2 to floor(s/2) do
        if is_prime(a) and is_prime(s-a) then
            return false
        end if
    end for
    return true
end function
 
function satisfies_statement2(integer p)
-- P says: Now I know the two numbers.
-- Given p, for /all/ pairs (a,b), a*b=p, 2<=a,b<=99, exactly one pair satisfies statement 1
    bool winner = false
    for i=2 to floor(sqrt(p)) do
        if mod(p,i)=0 then
            integer j = floor(p/i)
            if 2<=j and j<=99 then
                if satisfies_statement1(i+j) then
                    if winner then return false end if
                    winner = true
                end if
            end if
        end if
    end for
    return winner
end function
 
function satisfies_statement3(integer s)
-- S says: Now I know the two numbers.
-- Given s, for /all/ pairs (a,b), a+b=s, 2<=a,b<=99, exactly one pair satisfies statements 1 and 2
    integer winner = 0
    if satisfies_statement1(s) then
        for a=2 to floor(s/2) do
            if satisfies_statement2(a*(s-a)) then
                if winner then return 0 end if
                winner = a
            end if
        end for
    end if
    return winner
end function
 
for s=2 to 100 do
    integer a = satisfies_statement3(s)
    if a!=0 then
        printf(1,"%d (%d+%d)\n",{s,a,s-a})
    end if
end for
