SlideShare a Scribd company logo
1 of 13
+
ProjectEuler134
Prime pair connnection.
ICPC AOJ Meeting 2014/1/12
+
Problem
 連続する素数 p1 = 19, p2 = 23 について考える. 1219 は末尾の
桁が p1 からなり p2 で割り切られる最小の数であることが確か
められる.
 実際, p1 = 3, p2 = 5 を除けば, 全ての p2 > p1 なる連続する素数
のペアについて, 末尾の桁が p1 からなり p2 で割り切られる数
n が存在する. S を n の最小のものであるとする.
 5 ≤ p1 ≤ 1000000 を満たす連続する素数のペア全てに対し ∑ S
を求めよ
+
Solution
 素数のリストprimeListを作成し、しゃくとり法で前から素数リ
ストを見ていく。
 選択した任意の素数p1,p2からp2の倍数で且つ末尾桁がp1と一
致するものを計算する。これをSとする。
 全ての算出数Sの和ΣSを算出する。
+
SourceCode
class Execution {
private int[] primeList;
private long[] resultSet;
public Execution(int limit) {
primeList = new Prime(limit).getPrimPrimeList();
calculation();
}
private void calculation() {
resultSet = new long[primeList.length - 1];
IntStream.range(0, resultSet.length).parallel().forEach(
e -> resultSet[e] = calcB(primeList[e], primeList[e + 1]));
}
private long calcB(int p1, int p2) {
int mask = (int) Math.pow(10, count(p1));
for (long i = p2; i < Long.MAX_VALUE; i += p2) {
if (i % mask == p1) {
return i;
}
}
return -1;
}
private int count(int n) {
int c = 0;
while (n != 0) {
n /= 10;
c++;
}
return c;
}
public long getSum() {
long s = 0;
for (long n : resultSet) {
if (n == -1) {
System.out.println("!!!!!!!!!");
}
s += n;
}
return s;
}
}
+
class Prime {
private boolean[] primeBool;
public Prime(int limit) {
primeBool = new boolean[limit];
calculation();
}
private void calculation() {
Arrays.fill(primeBool, true);
primeBool[0] = false;
primeBool[1] = false;
for (int i = 2; i < primeBool.length; i++) {
if (primeBool[i]) {
for (int j = i + i; j < primeBool.length; j += i)
primeBool[j] = false;
}
}
}
public ArrayList<Integer> getPrimeList() {
ArrayList<Integer> ret = new ArrayList<>();
for (int i = 0; i < primeBool.length; i++) {
if (primeBool[i] && (5 <= i)) {
ret.add(i);
}
}
return ret;
}
public int[] getPrimPrimeList() {
ArrayList<Integer> tmp = getPrimeList();
int[] ret = new int[tmp.size()];
for (int i = 0; i < ret.length; i++) {
ret[i] = tmp.get(i);
}
return ret;
}}
+
Result
18613426663617118
Acceptしました
+
脱線します
高速化しよう
※速いアルゴリズムがあるのはわかってい
るが、総当りを高速化してみる。
+class GPUExecution extends Kernel {
private int[] primeList;
private long[] resultSet;
public GPUExecution(int limit) {
primeList = new Prime(limit).getPrimPrimeList();
resultSet = new long[primeList.length - 1];
}
public void run() {
int index = getGlobalId();
resultSet[index] = calcB(primeList[index], primeList[index + 1]);
}
private long calcB(int p1, int p2) {
int mask = (int) Math.pow(10, count(p1));
for (long i = p2; i < Long.MAX_VALUE; i += p2) {
if (i % mask == p1) {
return i;
}
}
return -1;
}
+ private int count(int n) {
int c = 0;
while (n != 0) {
n /= 10;
c++;
}
return c;
}
public long getSum() {
long s = 0;
for (long n : resultSet) {
if (n == -1) {
System.out.println("!!!!!!!!!");
}
s += n;
}
return s;
}
public int getExecuteSize() {
return resultSet.length;
}
}
GPUExecution gpuExecution = new GPUExecution(1000010);
gpuExecution.execute(gpuExecution.getExecuteSize());
System.out.println(gpuExecution.getSum());
呼び出し元
+
速いアルゴリズム
class FastExecution {
private int[] primeList;
private long[] resultSet;
public FastExecution(int limit) {
primeList = new Prime(limit).getPrimPrimeList();
resultSet = new long[primeList.length];
calculation();
}
private void calculation() {
IntStream.range(0, resultSet.length - 1).parallel().forEach(e -> {
long p1 = primeList[e];
long p2 = primeList[e + 1];
long a = DigitCountFactor(p1);
long b = p2 - p1;
long n = p2;
long[] rs = extended_gcd(a, n);
long x = rs[0] * b % n;
if (x < 0) {
x = n + x;
resultSet[e] = x * a + p1;
}); }
+
private long DigitCountFactor(long number) {
long factor = 1;
while (number > 0) {
factor *= 10;
number /= 10;
}
return factor;
}
private long[] extended_gcd(long a, long b) {
long x = 0;
long lastx = 1;
long y = 1;
long lasty = 0;
while (b != 0) {
long quotient = a / b;
long temp = b;
b = a % b;
a = temp;
temp = x;
x = lastx - quotient * x;
lastx = temp;
temp = y;
y = lasty - quotient * y;
lasty = temp;
}
return new long[]{lastx, lasty, a};
}
public long getSum() {
long s = 0;
for (long n : resultSet) {
if (n == -1) {
System.out.println("!!!!!!!!!");
}
s += n;
}
return s;
}}
+
実行時間の比較
0 20000 40000 60000 80000 100000 120000 140000 160000
CPU
GPU
Fast
CPU GPU Fast
ELAPSEDTIME 143275 87500 877
+
Sourcecode
http://ideone.com/8EhLrS

More Related Content

Viewers also liked

InsideRIA Outlook for 2009
InsideRIA Outlook for 2009InsideRIA Outlook for 2009
InsideRIA Outlook for 2009
AndreCharland
 
Uspto reexamination request - update - may 09 to may 16, 2011 - invn tree
Uspto   reexamination request - update - may  09 to may 16, 2011 - invn treeUspto   reexamination request - update - may  09 to may 16, 2011 - invn tree
Uspto reexamination request - update - may 09 to may 16, 2011 - invn tree
InvnTree IP Services Pvt. Ltd.
 
The existing offer baggio
The existing offer baggioThe existing offer baggio
The existing offer baggio
foxasher
 
Structure of living organism
Structure of living organismStructure of living organism
Structure of living organism
Anbu Azhagan
 

Viewers also liked (13)

InsideRIA Outlook for 2009
InsideRIA Outlook for 2009InsideRIA Outlook for 2009
InsideRIA Outlook for 2009
 
Top 10 Tips from Millionaires
Top 10 Tips from MillionairesTop 10 Tips from Millionaires
Top 10 Tips from Millionaires
 
dr_4
dr_4dr_4
dr_4
 
Time Management: for establishing and controlling your priorities
Time Management: for establishing and controlling your prioritiesTime Management: for establishing and controlling your priorities
Time Management: for establishing and controlling your priorities
 
2012 Acura RL Montgomery Alabama Brochure
2012 Acura RL Montgomery Alabama Brochure2012 Acura RL Montgomery Alabama Brochure
2012 Acura RL Montgomery Alabama Brochure
 
Uspto reexamination request - update - may 09 to may 16, 2011 - invn tree
Uspto   reexamination request - update - may  09 to may 16, 2011 - invn treeUspto   reexamination request - update - may  09 to may 16, 2011 - invn tree
Uspto reexamination request - update - may 09 to may 16, 2011 - invn tree
 
Programa sobre Trastorno Bipolar del 26 ECNP Barcelona 2013
Programa sobre Trastorno Bipolar del 26 ECNP Barcelona 2013Programa sobre Trastorno Bipolar del 26 ECNP Barcelona 2013
Programa sobre Trastorno Bipolar del 26 ECNP Barcelona 2013
 
C:\Fakepath\Ivy W6 A1 Final Project Beads Com
C:\Fakepath\Ivy W6 A1 Final Project Beads ComC:\Fakepath\Ivy W6 A1 Final Project Beads Com
C:\Fakepath\Ivy W6 A1 Final Project Beads Com
 
The existing offer baggio
The existing offer baggioThe existing offer baggio
The existing offer baggio
 
East Midland broadband mapping
East Midland broadband mappingEast Midland broadband mapping
East Midland broadband mapping
 
2012 Civic Burien Honda
2012 Civic Burien Honda2012 Civic Burien Honda
2012 Civic Burien Honda
 
Strom water harvesting
Strom water harvestingStrom water harvesting
Strom water harvesting
 
Structure of living organism
Structure of living organismStructure of living organism
Structure of living organism
 

Similar to Meeting18 (7)

C++0x in programming competition
C++0x in programming competitionC++0x in programming competition
C++0x in programming competition
 
ぱっと見でわかるC++11
ぱっと見でわかるC++11ぱっと見でわかるC++11
ぱっと見でわかるC++11
 
AtCoder Regular Contest 030 解説
AtCoder Regular Contest 030 解説AtCoder Regular Contest 030 解説
AtCoder Regular Contest 030 解説
 
C++0x in programming competition
C++0x in programming competitionC++0x in programming competition
C++0x in programming competition
 
DP特集
DP特集DP特集
DP特集
 
予想.pdf
予想.pdf予想.pdf
予想.pdf
 
第二回ミーティングスライド
第二回ミーティングスライド第二回ミーティングスライド
第二回ミーティングスライド
 

More from nullzine (11)

Meeting13
Meeting13Meeting13
Meeting13
 
Meeting12
Meeting12Meeting12
Meeting12
 
Meeting11
Meeting11Meeting11
Meeting11
 
Meeting10
Meeting10Meeting10
Meeting10
 
Meeting9
Meeting9Meeting9
Meeting9
 
Meeting8
Meeting8Meeting8
Meeting8
 
Meeting7
Meeting7Meeting7
Meeting7
 
Meeting6
Meeting6Meeting6
Meeting6
 
Meeting5
Meeting5Meeting5
Meeting5
 
Meeting4
Meeting4Meeting4
Meeting4
 
Meeting1
Meeting1Meeting1
Meeting1
 

Meeting18

  • 2. + Problem  連続する素数 p1 = 19, p2 = 23 について考える. 1219 は末尾の 桁が p1 からなり p2 で割り切られる最小の数であることが確か められる.  実際, p1 = 3, p2 = 5 を除けば, 全ての p2 > p1 なる連続する素数 のペアについて, 末尾の桁が p1 からなり p2 で割り切られる数 n が存在する. S を n の最小のものであるとする.  5 ≤ p1 ≤ 1000000 を満たす連続する素数のペア全てに対し ∑ S を求めよ
  • 4. + SourceCode class Execution { private int[] primeList; private long[] resultSet; public Execution(int limit) { primeList = new Prime(limit).getPrimPrimeList(); calculation(); } private void calculation() { resultSet = new long[primeList.length - 1]; IntStream.range(0, resultSet.length).parallel().forEach( e -> resultSet[e] = calcB(primeList[e], primeList[e + 1])); } private long calcB(int p1, int p2) { int mask = (int) Math.pow(10, count(p1)); for (long i = p2; i < Long.MAX_VALUE; i += p2) { if (i % mask == p1) { return i; } } return -1; } private int count(int n) { int c = 0; while (n != 0) { n /= 10; c++; } return c; } public long getSum() { long s = 0; for (long n : resultSet) { if (n == -1) { System.out.println("!!!!!!!!!"); } s += n; } return s; } }
  • 5. + class Prime { private boolean[] primeBool; public Prime(int limit) { primeBool = new boolean[limit]; calculation(); } private void calculation() { Arrays.fill(primeBool, true); primeBool[0] = false; primeBool[1] = false; for (int i = 2; i < primeBool.length; i++) { if (primeBool[i]) { for (int j = i + i; j < primeBool.length; j += i) primeBool[j] = false; } } } public ArrayList<Integer> getPrimeList() { ArrayList<Integer> ret = new ArrayList<>(); for (int i = 0; i < primeBool.length; i++) { if (primeBool[i] && (5 <= i)) { ret.add(i); } } return ret; } public int[] getPrimPrimeList() { ArrayList<Integer> tmp = getPrimeList(); int[] ret = new int[tmp.size()]; for (int i = 0; i < ret.length; i++) { ret[i] = tmp.get(i); } return ret; }}
  • 8. +class GPUExecution extends Kernel { private int[] primeList; private long[] resultSet; public GPUExecution(int limit) { primeList = new Prime(limit).getPrimPrimeList(); resultSet = new long[primeList.length - 1]; } public void run() { int index = getGlobalId(); resultSet[index] = calcB(primeList[index], primeList[index + 1]); } private long calcB(int p1, int p2) { int mask = (int) Math.pow(10, count(p1)); for (long i = p2; i < Long.MAX_VALUE; i += p2) { if (i % mask == p1) { return i; } } return -1; }
  • 9. + private int count(int n) { int c = 0; while (n != 0) { n /= 10; c++; } return c; } public long getSum() { long s = 0; for (long n : resultSet) { if (n == -1) { System.out.println("!!!!!!!!!"); } s += n; } return s; } public int getExecuteSize() { return resultSet.length; } } GPUExecution gpuExecution = new GPUExecution(1000010); gpuExecution.execute(gpuExecution.getExecuteSize()); System.out.println(gpuExecution.getSum()); 呼び出し元
  • 10. + 速いアルゴリズム class FastExecution { private int[] primeList; private long[] resultSet; public FastExecution(int limit) { primeList = new Prime(limit).getPrimPrimeList(); resultSet = new long[primeList.length]; calculation(); } private void calculation() { IntStream.range(0, resultSet.length - 1).parallel().forEach(e -> { long p1 = primeList[e]; long p2 = primeList[e + 1]; long a = DigitCountFactor(p1); long b = p2 - p1; long n = p2; long[] rs = extended_gcd(a, n); long x = rs[0] * b % n; if (x < 0) { x = n + x; resultSet[e] = x * a + p1; }); }
  • 11. + private long DigitCountFactor(long number) { long factor = 1; while (number > 0) { factor *= 10; number /= 10; } return factor; } private long[] extended_gcd(long a, long b) { long x = 0; long lastx = 1; long y = 1; long lasty = 0; while (b != 0) { long quotient = a / b; long temp = b; b = a % b; a = temp; temp = x; x = lastx - quotient * x; lastx = temp; temp = y; y = lasty - quotient * y; lasty = temp; } return new long[]{lastx, lasty, a}; } public long getSum() { long s = 0; for (long n : resultSet) { if (n == -1) { System.out.println("!!!!!!!!!"); } s += n; } return s; }}
  • 12. + 実行時間の比較 0 20000 40000 60000 80000 100000 120000 140000 160000 CPU GPU Fast CPU GPU Fast ELAPSEDTIME 143275 87500 877

Editor's Notes

  1. AOJ0222