Project Euler 226
@see http://projecteuler.net/index.php?section=problems&id=226
♥0 |
Line 81 |
Modified 2009-10-25 15:34:54 |
MIT License
archived:2017-03-30 04:46:47
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/aC4V
*/
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.utils.getTimer;
// @see http://projecteuler.net/index.php?section=problems&id=226
public class Euler226 extends Sprite {
private var _tf : TextField;
public function Euler226() {
_tf = new TextField();
_tf.width = 465;
_tf.height = 465;
addChild(_tf);
var s : int = getTimer();
tr(solve());
var g : int = getTimer();
tr((g - s) + " ms");
}
private function Sblancmange(seg : int, depth : int) : Number
{
var s : Number = 1.0 / (1 << (depth + 1));
for(var i : int = 0;i < depth;i++){
var pos : int = ((seg >> i) & 1) == 0 ?
seg & ((1 << i) - 1) :
((1 << i) - 1) - (seg & ((1 << i) - 1));
// tr(i, pos);
s += (pos + 0.5) / (1 << depth);
}
s /= (1 << depth);
return s;
}
private function bla(x : Number) : Number
{
var f : Number = 0;
var n2 : Number = 1;
for(var n : int = 0;n < 50;n++){
var d : Number = Math.round(n2 * x);
d = d - n2 * x;
if(d < 0)d = -d;
f += d / n2;
n2 *= 2;
}
return f;
}
private function solve() : Number
{
// 高木曲線と円の左側の交点のx座標を求める
var start : Number = 0;
var end : Number = 0.25;
do{
var mid : Number = (start + end) / 2;
var f : Number = -(0.5 - Math.sqrt(0.25 * 0.25 - (0.25 - mid) * (0.25 - mid)));
f += bla(mid);
if(f < 0){
start = mid;
}else{
end = mid;
}
}while(end - start > 0.00000000001);
var s : Number = rec(start, 1, 1); // [x,0.5]の高木曲線の面積
var minus : Number = // [x, 0.5]の長方形から円をひいた面積
(0.5 - mid) * 0.5 - // 長方形
0.25 * 0.25 / 2 * (Math.asin((0.25 - mid) / 0.25) + Math.PI / 2) - // 扇形
(0.25 - mid) * Math.sqrt(0.25 * 0.25 - (0.25 - mid) * (0.25 - mid)) / 2; // 残った三角形
tr(mid, s, minus);
return s - minus;
}
private function rec(start : Number, e : int, depth : int) : Number
{
if(depth == 31)return 0;
var n2 : Number = 1 << depth; // Math.pow(2, depth);
var s : Number = start * n2;
var ret : Number = 0;
for(var i : int = Math.ceil(s);i < e;i++){
ret += Sblancmange(i, depth);
}
return ret + rec(start, Math.ceil(s) * 2, depth + 1);
}
private function tr(...o : Array) : void
{
_tf.appendText(o + "\n");
_tf.scrollV = _tf.maxScrollV;
}
}
}