Project Euler 210(unsolved)
@see http://projecteuler.net/index.php?section=problems&id=210
♥0 |
Line 107 |
Modified 2010-03-12 11:42:30 |
MIT License
archived:2017-03-30 04:40:31
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/fEUK
*/
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.utils.getTimer;
// @see http://projecteuler.net/index.php?section=problems&id=210
public class Euler210 extends Sprite {
private var _tf : TextField;
public function Euler210() {
_tf = new TextField();
_tf.width = 465;
_tf.height = 465;
addChild(_tf);
var s : int = getTimer();
tr(solve(100));
tr(solveNaive(100));
var g : int = getTimer();
tr((g - s) + " ms");
}
private function solveNaive(r : Number) : Number
{
var ct : uint = 0;
var oc2 : Number = r*r/8;
for(var y : int = -r;y <= r;y++){
for(var x : int = -(r - Math.abs(y));x <= r - Math.abs(y);x++){
if(x == y)continue;
var ob2 : Number = x * x + y * y;
var bc2 : Number = (x-r/4)*(x-r/4)+(y-r/4)*(y-r/4);
if(ob2 == 0 || bc2 == 0)continue;
if(
ob2 + bc2 - oc2 < 0 ||
ob2 + oc2 - bc2 < 0 ||
oc2 + bc2 - ob2 < 0
){
if((x-r/8)*(x-r/8)+(y-r/8)*(y-r/8) <= r*r/32 && x < 0){
ct++;
}
}
}
}
return ct;
}
// |x|+|y|<=rを満たす格子点で、
// (0,0)と(r/4,r/4)と鈍角三角形をなすような格子点の個数をN(r)とするとき、
// N(10^9)を求める。
private function solve(r : Number) : Number
{
var R : Number = r/8*Math.SQRT2;
var dsup : Number = -(r/8-R);
var sum : Number = 0;
var i : uint;
var edge : Number;
for(i = 1;i <= dsup;i++){
// var sq : Number = Math.sqrt(R*R-(r/8+i)*(r/8+i));
// R*R-(r/8+i)*(r/8+i)=(r^2/64*2)-(r^2/64+r/4*i+i*i)
// 桁オーバーする・・
// r/8+√((√2(r/8))^2-(r/8+i)^2)=整数?
// =r/8+√(r^2/32-(r/8+i)^2)=1/2(r/4+√(r^2/8-(r/4+2i)^2)
// 625/2-(25/2+3)^2=625/2-961/4=289/4=>17/2
var D : Number = r/4+Math.sqrt(r*r/8-(r/4+2*i)*(r/4+2*i));
if(D / 2 == Math.floor(D / 2)){
sum += Math.sqrt(r*r/8-(r/4+2*i)*(r/4+2*i))-1;
}else{
var sq : Number = Math.sqrt(R-(r/8+i))*Math.sqrt(R+(r/8+i));
edge = r/8+sq;
// tr(edge, sq);
sum += Math.floor(edge);
edge = r/8-sq;
sum -= Math.floor(edge);
}
tr(sum);
}
tr(sum);
sum = sum * 4 - (r/4+1)-2;
tr(sum);
sum += (r/4+1)*(r/4+1);
tr(sum);
// r*r/2
// r*r/2
sum += r*r;
// r*(r/2)/2
// r*(r/2)/2
sum += r*r/2;
tr(sum);
tr(dsup);
return sum;
}
private function tr(...o : Array) : void
{
_tf.appendText(o + "\n");
_tf.scrollV = _tf.maxScrollV;
}
}
}
class N2{
public static const N : Number = 1E15;
public static function add(a : Array, b : Array) : Array
{
var r0 : Number = a[0] + b[0];
var rp : int = Math.floor(r0 / N);
r0 -= rp * N;
var r1 : Number = a[1] + b[1] + rp;
return [r0, r1];
}
public static function sub(a : Array, b : Array) : Array
{
var r0 : Number = a[0] - b[0];
var rp : int = Math.floor(r0 / N);
r0 -= rp * N;
var r1 : Number = a[1] - b[1] + rp;
return [r0, r1];
}
public static function inc(a : Array, b : Number) : Array
{
var r0 : Number = a[0] + b;
var rp : int = Math.floor(r0 / N);
r0 -= rp * N;
var r1 : Number = a[1] + rp;
a[0] = r0;
a[1] = r1;
return a;
}
}