7
\$\begingroup\$

The Seven-Eleven problem is find 4 positive numbers (with two decimal digits, A.BC) such that their sum is equal to their product and is equal to 7.11.

a + b + c + d = a * b * c * d = 7.11
0 < a <= b <= c <= d

Write the shortest program to compute all non-decreasing quadruples. Precomputing the values is not allowed.

\$\endgroup\$
3
  • \$\begingroup\$ Since both addition and multiplication are commutative, the last constraint of "0 < a <= b <= c <= d" is somewhat redundant; one simply has to solve for any a, b, c, and d that satisfies the other constraints and then sort the values in ascending order. \$\endgroup\$
    – ESultanik
    Commented Jun 17, 2011 at 15:41
  • \$\begingroup\$ At first sight, two negative numbers would lead to an positive product as well, and could lead to a sum which is a solution. So (a,b,c,d) >= 0 would be fine. (!= 0 follows for some other reason from the question). \$\endgroup\$ Commented Jun 17, 2011 at 17:20
  • \$\begingroup\$ @user unknown: I need to follow up on how to consider accepted solution since I don't want to accept only CodeGolf scripts. \$\endgroup\$
    – Alexandru
    Commented Jun 17, 2011 at 18:05

8 Answers 8

5
\$\begingroup\$

Ruby, 105 characters

Unfortunately I didn't get it below the 100 mark. It just brute forces all possible tuples and checks afterwards. Nevertheless it still finishes in finite time.

(1..m=711).map{|a|(a..m).map{|b|(b..m).map{|c|d=m-a-b-c;p [a/u=1e2,b/u,c/u,d/u]if d>=c&&a*b*c*d==m*1e6}}}

The formatted version looks like this:

(1..m=711).map{ |a|
  (a..m).map{ |b|
    (b..m).map{ |c|
      d=m-a-b-c
      p [a/u=1e2,b/u,c/u,d/u] if d>=c && a*b*c*d==m*1e6
    }
  }
}
\$\endgroup\$
3
\$\begingroup\$

Haskell - 121

(extra newline added for readability)

h=711
main=mapM(print.map((/100).realToFrac))
     [[a,b,c,d]|a<-[1..h],b<-[a..h],c<-[b..h],let d=h-a-b-c,c<=d,a*b*c*d==h*10^6]

This meets the requirements by only working with numbers with two decimal digits. It computes the solution (there's only one of them) using integer arithmetic, scaled up by 100. Floating-point arithmetic is too untrustworthy for this.

\$\endgroup\$
1
\$\begingroup\$

Python (146 152 characters)

Here's a "real" answer, if my Wolfram Alpha one doesn't please:

n=711
r=lambda v:range(v,n)
print [[a*0.01,b*0.01,c*0.01,d*0.01]for a in r(1)for b in r(a)for c in r(b)for d in r(c)if a+b+c+d==n and a*b*c*d==n]

It's very, very inefficient, but it works.

\$\endgroup\$
3
  • \$\begingroup\$ It looks like I've used basically the same method as Joey, just in a more verbose language :-) \$\endgroup\$
    – ESultanik
    Commented Jun 17, 2011 at 19:13
  • \$\begingroup\$ My solution (Haskell) was too slow until I computed d rather than brute-forcing it. \$\endgroup\$
    – Joey Adams
    Commented Jun 17, 2011 at 22:13
  • \$\begingroup\$ Also, I think you can replace def r(v):... with r=lambda v:range(v,n). \$\endgroup\$
    – Joey Adams
    Commented Jun 17, 2011 at 22:13
1
\$\begingroup\$

C (229 characters)

Sacrificial offering:

#include<stdio.h>
int main(void){int a,b,c,d;for(a=1;a<=711/4;++a)for(b=a;b<=711/4;++b)for(c=b;c<=711/4;++c){d=711-(a+b+c);if(d<c)break;if(a*b*c*d==711000000)printf("a=%.2f,b=%.2f,c=%.2f,d=%.2f\n",a/100.,b/100.,c/100.,d/100.);}}

Re-formatted for readability:

#include <stdio.h>

int main()
{
    int a, b, c, d;

    for (a = 1; a <= 711 / 4; ++a)
        for (b = a; b <= 711 / 4; ++b)
            for (c = b; c <= 711 / 4; ++c)
            {
                d = 711 - (a + b + c);
                if (d < c) break;
                if (a * b * c * d == 711000000)
                    printf("a = %.2f, b = %.2f, c = %.2f, d = %.2f\n", a / 100., b / 100., c / 100., d / 100.);
            }
}
\$\endgroup\$
5
  • \$\begingroup\$ You can make it shorter by abusing implicitly-declared arguments, rather than explicitly declaring variables: main(a,b,c,d){ instead of int main(void){int a,b,c,d; \$\endgroup\$
    – Joey Adams
    Commented Jun 17, 2011 at 22:10
  • \$\begingroup\$ @Joey: thanks, I could do that but I think I'd feel dirty afterwards. ;-) \$\endgroup\$
    – Paul R
    Commented Jun 18, 2011 at 7:59
  • 1
    \$\begingroup\$ If you feel dirty doing that sort of thing, then you will have some critical limitations in code golf. \$\endgroup\$ Commented Jun 19, 2011 at 6:25
  • \$\begingroup\$ @Peter: good point - I may have to work on this \$\endgroup\$
    – Paul R
    Commented Jun 19, 2011 at 7:43
  • 1
    \$\begingroup\$ b can run to 711/3, c to 711/2. (a,b,c) can then be precomputed (see my scala-solution). By optimising for speed, one would let b run to (711-a)/3, c to (711-a-b)/2 but not for golfing. \$\endgroup\$ Commented Jul 12, 2011 at 18:35
1
\$\begingroup\$

GNU Prolog REPL, 57 bytes

(The REPL input ends with two newlines, which are included in the byte count.)

A+B+C+D#=711,A*B*C*D#=711000000,fd_labeling([A,B,C,D]).


The first line prints the first solution (very quickly, in fact; fd_labeling often needs tuning to run quickly, but it didn't in this case). GNU Prolog's generates the solution which has the arguments in sorted order first. In this case, only one solution is in sorted order, so we can enter a newline at the "more solutions?" prompt to not generate the remaining solutions; arguably this is hardcoding the number of solutions, but as required by the question, it doesn't hardcode the values in the solution. Uses fixed-point arithmetic (so the numbers are printed without a decimal point), because GNU Prolog's built-in equation solver handles only integers.

This is just a case of finding a language with a language feature that solves the problem almost directly. Mathematica might be the obvious choice, but GNU Prolog has a constraint solver too. If only the REPL ran fd_labeling automatically! (Come to think of it, maybe I should write a language that uses GNU Prolog's constraint solver behind the scenes and has a terser syntax; it'd be useful in this sort of challenge when it comes up in the future, and possibly even for general use. Oh, and that's designed to solve problems using normal arithmetic operations rather than INTERCAL's.)

\$\endgroup\$
1
  • \$\begingroup\$ This is a fairly old challenge, so I was potentially concerned about language-newer-than-the-challenge, but it works using a version of GNU Prolog from 2007. \$\endgroup\$
    – user62131
    Commented Nov 21, 2016 at 2:07
1
\$\begingroup\$

K, 67 chars

Brute force, requires about ten seconds.

For information about K (unique mix of APL, functional, and Database programming language). see kdb.com

{if[(_711e6)=*/r:x,711-+/x;R::r]}'?{|':1+a\:x}'!*/a:3#_711%4;R%100

generates the answer

1.2 1.25 1.5 3.16

Explanation:

  • Algorithm:

    • Generates range 1..711/4 for each of three values

    • calculates the fourth as 711-sum of the other three

    • Filter to guarantee ascending order of the values

    • Calculates product of values and compare with 711000000

  • About syntax

    • Many predefined functions are one-letter operators. There are diad (x OP y) and monad (OP x) variants. Evaluation left to right, no precendence, ';' as sentence separator, 'var : value' to assign. {..} defines an anonimous function

    • diads: % is divide, x:y computes list fo digits of y in x-base, x#y takes, | is max

    • monads: _ is floor, f/ reduces list with funcion f (ej. */ calculates product, +/ calculates sumation), !x generate values 0..x-1, ?x return unique values of list x, f': applies f to each pair of the argument list (|':x to guarantee non.decreasing values)

    • func'args applies the function over each of the args

\$\endgroup\$
0
\$\begingroup\$

Scala 168 139

def h(i:Int)=i/100.0
val x=711
for(a<-1 to x;
b<-a to x;
c<-b to x;
d=x-a-b-c
if(d>c&&h(a)*h(b)*h(c)*h(d)==7.11))yield(h(a),h(b),h(c),h(d))
\$\endgroup\$
0
\$\begingroup\$

Mathematica

Solve[
    a + b + c + d == a * b * c * d / 10^6 == 711
        && 0 < a <= b <= c <= d,
    {a, b, c, d},
    Integers
]

Basically, solve it as an integer Diophantine equation. The advantage is that this avoids possible floating-point error.

On my computer, Mathematica runs out of memory, but it might work in principle...

It might be possible to run this on Wolfram Alpha, but I'm not familiar enough with its syntax.

In Mathematica, this is 58 characters + 1 fraction line + 1 exponentiation box.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.