Project Euler 165

by uwi
@see http://projecteuler.net/index.php?section=problems&id=165
♥0 | Line 140 | Modified 2009-12-05 17:27:37 | 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/46oQ
 */

package {
    import flash.display.Sprite;
    import flash.text.TextField;
    import flash.utils.getTimer;
    import flash.events.Event;
    // @see http://projecteuler.net/index.php?section=problems&id=165
    public class Euler165 extends Sprite {
        private var _tf : TextField;
  
        public function Euler165() {
            _tf = new TextField();
            _tf.width = 465;
            _tf.height = 465;
            addChild(_tf);
            
            solve(5000);
        }

        private function solve(M : int) : void
        {
            var t : Array = [];
            var s : Number = 290797;
            var i : int, j : int;
            for(i = 0;i < 20000;i++){
                s = (s * s) % 50515093;
                t.push(s % 500);
            }
            
            var ar : Array = [];
            var step1 : Function = function() : void
            {
                tr("generate");
            for(i = 0;i < M;i++){
                for(j = i + 1;j < M;j++){
                    var ins : Array = intersect(
                        t[i<<2], t[(i<<2)+1], t[(i<<2)+2], t[(i<<2)+3],
                        t[j<<2], t[(j<<2)+1], t[(j<<2)+2], t[(j<<2)+3]
                        );
                    if(ins != null){
                        ar.push(ins);
                    }
                }
            }
            
            tr(ar.length);
            };
            
            var step2 : Function = function() : void
            {
                tr("sort");
                // x座標ソート
                ar.sortOn("0", Array.NUMERIC);
            }
             
            var step3 : Function = function() : void
            {
                var THRES : Number = 0.000001;
                
            // 近寄っているのを抽出
                tr("judge");
            var start : int = 0;
            var ar2 : Array = [];
            for(i = 1;i < ar.length;i++){
                if(ar[i][0] - ar[i - 1][0] > THRES){
                    start = i;
                }else{
                    if(start == i - 1){
                        ar2.push(ar[i-1]);
                    }
                    ar2.push(ar[i]);
//                    tr(i, ar[i - 1][0], ar[i][0]);
                }
            }
            
            // y座標ソート→近寄っているのを抽出
            ar2.sortOn("1", Array.NUMERIC);
            
            var same : Array = [];
            start = 0;
            for(i = 1;i < ar2.length;i++){
                if(ar2[i][1] - ar2[i - 1][1] > THRES){
                    start = i;
                }else{
                    if(start == i - 1){
                        same.push(ar2[i-1]);
                    }
                    same.push(ar2[i]);
                }
            }
            
            // 厳密に交差チェック
            var f : Array = new Array(same.length);
            var ctx : int = 0; // 同一点の非重複カウント
            for(i = 0;i < same.length;i++){
                for(j = i + 1;j < same.length;j++){
                    if(
                    (same[i][2]-same[j][2])*same[i][7]*same[j][7]+
                    same[i][3]*same[i][6]*same[j][7]-
                    same[j][3]*same[j][6]*same[i][7]==0 &&
                    (same[i][4]-same[j][4])*same[i][7]*same[j][7]+
                    same[i][5]*same[i][6]*same[j][7]-
                    same[j][5]*same[j][6]*same[i][7]==0
                    ){
                        if(!f[i])ctx++;
                        f[i] = true;
                        f[j] = true;
                    }
                }
            }
            
            // 同一点の重複カウント
            var ctt : int = 0;
            for(i = 0;i < f.length;i++){
                if(f[i])ctt++;
            } 
            
            tr(ctx);
            tr(ctt);
            tr(ar2.length);
            tr(same.length);
            tr("answer:" + (ar.length - ctt + ctx));
//            tr(same.join('\n'));
            }
            
            addEventListener(Event.ENTER_FRAME, makeEnterFrame([step1, step2, step3]));
        }
        
        private function makeEnterFrame(queue : Array) : Function
        {
            return function(e : Event) : void
            {
                removeEventListener(Event.ENTER_FRAME, arguments.callee);
                queue.shift()();
                if(queue.length > 0){
                    addEventListener(Event.ENTER_FRAME, makeEnterFrame(queue));
                }
            }
        }
       
        private function intersect(x1s : int, y1s : int, x1g : int, y1g : int, x2s : int, y2s : int, x2g : int, y2g : int) : Array
        { 
            var x1d : int = x1g - x1s;
            var y1d : int = y1g - y1s;
            var x2d : int = x2g - x2s;
            var y2d : int = y2g - y2s;
            
            var D : int = x1d * -y2d - y1d * -x2d;
            if(D == 0)return null; 
            
            var Ut : int = (-y2d * (x2s - x1s) + x2d * (y2s - y1s));
            var Uu : int = (-y1d * (x2s - x1s) + x1d * (y2s - y1s));
            if(D > 0){
                if(Ut <= 0 || Ut >= D)return null;
                if(Uu <= 0 || Uu >= D)return null;
            }else{
                if(Ut >= 0 || Ut <= D)return null;
                if(Uu >= 0 || Uu <= D)return null;
            } 
             
//             var t : Number = Ut / D;
//             var u : Number = Uu / D;
             return [x1s+x1d*Ut/D, y1s+y1d*Ut/D, x1s, x1d, y1s, y1d, Ut, D];
        }
           
        private function tr(...o : Array) : void
        {
            _tf.appendText(o + "\n");
        }
    }
}

Forked