Three Wise Men

December 28, 2012

It is easier to convert all the prices to pennies and work with a multiplicative total of 65.52 * 1003. Here’s a function using a list comprehension that solves the problem for any given total:

(define (magi n)
  (list-of (list a b c)
    (a range 1 (quotient n 2))
    (b range (+ a 1) (quotient (- n a) 3))
    (c is (- n a b))
    (= (* a b c) (* n 10000))))

> (magi 6552)
((52 200 6300))

The three prices are $0.52, $2.00 and $63.00. You can run the program at http://programmingpraxis.codepad.org/VpH8ZI25.

Advertisement

Pages: 1 2

11 Responses to “Three Wise Men”

  1. Paul said

    A Python version.

    def three_wise_men(sumabc):
        prodabc = sumabc * 10000
        for a in xrange(1,sumabc // 3):
            if prodabc % a == 0:
                prodbc = prodabc // a
                sumbc =sumabc - a
                for b in xrange(a, sumbc // 2):
                    if prodbc % b == 0:
                        c = prodbc // b
                        if b + c == sumbc:
                            return a, b, c
                
    print three_wise_men(6552)
    
  2. […] today’s Programming Praxis exercise, our goal is to solve a puzzle in which both the addition and […]

  3. My Haskell solution (see http://bonsaicode.wordpress.com/2012/12/28/programming-praxis-three-wise-men/ for a version with comments):

    main :: IO ()
    main = print $ head [(a,b,c) | a <- [1..6550], b <- [1..a], let c = 6552 - a - b, a * b * c == 65520000]
    
  4. Mark Henderson said

    Takes a few minutes:

    def three_wise():
        r = [x for x in range(1, 6553)]
        return next((a, b, c) for a in r for b in r for c in reversed(r)
                if a + b + c == 6552
                if a * b * c == 65520000)
    
    print three_wise()
    
  5. Overpants said

    This is an easier version of an earlier problem (https://programmingpraxis.com/2009/11/27/7-11/). Unlike the other problem, it seems that you can just brute force this one and still have it run fairly quickly.

  6. cosmin said

    Another Python solution:

    from math import sqrt, ceil
    
    def divisors(n):
    	f = [i for d in xrange(1, 1 + int(sqrt(n))) if n%d == 0 for i in [d, n/d]]
    	if len(f) >= 2 and f[-1] == f[-2]: f.pop()
    	return f
    
    def three_wise_men(x):
    	s, p = int(ceil(x*100)), int(ceil(x*1000000))
    	return [(a, b, c) for a in divisors(p) if a <= s/3 for b in divisors(p/a) for c in [p/a/b] if a<=b<=c and a+b+c == s]
    
    print three_wise_men(65.52)
    
  7. Heather said

    My fastest Ruby solution:

    $ time ruby wisemen.rb
    [0.52, 2.0, 63.0]

    real 0m1.919s
    user 0m1.795s
    sys 0m0.120s

    dollars = 65.52
    cents = (dollars * 100).to_i
    
    trips = []
    
    i = 1
    j = 1
    halfcents = cents / 2
    while true
      k = cents - i - j
      if k < j
        i += 1
        j = i
        if (i >= halfcents) || (k < 2)
          break
        else
          next
        end
      end
      trips << [i, j, k]
      j += 1
    end
    
    trips.each do |trip|
      trip = trip.map { |t| t / 100.0 }
      if trip.inject(:*) == dollars
        puts trip.inspect
        break
      end
    end
    

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: