Project Euler 287

by uwi
@see http://projecteuler.net/index.php?section=problems&id=287
♥0 | Line 63 | Modified 2010-04-10 23:31:59 | 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/4atx
 */

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

        // 左上右下の場合は領域の左上隅と右下隅を調べればOK (rec2)
        // 左下右上の場合は左下隅と右上隅を調べればOK (rec1)
        // N=24は30秒近くかかった・・
        private function solve(N : uint) : Number
        {
        		var inf : Number = 0;
        		var sup : Number = 1 << (N-1);
        		return rec1(inf, inf, sup, sup, sup) +
        		2 * rec2(inf, sup, sup, 2 * sup, sup) +
        		rec1(sup, sup, 2 * sup, 2 * sup, sup) + 1;
        }
        
        private function rec1(x1 : uint, y1 : uint, x2 : uint, y2 : uint, r : uint) : Number
        {
        		var b1 : Boolean = judge(x1, y1, r);
        		var b2 : Boolean = judge(x2-1, y2-1, r);
        		if(b1 == b2)return 2;
        		if(x2 - x1 == 2)return 9;
        		var cx : uint = (x1+x2)>>1;
        		var cy : uint = (y1+y2)>>1;
        		return 1 + 
        			rec1(x1, y1, cx, cy, r) +
        			rec1(x1, cy, cx, y2, r) +
        			rec1(cx, y1, x2, cy, r) +
        			rec1(cx, cy, x2, y2, r);
        }
        
        private function rec2(x1 : uint, y1 : uint, x2 : uint, y2 : uint, r : uint) : Number
        {
        		var b1 : Boolean = judge(x1, y2-1, r);
        		var b2 : Boolean = judge(x2-1, y1, r);
        		if(b1 == b2)return 2;
        		if(x2 - x1 == 2)return 9;
        		var cx : uint = (x1+x2)>>1;
        		var cy : uint = (y1+y2)>>1;
        		return 1 + 
        			rec2(x1, y1, cx, cy, r) +
        			rec2(x1, cy, cx, y2, r) +
        			rec2(cx, y1, x2, cy, r) +
        			rec2(cx, cy, x2, y2, r);
        }
        
        private function judge(x : Number, y : Number, r : Number) : Boolean
        {
        		return (x-r) * (x-r) + (y-r) * (y-r) <= r*r;
        }

        private function tr(...o : Array) : void
        {
            _tf.appendText(o + "\n");
            _tf.scrollV = _tf.maxScrollV;
        }
    }
}