|
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
|