问题的来源
顺便说一下,CSDN markdown编辑器的改版带来诸多不爽。
言归正传,网上有人以征婚名义出了两道素数题,虽然八成又是一个做微商、卖茶叶或其他山货的营销手段,必然带有欺骗性(如果是愚人节玩笑,算我没说),但是其中的问题还是有好事者用各种工具给出答案的。实际上,看遍各种工具,mathematica最为强大。
问题直接抽象出来就是两道简单的素数问题:
- 分解出 7140229933 的两个素数因子;
- 找出只有两个素数因子的形如: 6541367xxx 的素数,并分解它(们)的素数因子
求解
直接跳过网络上其它任何求解方法,用mathematica:
-
直接输入代码如下得到第一个问题答案:
FactorInteger[7140229933] // Flatten[Delete[#, Position[#, 1]]] &
秒出结果:
{83777, 85229}
-
第二个问题的答案不妨稍作分析
形如“6541367xxx”的数,其实就是“6541367000~6541367999”之间(包含两端)的1000个数字,暴力穷举方式逐个验证素数因子的个数,然后对个数为2的逐个拿出来即可,答案不唯一、而且技术难度跟第一题类似,这是让我觉得这“征婚”可能是微商卖茶叶或山货的重要原因。
评论区“土肥圆”网友给出了一个更好的解法,总之我眼睛为之一亮,我找的那些代码尽可以扔垃圾堆里里。
Select[Range[1000] + 6541367*1000 - 1, DivisorSigma[0, #] == 4 &] // Timing
在我电脑上0.05秒不到找出所有的这151个整数。主要是用到了Mathematica中内置的整数和数论有关的特殊函数。DivisorSigma[k,n] 可以从帮助文档中查看,可以找出整数n的全部因子(包括1和自身及其它可能存在的素因子)的k次幂的和。如果k=0, 找到的就是不同素数因子的个数加2. 点到这里就可以为止了。
先统计满足条件的数有多少个:
((PrimeNu /@ Range[6541367000, 6541367999]) //Count[#, x_ /; x == 2] &) - ((((FactorInteger /@ numList) // Flatten[#, 1] &)[[;; , 2]]) // Count[#, x_ /; x >= 2] &)
得到 151;
再找出这些数(实际上上面统计代码是先找到这些数,不过输出的形式不同而已)在整个自然数列中的位置:
index=((First@Dimensions@FactorInteger@#) & /@
Range[6541367000, 6541367999]) // Position[#, 2] &
使用计算出的位置索引,找出这些数
numList=Range[6541367000, 6541367999] // Extract[#, index] &
结果是:
{6541367003, 6541367005, 6541367011, 6541367017, 6541367023, \
6541367037, 6541367038, 6541367039, 6541367043, 6541367053, \
6541367059, 6541367061, 6541367071, 6541367077, 6541367113, \
6541367114, 6541367117, 6541367127, 6541367135, 6541367137, \
6541367141, 6541367153, 6541367159, 6541367167, 6541367169, \
6541367171, 6541367173, 6541367177, 6541367179, 6541367186, \
6541367189, 6541367201, 6541367207, 6541367218, 6541367239, \
6541367241, 6541367254, 6541367257, 6541367258, 6541367267, \
6541367277, 6541367289, 6541367293, 6541367297, 6541367309, \
6541367311, 6541367317, 6541367323, 6541367341, 6541367353, \
6541367359, 6541367369, 6541367374, 6541367379, 6541367402, \
6541367413, 6541367419, 6541367421, 6541367429, 6541367431, \
6541367433, 6541367438, 6541367439, 6541367446, 6541367447, \
6541367451, 6541367459, 6541367461, 6541367471, 6541367473, \
6541367477, 6541367479, 6541367483, 6541367485, 6541367489, \
6541367491, 6541367497, 6541367501, 6541367503, 6541367521, \
6541367523, 6541367531, 6541367541, 6541367545, 6541367551, \
6541367554, 6541367557, 6541367563, 6541367577, 6541367597, \
6541367599, 6541367603, 6541367605, 6541367609, 6541367611, \
6541367617, 6541367619, 6541367626, 6541367627, 6541367649, \
6541367654, 6541367662, 6541367663, 6541367669, 6541367674, \
6541367681, 6541367689, 6541367707, 6541367719, 6541367727, \
6541367731, 6541367738, 6541367743, 6541367747, 6541367758, \
6541367761, 6541367765, 6541367771, 6541367773, 6541367782, \
6541367793, 6541367795, 6541367806, 6541367829, 6541367843, \
6541367845, 6541367851, 6541367857, 6541367871, 6541367873, \
6541367879, 6541367883, 6541367887, 6541367901, 6541367906, \
6541367909, 6541367915, 6541367921, 6541367923, 6541367926, \
6541367927, 6541367929, 6541367933, 6541367942, 6541367951, \
6541367959, 6541367962, 6541367963, 6541367971, 6541367989, \
6541367995}
分解它们的素数因子:
Sort /@ ((numList // FactorInteger) // Delete[#, Position[#, 1]] & //
Flatten // ArrayReshape[#, {194, 2}] &) // MatrixForm
得到结果如下:
⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡23537415419321417731320359331753217357323118393742313208911192443927285740819211323124093332707263331883559012415107529011379723272693735332326203311947583910131578975670491771908111133833547219973431133757114971133217322580497124431693794213988729711921070957980121123523113515671930935416138681324910951123247487172977213331135284407261130827340117679370315954553712071172180455679327068351946140721804556815031820813213012180455687211011841934481011123422021327068355738478630121804557091308273427896077692844072675525271767937071546057218045572331313395946697433442824832676613270683593934481027228959316025332706836095946697492180455747327068362721101184732706836291599356321804557592180455763199999248721191976243974081171170172714260312808631236534774720767436777327068368721804557933270683701934481059243173512180455807896077731234220272180455811327068371921804558133270683723105454921804558175946697696907463112028964574214166476173498511934481069130827349797561384786323934481071342821594669773503182117218045584178811657218045584713082735091391780333270683777344282503674367792180455859151771875031821231767937191308273521934481087568963578882092180455873327068381338478633121804558833270683827327068383111268792131939327068383714766067386377393448110169433921804559096616133270683869673673334428251332706838796108291308273553819713100174332706838912180455931130827355932706839032180455943578882111308273569417445333877321804559571209125310723553921804559617535272180455967327068395313320113082735835946698112844073013270683963139178041134319673847863493270683971674367839344811373270683981503182151197624415031821531308273599⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
看到答案之后,您可以尝试拿着这里的数据去加微信、购买茶叶或山货了。注意别买得比市场价高太多,同时也要监控产品质量,别买一堆假冒伪劣产品。——特别指出的是,我给出这里正确答案的代码,并不是贴在此处的代码。Mathematica数组操作没有matlab思维那么直观;要不断尝试不同的函数,如果不常使用也不太熟悉,挺繁琐。大概思路,找出1000个10位数字中的素数,排除;找出三个以上不同素因子的,排除;还得找出虽然刚好两个独立素因子,但某个素因子指数大于1的,排除(如果不排除这种则有194个);剩下的就是刚好2个素因子的了(151个);