Project Euler 141

by uwi
@see http://projecteuler.net/index.php?section=problems&id=
♥0 | Line 51 | Modified 2009-09-22 14:37:02 | 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/9ZdX
 */

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

        // n=dq+r r<q
        // 等比数列の昇順として、d<r<q, r<d<q, r<q<dがある。
        // 1番目の場合、r=dk, q=dk^2 (kは有理数)とすると、n=dk(dk+1)となり、
        // これは平方数にはならないので不適。よってd or q = rk or rk^2 (k>1)
        // k=v/w (v,wは自然数, v>w, (v,w)=1)として、
        // r=uw^2, d or q = uvw or uv^2 (uは自然数)と表すと、
        // n=uw(uv^3+w)となるので、(u,v,w)について走査すればよい。
        // n<=10^12なら、w<v<=10^4なのでそんなでもないはず。
        private function solve(M : Number) : Number
        {
            var LIM : Number = Math.pow(M, 1 / 3);
            var set : Object = {};
            for(var v : int = 1;v <= LIM;v++){
                var v3 : Number = v * v * v;
                for(var w : int = 1;w < v && w * (v3 + w) <= M;w++){
                    if(GCD(v, w) != 1)continue;
                    for(var u : int = 1;;u++){
                        var n : Number = u * w * (u * v3 + w);
                        if(n > M)break;
                        var sq : Number = Math.sqrt(n);
                        if(int(sq) == sq){
                            tr(u, v, w, sq, n);
                            set[sq] = sq;
                        }
                    }
                }
            }
            
            var sum : Number = 0;
            for each(var q : int in set){
                sum += q * q;
            }
            return sum;
        }
        
        private static function GCD(a : int, b : int) : int
        {
            return b == 0 ? a : GCD(b, a % b);
        }

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