Project Euler 222

by uwi
@see http://projecteuler.net/index.php?section=problems&id=222
重いのでENTER_FRAMEでまわしてるけどそれでも重い
♥0 | Line 59 | Modified 2009-10-06 04:43: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/lx68
 */

package {
    import flash.display.Sprite;
    import flash.text.TextField;
    import flash.utils.getTimer;
    import flash.events.*;
    // @see http://projecteuler.net/index.php?section=problems&id=222
    // 重いのでENTER_FRAMEでまわしてるけどそれでも重い
    public class Euler222 extends Sprite {
        private var _tf : TextField;
  
        public function Euler222() {
            _tf = new TextField();
            _tf.width = 465;
            _tf.height = 465;
            addChild(_tf);
            
            var s : int = getTimer();
            tr(solve());
            var g : int = getTimer();
            tr((g - s) + " ms");
        }

        // DP
        private function solve() : Number
        {
            _cache = new Vector.<Number>(21 * (1 << 21));
            
            var min : Number = Number.MAX_VALUE;
            var i : int = 30;
            addEventListener(Event.ENTER_FRAME, function(e : Event) : void
            {
                var v : Number = i + dfs(i, (1 << 21) - 1 - (1 << (i - 30)));
                if(v < min)min = v;
                tr(i, min);
                i++;
                if(i == 51){
                    tr(Math.round(min * 1000));
                    removeEventListener(Event.ENTER_FRAME, arguments.callee);
                }
            });
            return 0;
        }
        
        private var _cache : Vector.<Number>;
                
        private function dfs(prev : int, code : int) : Number
        {
            if(code == 0){
                return prev;
            }
            
            var ci : int = ((prev - 30) << 21) + code;
            if(_cache[ci])return _cache[ci];
            var ret : Number = Number.MAX_VALUE;
            for(var c : int = code, i : int = 30;c > 0;c >>>= 1, i++){
                if((c & 1) == 1){
                    var v : Number = Math.sqrt(200 * (prev + i) - 10000) + dfs(i, code - (1 << (i - 30)));
                    if(v < ret)ret = v;
                }
            }
            _cache[ci] = ret;
            return ret;
        }

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