Project Euler 162

by uwi
@see http://projecteuler.net/index.php?section=problems&id=162
♥0 | Line 124 | Modified 2009-07-22 19:51:10 | 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/srcP
 */

package {
    import flash.display.Sprite;
    import flash.text.TextField;
    import flash.utils.getTimer;
    // @see http://projecteuler.net/index.php?section=problems&id=162
    public class Euler162 extends Sprite {
        private var _tf : TextField;
  
        public function Euler162() {
            _tf = new TextField();
            _tf.width = 465;
            _tf.height = 465;
            addChild(_tf);
            
            var s : int = getTimer();
//            _tf.appendText("" + solve(16).toString(16).toUpperCase() + "\n");
            _tf.appendText("" + solve(16).toString() + "\n");
            var g : int = getTimer();
            _tf.appendText("" + (g - s) + " ms\n");
        }
        
        private var _cache : Array;
        
        private function solve(N : int) : MPI
        {
            _cache = new Array(N);
            var i : int, j : int;
            for(i = 0;i < N;i++){
                _cache[i] = new Array(8);
                for(j = 0;j < 8;j++)_cache[i][j] = null;
            }
            
            var ret : MPI = new MPI(0);
            for(i = 1;i <= N;i++){
                ret.add(rec(0, i, 0));
            }
            return ret;
        }
        
        private function rec(pos : int, n : int, flag : uint) : MPI
        {
            if(pos == n){
                return new MPI(flag == 7 ? 1 : 0);
            }
            if(pos > 0 && _cache[n - pos][flag] != null)return _cache[n - pos][flag];
            
            var ret : MPI = new MPI(0);
            for(var i : int = (pos == 0 ? 1 : 0);i <= 15;i++){
                var nflag : uint = flag;
                if(i == 0)nflag = nflag | 1;
                if(i == 1)nflag = nflag | 2;
                if(i == 10)nflag = nflag | 4;
                ret.add(rec(pos + 1, n, nflag));
            }
            if(pos > 0)_cache[n - pos][flag] = ret;
            return ret;
        }
    }
}

internal class MPI
{
    public var d : Vector.<uint>;
    
    public function MPI(v : Number = 0)
    {
        if(v == 0){
            d = Vector.<uint>([0]);
        }else{
            d = Vector.<uint>([]);
            for(var i : Number = v;i != 0;i = Math.floor(i / 10))d.push(i % 10);
        }
    }
    
    public function clone() : MPI
    {
        var ret : MPI = new MPI();
        ret.d = d.concat();
        return ret;
    }
    
    public function carry() : void
    {
        for(var i : int = 0;i < d.length;i++){
            var c : uint = d[i] / 10;
            if(c > 0){
                if(i == d.length - 1){
                    d.push(0);
                }
                d[i + 1] += c;
            }
            d[i] %= 10;
        }
    }
    
    public function add(n : MPI) : MPI
    {
        var i : int;
        for(i = 0;i < Math.min(d.length, n.d.length);i++){
            d[i] += n.d[i];
        }
        for(i = d.length;i < n.d.length;i++){
            d.push(n.d[i]);
        }
        carry();
        return this;
    }
    
    public function mul(n : MPI) : MPI
    {
        var ret : Vector.<uint> = new Vector.<uint>(d.length + n.d.length);
        var i : int, j : int;
        for(i = 0;i < ret.length;i++)ret[i] = 0;
        for(i = 0;i < d.length;i++){
            for(j = 0;j < n.d.length;j++){
                ret[i + j] += d[i] * n.d[j];
            }
        }
        d = ret;
        carry();
        shave();
        return this;
    }
    
    public function shave() : void
    {
        for(var i : int = d.length - 1;i >= 1;i--){
            if(d[i] > 0)break;
            d.pop();
        }
    }
    
    public function toString() : String
    {
        var ret : String = "";
        for(var i : int = d.length - 1;i >= 0;i--){
            ret += d[i].toString();
        }
        return ret;
    } 
}