/**
* Copyright uwi ( http://wonderfl.net/user/uwi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/4atx
*/
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.utils.getTimer;
// @see http://projecteuler.net/index.php?section=problems&id=287
public class Euler287 extends Sprite {
private var _tf : TextField;
public function Euler287() {
_tf = new TextField();
_tf.width = 465;
_tf.height = 465;
addChild(_tf);
var s : int = getTimer();
tr(solve(19));
var g : int = getTimer();
tr((g - s) + " ms");
}
// 左上右下の場合は領域の左上隅と右下隅を調べればOK (rec2)
// 左下右上の場合は左下隅と右上隅を調べればOK (rec1)
// N=24は30秒近くかかった・・
private function solve(N : uint) : Number
{
var inf : Number = 0;
var sup : Number = 1 << (N-1);
return rec1(inf, inf, sup, sup, sup) +
2 * rec2(inf, sup, sup, 2 * sup, sup) +
rec1(sup, sup, 2 * sup, 2 * sup, sup) + 1;
}
private function rec1(x1 : uint, y1 : uint, x2 : uint, y2 : uint, r : uint) : Number
{
var b1 : Boolean = judge(x1, y1, r);
var b2 : Boolean = judge(x2-1, y2-1, r);
if(b1 == b2)return 2;
if(x2 - x1 == 2)return 9;
var cx : uint = (x1+x2)>>1;
var cy : uint = (y1+y2)>>1;
return 1 +
rec1(x1, y1, cx, cy, r) +
rec1(x1, cy, cx, y2, r) +
rec1(cx, y1, x2, cy, r) +
rec1(cx, cy, x2, y2, r);
}
private function rec2(x1 : uint, y1 : uint, x2 : uint, y2 : uint, r : uint) : Number
{
var b1 : Boolean = judge(x1, y2-1, r);
var b2 : Boolean = judge(x2-1, y1, r);
if(b1 == b2)return 2;
if(x2 - x1 == 2)return 9;
var cx : uint = (x1+x2)>>1;
var cy : uint = (y1+y2)>>1;
return 1 +
rec2(x1, y1, cx, cy, r) +
rec2(x1, cy, cx, y2, r) +
rec2(cx, y1, x2, cy, r) +
rec2(cx, cy, x2, y2, r);
}
private function judge(x : Number, y : Number, r : Number) : Boolean
{
return (x-r) * (x-r) + (y-r) * (y-r) <= r*r;
}
private function tr(...o : Array) : void
{
_tf.appendText(o + "\n");
_tf.scrollV = _tf.maxScrollV;
}
}
}