Project Euler 200
@see http://projecteuler.net/index.php?section=problems&id=200
♥0 |
Line 200 |
Modified 2010-02-07 12:36:16 |
MIT License
archived:2017-03-30 04:41:28
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/jjGm
*/
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.utils.getTimer;
// @see http://projecteuler.net/index.php?section=problems&id=200
public class Euler200 extends Sprite {
private var _tf : TextField;
public function Euler200() {
_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 solve() : Number
{
var i : uint, j : uint;
var primes : Array = sieveEratosthenes(250000);
var tops : Array = [];
var ct : uint = 0;
// 小さい数を列挙しやすいものから消していく。
// 2, 5の倍数はprime-proofの判定が1の位だけでいいので、
// それを先に洗う。
var p : uint;
var n : Number;
var base : Number;
var f : Boolean;
var x : uint;
// p^2 * 2^3
for each(p in primes){
n = p * p * 8;
if(n.toString().indexOf("200") > -1){
base = n - (n % 10);
f = true;
for each(x in [1, 3, 7, 9]){
if(isPrime(base + x)){
f = false;
break;
}
}
if(!f)continue;
ct++;
tops.push({number:n, p2:p, p3:2});
if(ct == 200)break;
}
}
// 2^2 * p^3
for each(p in primes){
n = p * p * p * 4;
if(n > tops[199].number)break;
if(n.toString().indexOf("200") > -1){
base = n - (n % 10);
f = true;
for each(x in [1, 3, 7, 9]){
if(isPrime(base + x)){
f = false;
break;
}
}
if(!f)continue;
tops.push({number:n, p2:2, p3:p});
}
}
tops.sortOn("number", Array.NUMERIC);
tops = tops.slice(0, 200);
// p^2 * 5^3
for each(p in primes){
if(p == 2 || p == 5)continue;
n = p * p * 125;
if(n > tops[199].number)break;
if(n.toString().indexOf("200") > -1){
base = n - (n % 10);
f = true;
for each(x in [1, 3, 7, 9]){
if(isPrime(base + x)){
f = false;
break;
}
}
if(!f)continue;
ct++;
tops.push({number:n, p2:p, p3:5});
if(ct == 200)break;
}
}
tops.sortOn("number", Array.NUMERIC);
tops = tops.slice(0, 200);
printTops(tops);
// 5^2 * p^3
for each(p in primes){
if(p == 2 || p == 5)continue;
n = p * p * p * 25;
if(n > tops[199].number)break;
if(n.toString().indexOf("200") > -1){
base = n - (n % 10);
f = true;
for each(x in [1, 3, 7, 9]){
if(isPrime(base + x)){
f = false;
break;
}
}
if(!f)continue;
ct++;
tops.push({number:n, p2:5, p3:p});
if(ct == 200)break;
}
}
tops.sortOn("number", Array.NUMERIC);
tops = tops.slice(0, 200);
printTops(tops);
// p^2 * q^3
// prime-proofの判定もしているが、実際にprime-proofになるのは
// ひとつもなかった。
var q : uint;
var r : Number;
var gct : uint = 0;
for each(p in primes){
if(p == 2 || p == 5)continue;
for each(q in primes){
if(q == 2 || q == 5 || p == q)continue;
n = p * p * q * q * q;
if(n > tops[199].number)break;
if(n.toString().indexOf("200") > -1){
base = n - (n % 10);
f = true;
for each(x in [1, 3, 7, 9]){
if(isPrime(base + x)){
f = false;
break;
}
}
if(!f)continue;
for(r = 10;r < n;r *= 10){
base = n - uint((n % (r * 10)) / r) * r;
for(i = 0;i <= 9;i++){
if(isPrime(base + i * r)){
f = false;
break;
}
}
if(!f)break;
}
if(!f)continue;
tr(n, p, q);
gct++;
}
}
}
tr(gct);
return 0;
}
private function printTops(tops : Array) : void
{
for(var i : uint = 0;i < tops.length;i++){
var o : Object = tops[i];
tr(i, o.number, o.p2, o.p3);
}
}
private var _cache : Object = {};
private function isPrime(n : Number) : Boolean
{
if(n <= 1)return false;
if(n % 2 == 0)return n == 2;
if(_cache[n])return _cache[n] == 1;
var sq : int = Math.sqrt(n);
for(var i : int = 3;i <= sq;i+=2){
if(n % i == 0){
_cache[n] = -1;
return false;
}
}
_cache[n] = 1;
return true;
}
private function sieveEratosthenes(n : int) : Array
{
var nn : uint = ((n / 2 - 1) >>> 5) + 1;
var ar : Vector.<uint> = new Vector.<uint>(nn);
var i : uint, j : uint;
for(i = 0;i < nn - 1;i++)ar[i] = 0xffffffff;
ar[nn - 1] = (1 << ((n / 2 - 1) & 31)) - 1;
var sq : uint = (Math.sqrt(n) - 3) >>> 1;
for(var p : uint = 0;p <= sq;p++){
if(ar[p >>> 5] & (1 << (p & 31))){
var m : uint = (p << 1) + 3;
var m2 : uint = m << 1;
for(var mm : uint = m * m;mm <= n;mm += m2){
var ind : uint = (mm - 3) >>> 1;
ar[ind >>> 5] &= ~(1 << (ind & 31));
}
}
}
var ret : Array = [2];
for(i = 0;i < nn;i++){
for(j = 0;j <= 31;j++){
if(ar[i] & (1 << j))ret.push((((i << 5) | j) << 1) + 3);
}
}
return ret;
}
private function tr(...o : Array) : void
{
_tf.appendText(o + "\n");
_tf.scrollV = _tf.maxScrollV;
}
}
}