Sum and product puzzle

From Rosetta Code
Revision as of 11:06, 25 April 2015 by rosettacode>Bearophile (First draft + D solution)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Sum and product puzzle is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Solve the Impossible Puzzle:

X and Y are two different integers, greater than 1, with sum less than or equal to 100. S and P are two mathematicians; S knows the sum X+Y, P knows the product X*Y, and both are perfect logicians. Both S and P know the information in these two sentences. 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?

See also: http://en.wikipedia.org/wiki/Sum_and_Product_Puzzle

D

<lang d>void main() {

   import std.stdio, std.algorithm, std.range, std.typecons;
   const s1 = cartesianProduct(iota(1, 101), iota(1, 101))
              .filter!(p => 1 < p[0] && p[0] < p[1] && p[0] + p[1] < 100)
              .array;
   alias P = const Tuple!(int, int);
   enum add   = (P p) => p[0] + p[1];
   enum mul   = (P p) => p[0] * p[1];
   enum sumEq = (P p) => s1.filter!(q => add(q) == add(p));
   enum mulEq = (P p) => s1.filter!(q => mul(q) == mul(p));
   const s2 = s1.filter!(p => sumEq(p).all!(q => mulEq(q).walkLength != 1)).array;
   const s3 = s2.filter!(p => mulEq(p).setIntersection(s2).walkLength == 1).array;
   s3.filter!(p => sumEq(p).setIntersection(s3).walkLength == 1).writeln;

}</lang>

Output:
[const(Tuple!(int, int))(4, 13)]

With an older version of the LDC2 compiler replace the cartesianProduct line with: <lang d>

   const s1 = iota(1, 101).map!(x => iota(1, 101).map!(y => tuple(x, y))).joiner

</lang> Run-time: about 0.43 seconds with dmd, 0.08 seconds with ldc2.