|  | 
	The solution follows the form feed ...
	the only solution is the two numbers: 4 and 13;
	the following BLISS program can be compiled and link and run
	to yield the result.  hopefully the logic in the code is
	understandable enough whether you know bliss or not.
-------------------------------------------------------------------------------
MODULE a (	MAIN = a_main,
		ADDRESSING_MODE(EXTERNAL = LONG_RELATIVE,
		NONEXTERNAL = LONG_RELATIVE)) =
BEGIN
LIBRARY	'sys$library:starlet';
MACRO desc(name, buffer, size) =
    buffer : vector[size,byte],
    name : block[8, byte]
	preset(
	    [DSC$W_LENGTH] = size,
	    [DSC$B_DTYPE] = DSC$K_DTYPE_T,
	    [DSC$B_CLASS] = DSC$K_CLASS_S,
	    [DSC$A_POINTER] = buffer) %;
EXTERNAL ROUTINE	LIB$PUT_OUTPUT : addressing_mode(general);
FORWARD ROUTINE
	a_main,
	init_prod_table,
	init_sum_table,
	with_product_one_sum_cant_know,
	with_sum_one_product_can_know;
OWN
prod_table	: vector[10000, byte],
sum_table	: vector[200, byte];
!==============================================================================
ROUTINE a_main =
BEGIN
LOCAL
sum,
product,
len,
desc(out_desc, out_buf, 80);
init_prod_table();
init_sum_table();
incr i from 2 to 99 do
    incr j from (.i + 1) to 100 do
	BEGIN
	product = .i * .j;
	sum     = .i + .j;
	if (.prod_table[.product] GTR 1) then				! if product can be generated more than one way
	    if (.sum GTR 6) then					! if sum can be generated more than one way
		if (.sum_table[.sum]) then				! if every sums product can be generated more than one way
		    if with_product_one_sum_cant_know(.product) then
			if with_sum_one_product_can_know(.sum) then
			    BEGIN
			    out_desc[DSC$W_LENGTH] = 80;
			    $FAO(%ascid 'NUMBERS = !UL, !UL;', len, out_desc, .i, .j);
			    out_desc[DSC$W_LENGTH] = .len;
			    LIB$PUT_OUTPUT(out_desc);
			    END;
	END;
RETURN 1;
END;
!==============================================================================
ROUTINE init_prod_table =
BEGIN
LOCAL
product;
incr i from 2 to 99 do
    incr j from (.i + 1) to 100 do
	BEGIN
	product = .i * .j;
	prod_table[.product] = .prod_table[.product] + 1;	! number of number pairs that generate this product
	END;
RETURN 1;
END;
!==============================================================================
ROUTINE init_sum_table =
BEGIN
LOCAL
half_sum,
product,
increment;
incr sum from 5 to 199 do
    BEGIN
    sum_table[.sum] = 1;
    if (.sum)	then half_sum = (.sum / 2)		! not multiple of 2
		else half_sum = (.sum / 2) - 1;		! multiple of 2
    product = 2 * (.sum - 2);
    increment = .sum - 3;
    incr half from 2 to .half_sum do
	BEGIN
	if (.prod_table[.product] LEQ 1) then
	    BEGIN
	    sum_table[.sum] = 0;
	    EXITLOOP;
	    END;
	increment = .increment - 2;			! this is a fast way of calculating x * y from the previous value
	product = .product + .increment;		! (x + 1) * (y - 1) = (x * y) + (y - x - 1)
	END;
    END;
RETURN 1;
END;
!==============================================================================
ROUTINE with_product_one_sum_cant_know ( product ) =
BEGIN
LOCAL
j,
pair_found;
pair_found = 0;
incr i from 2 to .product do
    BEGIN
    j = .product / .i;
    if (.i GTR .j) then EXITLOOP;
    if (.j * .i EQL .product) then
	BEGIN
	if (.sum_table[.j + .i]) then				! if every sums product can be generated more than one way
	    BEGIN
	    if (.pair_found) then RETURN 0;
	    pair_found = 1;
	    END;
	END;
    END;
RETURN .pair_found;
END;
!==============================================================================
ROUTINE with_sum_one_product_can_know ( sum ) =
BEGIN
LOCAL
half_sum,
pair_found;
if (.sum)	then half_sum = (.sum / 2)		! not multiple of 2
		else half_sum = (.sum / 2) - 1;		! multiple of 2
pair_found = 0;
incr half from 2 to .half_sum do
    BEGIN
    if with_product_one_sum_cant_know(.half * (.sum - .half)) then
	BEGIN
	if (.pair_found) then RETURN 0;
	pair_found = 1;
	END;
    END;
RETURN .pair_found;
END;
!==============================================================================
END
ELUDOM
 | 
|  | 
	Hi,
	Glad you liked the puzzle.  It's really pretty difficult to
	explain this solution in words, but i'll give it a quick shot.
	The solution must be a pair of numbers such that ...
1.	Given the product, it can be generated by more than one pair
	of numbers (product is not unique).
2.	Given the sum, it can be generated by more than one pair of
	numbers (sum is not unique), and for every one of those possible
	pairs the products they generate must also be non-unique.
3.	Given the product, find all the possible values for the sums.
	There must only be exactly one of those possible sums that
	generates all non-unique products.  That's how Mr. P figures it
	out.
4.	Finally, Mr. S must be able to figure it out so ...
	Given the sum, find all possible values for the product, there
	must be exactly one of those products that meets all the criteria
	in the previous step such that Mr. P could have figure it out.  When
	Mr. S determines which of those products can do this he knows
	the solution too.
	I realize that reading these statements quickly will probably
	confuse you, but it's the only way i know of to put the solution
	in words.  If you look at this explanation together with the
	program solution maybe it will make more sense to you.
	- marty
 |