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\$
  • \$\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 Jun 17 '11 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\$ – user unknown Jun 17 '11 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 Jun 17 '11 at 18:05
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\$
8
\$\begingroup\$

Wolfram Alpha (51 characters)

You can also run it yourself.

solve(a+b+c+d=7.11,a*b*c*d=7.11,a>0,b>=a,c>=b,d>=c)
\$\endgroup\$
  • \$\begingroup\$ @ESultanik: While that is very clever, I don't think the OP wanted an exact solution. \$\endgroup\$ – mellamokb Jun 17 '11 at 13:52
  • 1
    \$\begingroup\$ Well, Wolfram Alpha is built atop Mathematica, which is a Turing complete programming language, so I figured it was fair game ;-) \$\endgroup\$ – ESultanik Jun 17 '11 at 14:55
  • \$\begingroup\$ (a,b,c,d) | x=> x*100 € N isn't fulfilled, is it? \$\endgroup\$ – user unknown Jun 17 '11 at 17:24
  • 1
    \$\begingroup\$ I don't think this solution meets the requirement "with two decimal digits, A.BC". \$\endgroup\$ – Joey Adams Jun 17 '11 at 18:44
  • \$\begingroup\$ @Joey: The problem just asked to "print out all non-decreasing quadruples"; it didn't say that was the only thing the program was allowed to output! Simply filter out all of the (infinite) other reals that don't have two decimal digits ;-) \$\endgroup\$ – ESultanik Jun 17 '11 at 19:16
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\$
  • \$\begingroup\$ It looks like I've used basically the same method as Joey, just in a more verbose language :-) \$\endgroup\$ – ESultanik Jun 17 '11 at 19:13
  • \$\begingroup\$ My solution (Haskell) was too slow until I computed d rather than brute-forcing it. \$\endgroup\$ – Joey Adams Jun 17 '11 at 22:13
  • \$\begingroup\$ Also, I think you can replace def r(v):... with r=lambda v:range(v,n). \$\endgroup\$ – Joey Adams Jun 17 '11 at 22:13
  • \$\begingroup\$ @Joey: You're right. Thanks! \$\endgroup\$ – ESultanik Jun 18 '11 at 0:41
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\$
  • \$\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 Jun 17 '11 at 22:10
  • \$\begingroup\$ @Joey: thanks, I could do that but I think I'd feel dirty afterwards. ;-) \$\endgroup\$ – Paul R Jun 18 '11 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\$ – Peter Olson Jun 19 '11 at 6:25
  • \$\begingroup\$ @Peter: good point - I may have to work on this \$\endgroup\$ – Paul R Jun 19 '11 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\$ – user unknown Jul 12 '11 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\$
  • \$\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 Nov 21 '16 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, privacy policy and cookie policy

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