Project Euler 165
@see http://projecteuler.net/index.php?section=problems&id=165
♥0 |
Line 140 |
Modified 2009-12-05 17:27:37 |
MIT License
archived:2017-03-30 04:44:21
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");
}
}
}