Project Euler 94
@see http://projecteuler.net/index.php?section=problems&id=94
♥0 |
Line 53 |
Modified 2009-06-23 15:01:29 |
MIT License
archived:2017-03-30 04:57:20
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/fenJ
*/
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.utils.getTimer;
// @see http://projecteuler.net/index.php?section=problems&id=94
public class Euler94 extends Sprite {
private var _tf : TextField;
public function Euler94() {
_tf = new TextField();
_tf.width = 465;
_tf.height = 465;
addChild(_tf);
var s : int = getTimer();
_tf.appendText(solve().toString() + "\n");
var g : int = getTimer();
_tf.appendText((g - s).toString() + " ms\n");
}
private const N : int = 1000000000;
// 3辺の長さをa,a,cとする。(c = a+1 or a-1)
// 面積はS=c√(4a^2-c^2)/4
// 周の長さはL=2a+c
// Sの√内が平方数でないといけなく、4a^2=(2a)^2より、ピタゴラス数を生成して該当するa,cを求める。
// m,n,k(どれも自然数、m>n, m,nは互いに素)に対して、
// 2a = k(m^2 + n^2)=ka'
// c = k(2mn) or k(m^2 - n^2) = kc'
// cはa±1なので、aとcは互いに素。よって2aとcの最大公約数はたかだか2
// m^2+n^2は奇数なので、k=1ではない。よってk=2
// b'=√(a'^2-c'^2)=(m^2-n^2 or 2mn) とすると、
// S=c'b', L=2(a'+c')
//
// あとはa'と2c'の差が1となるような(m,n)の組を列挙してLを加算していけばよい。
// mを固定するとa'-2c'=±1の解は4個。そのうち2個は整数になり得ないので、m 1あたりたかだか2個のnについて調べればよい。
private function solve() : int
{
var sum : int = 0;
// 2(m^2+n^2)+(m^2+n^2)±1 <= N
var mlim : int = Math.sqrt((N - 1) / 3);
for(var m : int = 1;m <= mlim;m++){
var ncans : Object = {};
var ncan : Number;
ncan = 2 * m - Math.sqrt(3 * m * m + 1); if(ncan == ncan >> 0)ncans[ncan] = ncan;
// ncan = 2 * m - Math.sqrt(3 * m * m - 1); if(ncan == ncan >> 0)ncans[ncan] = ncan;
// ncan = Math.sqrt((m * m + 1) / 3); if(ncan == ncan >> 0)ncans[ncan] = ncan;
ncan = Math.sqrt((m * m - 1) / 3); if(ncan == ncan >> 0)ncans[ncan] = ncan;
for each(var n : int in ncans){
if(n <= 0)continue;
if(((m ^ n) & 1) == 0 || GCD(m, n) != 1)continue;
var a : int = m * m + n * n;
var ch1 : int = 2 * m * n;
var ch2 : int = m * m - n * n;
var p : int;
if(2 * ch1 + 1 == a || 2 * ch1 - 1 == a){
_tf.appendText(m.toString() + "\t" + n.toString() + "\n");
// _tf.appendText((ch1 * ch2).toString() + "\n");
p = 2 * (a + ch1);
if(p < N)sum += p;
}
if(2 * ch2 + 1 == a || 2 * ch2 - 1 == a){
_tf.appendText(m.toString() + "\t" + n.toString() + "\n");
// _tf.appendText((ch1 * ch2).toString() + "\n");
p = 2 * (a + ch2);
if(p < N)sum += p;
}
}
}
return sum;
}
private static function GCD(a : int, b : int) : int
{
return b == 0 ? a : GCD(b, a % b);
}
}
}