Project Euler 199

by uwi
@see http://projecteuler.net/index.php?section=problems&id=
♥0 | Line 73 | Modified 2010-07-20 12:59:21 | MIT License
play

ActionScript3 source code

/**
 * Copyright uwi ( http://wonderfl.net/user/uwi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/1J8c
 */

package {
    import flash.display.Sprite;
    import flash.text.TextField;
    import flash.utils.getTimer;
    // @see http://projecteuler.net/index.php?section=problems&id=
    public class Euler extends Sprite {
        private var _tf : TextField;
  
        public function Euler() {
            _tf = new TextField();
            _tf.width = 465;
            _tf.height = 465;
            addChild(_tf);
            
            var s : int = getTimer();
            tr(solve(3));
            var g : int = getTimer();
            tr((g - s) + " ms");
        }

        private function solve(N : uint) : Number
        {
                var R : Number = 2 * Math.sqrt(3) - 3;
                return 1.0 - R * R * 3 - 3 * recO(R, R, 1, N) 
                    - recI(R, R, R, N);
        } 
        
        private function recO(a : Number, b : Number, c : Number, depth : uint) : Number
        {
                if(depth == 0)return 0;
                var r : Number = solveIIO(a, b, c);
//                tr(r,depth);
                return r * r + recO(r, a, c, depth-1) + recO(r, b, c, depth-1) + recI(r, a, b, depth-1);
        }
        
        private function recI(a : Number, b : Number, c : Number, depth : uint) : Number
        {
                if(depth == 0)return 0;
                var r : Number = solveIII(a, b, c);
                return r * r + recI(r, a, c, depth-1) + recI(r, b, c, depth-1) + recI(r, a, b, depth-1);
        }
        
        private function solveIII(a : Number, b : Number, c : Number) : Number
        {
                return binarySolve(0, Math.max(a,b,c), function(r : Number) : Number {
                    return Math.sqrt((a+b+c)*a*b*c)-Math.sqrt((a+b+r)*a*b*r)-Math.sqrt((b+c+r)*b*c*r)-Math.sqrt((c+a+r)*c*a*r);
                }, 1E-12);
        }
        
        // c > a,b
        private function solveIIO(a : Number, b : Number, c : Number) : Number
        {
                var fiio : Function = 
                    function(r : Number) : Number {
                        return Math.sqrt((c-a-b)*a*b*c)+Math.sqrt((a+b+r)*a*b*r)-Math.sqrt((c-b-r)*b*c*r)-Math.sqrt((c-a-r)*c*a*r);
                    };
            var max : Number = Math.min(c-b,c-a,Math.max(b,a), (c-Math.sqrt(c*(a*c+b*c-4*a*b)/(a+b)))/2);
            /*
            if(fiio(max) > 0){
//                max = max / 2;
            }
            
            */
                
                return binarySolve(max / 2, max, fiio, 1E-12);
                /*
                return binarySolve(0, Math.min(c-b,c-a), function(r : Number) : Number {
                    return Math.sqrt((c-a-b)*a*b*c)+Math.sqrt((a+b+r)*a*b*r)-Math.sqrt((c-b-r)*b*c*r)-Math.sqrt((c-a-r)*c*a*r);
                }, 1E-8);
                */
        }
        
        private function ff(x : Number) : Number
        {
            return 5 - x*x;
//                return x * x - 5;
        }

        private function binarySolve(a : Number, b : Number, f : Function, eps : Number) : Number
        {
                var inc : Boolean = f(a) < 0;
                while(b - a > eps){
                    var c : Number = (a + b) * 0.5;
                    if((f(c) < 0) == inc){
                        a = c;
                    }else{
                        b = c;
                    }
                }
                return a;
        }
        
        private function tr(...o : Array) : void
        {
            _tf.appendText(o + "\n");
            _tf.scrollV = _tf.maxScrollV;
        }
    }
}