鱼C论坛

 找回密码
 立即注册
查看: 3335|回复: 10

题目60:找出一个5个质数的集合,该集合中每两个质数相连接都能产生一个素数

[复制链接]
发表于 2015-6-18 23:51:29 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x

Prime pair sets

The primes 3, 7, 109, and 673, are quite remarkable. By taking any two primes and concatenating them in any order the result will always be prime. For example, taking 7 and 109, both 7109 and 1097 are prime. The sum of these four primes, 792, represents the lowest sum for a set of four primes with this property.

Find the lowest sum for a set of five primes for which any two primes concatenate to produce another prime.

题目:

质数 3, 7, 109, 和 673 是值得注意的。将其中任意两个质数以任何顺序相连接产生的结果都是质数。例如,取 7 和 109,连接而成的 7109 和 1097 都是质数。这四个质数的和是 792,这也是满足这个性质的四个质数集合的最小总和。

找出满足这个性质的五个质数的集合中,集合数之和最小的。算出这个最小的和。


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-8-31 13:08:30 | 显示全部楼层
Mark
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-9-29 05:21:55 | 显示全部楼层
本帖最后由 jerryxjr1220 于 2016-10-14 09:34 编辑

Result = 26033, in 36.276000 s
  1. #!/usr/bin/env python
  2. """
  3. q060
  4. Algorithm (by iwek7, from forum):
  5. 1. Generate prime list up to N. Remove 2 and 5 from list since they are trivial.
  6.    Call the list prime_list.
  7. 2. Create an empty list all_list, to contain lists of prime pairs.
  8. 3. For each prime, ci, in prime_list, do
  9.    a. create an empty new_list to contain newly found lists of prime pairs
  10.    b. for each list l in all_list, do
  11.       i. Test if ALL primes in l form prime pair with ci.
  12.       ii. If it does,
  13.           1. Create a copy of list l, call it cl
  14.           2. Append ci to this cl
  15.           3. If length of cl >= LEN, solution found.
  16.           4. Append cl to new_list
  17.    c. Append all lists in new_list to all_list
  18.    d. Append [ci] to all_list
  19. Optimisation:
  20. 1. Create a is_prime_table to store the flag if a given prime pairs are prime or not. This
  21.    is to avoid primality test for a given prime pair.
  22. 2. Use a faster prime generation algorithm.
  23. 3. Use a faster primality test algorithm, rather than generating list of primes and test
  24.    if a prime pair is in the list or not.
  25. """
  26. import time
  27. import numpy as np
  28. def getPrime(n):
  29.         primes = [True]*n
  30.         primes[0], primes[1] = False, False
  31.         for (i,prime) in enumerate(primes):
  32.                 if prime:
  33.                         for j in range(i*i,n,i):
  34.                                 primes[j] = False
  35.         return primes

  36. def is_prime(n):
  37.         factor = 3
  38.         if n == 2:
  39.                 return True
  40.         if (n%2 == 0):
  41.                 return False
  42.         while factor * factor <= n:
  43.                 if n % factor == 0:
  44.                         return False
  45.                 factor += 2
  46.         return True

  47. def test_cat(prime_set, ci, i, lut):
  48.     for j, cj in prime_set:
  49.         if lut[i][j] == 0:
  50.             cat1 = int(str(ci) + str(cj))
  51.             cat2 = int(str(cj) + str(ci))
  52.             isprime = is_prime(cat1) and is_prime(cat2)
  53.             lut[i][j] = 1 if isprime else -1
  54.             lut[j][i] = 1 if isprime else -1
  55.         if lut[i][j] == -1:
  56.             return False
  57.     return True

  58. def solve_q060(prime, LEN):
  59.     all_list = list()
  60.     for i, ci in enumerate(prime):
  61.         new_list = list()
  62.         for l in all_list:
  63.             if test_cat(l, ci, i, is_prime_table):
  64.                 new_cand = list(l)
  65.                 new_cand.append((i, ci))
  66.                 if len(new_cand) >= LEN:
  67.                     return new_cand
  68.                 new_list.append(new_cand)
  69.         all_list.extend(new_list)
  70.         all_list.append([(i, ci)])
  71.     return None

  72. primes = getPrime(100000)
  73. UPPER = 10000
  74. LEN = 5
  75. tic = time.time()
  76. prime_cand = []
  77. pl = getPrime(UPPER)
  78. for (m,trueprime) in enumerate(pl):
  79.         if trueprime:
  80.                 prime_cand.append(m)
  81. prime_cand.remove(2)
  82. prime_cand.remove(5)
  83. prime_len = len(prime_cand)
  84. res_list = []
  85. is_prime_table = np.zeros((prime_len, prime_len))
  86. res_list = solve_q060(prime_cand, LEN)
  87. res_list = [c[1] for c in res_list]
  88. toc = time.time()
  89. if res_list:
  90.     res = sum(res_list)
  91.     print "Result = %d, in %f s" % (res, toc - tic)
  92. else:
  93.     print "Not found, try increase prime numbers."
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2016-10-13 16:31:20 | 显示全部楼层
递归算法,20秒不到可以出结果:
13
5197
5701
6733
8389
[Finished in 19.3s]
  1. def is_prime(n):
  2.     factor = 2
  3.     while factor * factor <= n:
  4.         if n % factor == 0:
  5.             return False
  6.         factor += 1
  7.     return True

  8. def is_valid_pair(n, m):
  9.     return is_prime(int(str(n) + str(m))) and is_prime(int(str(m) + str(n)))

  10. def check_comb(nb_chosen, indices):
  11.     if nb_chosen == NB_TO_CHOOSE:
  12.         for i in indices:
  13.             print(prime_list[i])
  14.         exit()
  15.     start = -1
  16.     if nb_chosen > 0:
  17.         start = indices[nb_chosen - 1]
  18.     for i in range(start + 1, nb_primes):
  19.         valid = True
  20.         for j in range(nb_chosen):
  21.             if not is_valid_pair(prime_list[i], prime_list[indices[j]]):
  22.                 valid = False
  23.                 break
  24.         if valid:
  25.             indices[nb_chosen] = i
  26.             check_comb(nb_chosen + 1, indices)

  27. UPPER_BOUND = 10 ** 4
  28. NB_TO_CHOOSE = 5
  29. prime_list = []
  30. prime = [True] * UPPER_BOUND

  31. for i in range(2, UPPER_BOUND):
  32.     if prime[i]:
  33.         prime_list.append(i)
  34.         for j in range(i + i, UPPER_BOUND, i):
  35.             prime[j] = False

  36. nb_primes = len(prime_list)
  37. indices = [-1] * NB_TO_CHOOSE
  38. check_comb(0, indices)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2016-12-28 22:07:27 | 显示全部楼层
另外还有一种字典法,不过用时也不短,关键生成字典的时间比较长。
方法多多
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-1-19 09:27:46 | 显示全部楼层
  1. # encoding:utf-8
  2. # 寻找特殊质数  3,7,109,673已任何形式组合比如37  73  7109  1097 都是质数
  3. # 寻找满足条件的  和最小的五个质数,满足该条件
  4. from time import time
  5. from math import sqrt
  6. def getPrimes(N):
  7.     primes = [True] * N
  8.     primes[0], primes[1] = False, False
  9.     for i, prime in enumerate(primes):
  10.         if prime:
  11.             for j in range(i * i, N, i):
  12.                 primes[j] = False
  13.     return [k for k, p in enumerate(primes) if p ]
  14. def isPrime(n, l_pr):
  15.     # 不考虑1
  16.     if n < 4:
  17.         return True
  18.     if n % 2 == 0 or n % 3 == 0 :
  19.         return False
  20.     t = int(sqrt(n))
  21.     for i in l_pr:
  22.         if i > t:
  23.             return True
  24.         if n % i == 0:
  25.             return False
  26.     return True
  27. def findNums(l_pr, l_primes, N, l_result):
  28.     if N == 1 and len(l_result) < 1:
  29.         l_result.append(min(l_primes))
  30.     else:
  31.         if len(l_result) < N:
  32.             findNums(l_pr, l_primes, N - 1, l_result)
  33.             for i in [x for x in l_primes if x > max(l_result)]:
  34.                 flag = True
  35.                 for j in l_result:
  36.                     if not (isPrime(int(str(j) + str(i)), l_pr)  
  37.                             and isPrime(int(str(i) + str(j)), l_pr)):
  38.                         flag = False
  39.                         break
  40.                 if flag:
  41.                     l_result.append(i)
  42.                     return         
  43. def euler060(N=10000):
  44.     l_primes = getPrimes(N)
  45.     l_result = [3]
  46.     l_pr = [x for x in l_primes]
  47.     findNums(l_pr, l_primes, 5, l_result)
  48.     while len(l_result) < 5:
  49.         l_primes = [i for i in l_pr if i > max(l_result)]
  50.         l_result.remove(max(l_result))
  51.         findNums(l_pr, l_primes, 5, l_result)
  52.     print(l_result)
  53. if __name__ == '__main__':
  54.     start = time()
  55.     euler060()
  56.     print('cost %.6f sec' % (time() - start))
复制代码

[13, 5197, 5701, 6733, 8389]
cost 11.987199 sec
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2017-10-2 00:07:49 | 显示全部楼层
用的matlab
结果是
          13        5197        5701        6733        8389

时间已过 3.885805 秒。
>>


第二组的话
           7        1237        2341       12409       18433
          13        5197        5701        6733        8389

时间已过 16.375198 秒。
>>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-10-24 21:55:30 | 显示全部楼层
是谁说 mathematica代码好理解的   下面这段代码,能理解算我输  答案26033
  1. pp[a_, b_] := FromDigits[IntegerDigits@a~Join~IntegerDigits@b]
  2. Total[FindClique[
  3.     Graph[#[[1]] <-> #[[2]] & /@
  4.       Select[Prime@Range@PrimePi@10000~Subsets~{2},
  5.        PrimeQ[#[[1]]~pp~#[[2]]] && PrimeQ[#[[2]]~pp~#[[1]]] &]]][[
  6.    1]]]
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-11-1 10:41:08 | 显示全部楼层
感觉很麻烦,但还是出来的不算太慢
  1. def prime(n):
  2.     if n==2 or n==3:
  3.         return True
  4.     else:
  5.         if n%2==0:
  6.             return False
  7.         else:
  8.             for i in range(3,int(n**0.5)+1,2):
  9.                 if n%i == 0:
  10.                     return False
  11.             return True

  12. def lj(n,m):#连接两个数字
  13.     return prime(int(str(n)+str(m))) and prime(int(str(m)+str(n)))

  14. l1 = list(i for i in range(2,10000) if prime(i))
  15. count = 0
  16. for i in l1:
  17.     for j in l1:
  18.         if lj(i,j):
  19.             for k in l1:
  20.                 if lj(i,k) and lj(j,k):
  21.                     for l in l1:
  22.                         if lj(i,l) and lj(j,l) and lj(k,l):
  23.                             for m in l1:
  24.                                 if lj(i,m) and lj(j,m) and lj(k,m) and lj(l,m):
  25.                                     count += 1
  26.                                     print(i,j,k,l,m)
  27.                                 if count==1:
  28.                                     exit()
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-9 12:59:36 | 显示全部楼层
本帖最后由 guosl 于 2022-1-9 22:23 编辑
  1. /*
  2. 答案:26033
  3. 耗时:30.2571秒(单核)
  4.       5.08559秒(六核)
  5. */
  6. #include <iostream>
  7. #include <vector>
  8. #include <cstring>
  9. #include <cstdlib>
  10. #include <cmath>
  11. #include <omp.h>
  12. using namespace std;

  13. const int N = 30000;//搜索范围一定要大于那个最小和才行,否则从理论上来讲不能得到全局最小和的
  14. const int M = 1000000;
  15. const int INF = 0x7fffffff;

  16. char cp[M + 4];
  17. vector<int> vp;

  18. bool chkbp(long long n)//判别数n是否是一个素数
  19. {
  20.   if ((n & 1) == 0)
  21.     return false;
  22.   int d = (int)sqrt((double)n);
  23.   for (int i = 1; i < (int)vp.size() && vp[i] <= d; ++i)
  24.   {
  25.     if (n%vp[i] == 0)
  26.       return false;
  27.   }
  28.   return true;
  29. }

  30. bool chk(int p1, int p2)//检查p1p2与p2p1是否是素数
  31. {
  32.   char str1[8], str2[8];
  33.   _itoa_s(p1, str1, 10);
  34.   _itoa_s(p2, str2, 10);
  35.   char str[12];
  36.   strcpy_s(str, str1);
  37.   strcat_s(str, str2);
  38.   long long n = atoll(str);
  39.   if (n < M)
  40.   {
  41.     if (cp[n] == 0)
  42.       return false;
  43.   }
  44.   else
  45.   {
  46.     if (!chkbp(n))
  47.       return false;
  48.   }
  49.   strcpy_s(str, str2);
  50.   strcat_s(str, str1);
  51.   n = atoll(str);
  52.   if (n < M)
  53.   {
  54.     if (cp[n] == 0)
  55.       return false;
  56.   }
  57.   return chkbp(n);
  58. }

  59. int main(void)
  60. {
  61.   double t = omp_get_wtime();
  62.   memset(cp + 2, 1, (M + 2) * sizeof(char));
  63.   for (int i = 2; i <= (int)sqrt((double)M); ++i)
  64.   {
  65.     if (cp[i] == 0)
  66.       continue;
  67.     for (int j = i * i; j <= M; j += i)
  68.       cp[j] = 0;
  69.   }
  70.   vp.push_back(2);
  71.   for (int i = 3; i <= N; i += 2)
  72.   {
  73.     if (cp[i] == 1)
  74.       vp.push_back(i);
  75.   }
  76.   volatile int nMinSum = INF, k = 1;
  77.   volatile bool bContinue = true;
  78. #pragma omp parallel shared(k,bContinue,vp,nMinSum)
  79.   while (bContinue)
  80.   {
  81.     if (k >= nMinSum || k >= (int)vp.size())
  82.     {
  83.       bContinue = false;
  84. #pragma omp flush(bContinue)
  85.       break;
  86.     }
  87.     int i0;
  88. #pragma omp critical(c1)
  89.     {
  90.       i0 = k;
  91.       ++k;
  92.     }
  93.     for (int i1 = i0 + 1; i1 < (int)vp.size(); ++i1)
  94.     {
  95.       if (vp[i0] + vp[i1] >= nMinSum)
  96.         break;
  97.       if (!chk(vp[i0], vp[i1]))
  98.         continue;
  99.       for (int i2 = i1 + 1; bContinue && i2 < (int)vp.size(); ++i2)
  100.       {
  101.         if (vp[i0] + vp[i1] + vp[i2] >= nMinSum)
  102.           break;
  103.         if (!(chk(vp[i0], vp[i2]) && chk(vp[i1], vp[i2])))
  104.           continue;
  105.         for (int i3 = i2 + 1; bContinue && i3 < (int)vp.size(); ++i3)
  106.         {
  107.           if (vp[i0] + vp[i1] + vp[i2] + vp[i3] >= nMinSum)
  108.             break;
  109.           if (!(chk(vp[i0], vp[i3]) && chk(vp[i1], vp[i3]) && chk(vp[i2], vp[i3])))
  110.             continue;
  111.           for (int i4 = i3 + 1; bContinue && i4 < (int)vp.size(); ++i4)
  112.           {
  113.             if (vp[i0] + vp[i1] + vp[i2] + vp[i3] + vp[i4] >= nMinSum)
  114.               break;
  115.             if (!(chk(vp[i0], vp[i4]) && chk(vp[i1], vp[i4]) && chk(vp[i2], vp[i4]) && chk(vp[i3], vp[i4])))
  116.               continue;
  117.             int nS = vp[i0] + vp[i1] + vp[i2] + vp[i3] + vp[i4];
  118.             if (nMinSum > nS)
  119. #pragma omp critical(c2)
  120.               nMinSum = nS;
  121.           }
  122.         }
  123.       }
  124.     }
  125.   }
  126.   t = omp_get_wtime() - t;
  127.   cout << nMinSum << endl << t << endl;
  128.   return 0;
  129. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-10-29 15:45:16 | 显示全部楼层
  1. import time as t
  2. import math

  3. start = t.perf_counter()


  4. def check_prime(a_num):
  5.     is_prime = True
  6.     for prime_i in range(2, int(math.sqrt(a_num) + 1)):
  7.         if a_num % prime_i == 0:
  8.             is_prime = False
  9.     return is_prime


  10. def is_exchangeable(prime_list):
  11.     length_list = len(prime_list)
  12.     for each_prime1 in range(length_list - 1):
  13.         for each_prime2 in range(each_prime1 + 1, length_list):
  14.             new_num_1 = int(str(prime_list[each_prime1]) + str(prime_list[each_prime2]))
  15.             new_num_2 = int(str(prime_list[each_prime2]) + str(prime_list[each_prime1]))
  16.             if not check_prime(new_num_1) or not check_prime(new_num_2):
  17.                 return False
  18.     return True


  19. def p60():
  20.     primes = []
  21.     prime_range = 10000
  22.     for numbers in range(2, prime_range):
  23.         if check_prime(numbers):
  24.             primes.append(numbers)
  25.     primes.remove(2)
  26.     primes.remove(5)
  27.     test_range = len(primes)
  28.     for prime1 in range(test_range):
  29.         for prime2 in range(prime1 + 1, test_range):
  30.             cur_plist = [primes[prime1], primes[prime2]]
  31.             if is_exchangeable(cur_plist):
  32.                 for prime3 in range(prime2 + 1, test_range):
  33.                     cur_plist = [primes[prime1], primes[prime2], primes[prime3]]
  34.                     if is_exchangeable(cur_plist):
  35.                         for prime4 in range(prime3 + 1, test_range):
  36.                             cur_plist = [primes[prime1], primes[prime2], primes[prime3], primes[prime4]]
  37.                             if is_exchangeable(cur_plist):
  38.                                 for prime5 in range(prime4 + 1, test_range):
  39.                                     cur_plist = [primes[prime1], primes[prime2], primes[prime3],
  40.                                                  primes[prime4], primes[prime5]]
  41.                                     if is_exchangeable(cur_plist):
  42.                                         return cur_plist


  43. answer = p60()
  44. print(answer)
  45. print(sum(answer))
  46. print("It costs %f s" % (t.perf_counter() - start))
复制代码



[13, 5197, 5701, 6733, 8389]
26033
It costs 51.725813 s
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 02:55

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表