列出0000-01-01至99999-12-31之间的所有回文素数日期


11

您知道回文素数日期是什么。

您的任务是列出满足所有三个特征的十万年的所有日期。

除了数字外,别无其他,请使用以下格式:YYYYMMDDYYYYYMMDD

0000-01-01和9999-12-31之间的日期应打印为8位回文日期(如果有?),而10000-01-01和99999-12-31之间的日期应打印为9位回文日期。

按时间顺序列出日期不是强制性的。

有效输出的示例部分。

前三个9位数主要回文日期:

...
100111001
100131001
100161001
...

规则

有标准漏洞


规则:02-29仅存在可被400整除或(被4整除而不能被100整除)的年份。
user202729

@ user202729是的,我想是这样,例如,我认为2017-02-29、2018-02-29和1900-02-29不能被视为“日期”。
暴民埃里克(Erik the Outgolfer)'18年

4
没有任何8位回文日期也是素数。这是我们应该返回/打印的列表的pastebin(总计197)。这是正确的@Plarsen吗?
凯文·克鲁伊森

1
我们应该允许2月30日吗?> timeanddate.com/date/february-30.html
jrtapsell

Answers:


5

Ruby144 141字节(-rprime标志为134 + 7 )

感谢benj2240,节省了3个字节!

('01'..'12').map{|m|('01'..'31').map{|d|(?0..?9).map{|k|q=m+d
y=q.reverse+k
r=y+q
Time.new(y,m,d).day==d.to_i&&r.to_i.prime?&&(p r)}}}

在线尝试!

算法:

  • 生成从“ 0101”到“ 1231”的所有可能的MMDD组合
  • 通过反转MMDD字符串并在中间添加(0..9)范围内的所有字符,生成该日期的所有年份,从而导致回文
  • 检查是否是通过创建一个有效的日期Time与给定的情况下ymd值。如果结果时间对象的#day值等于d,则该日期为有效日期。否则,它将改变日期(例如,Time.new 2018,2,30return 2018-03-02)。
  • 检查有效回文日期是否也是素数,如果显示,则显示它。

内部循环最初是一个函数,该函数针对该(?0..?9)范围内的每个元素以及空字符串被调用。

由于空字符串未产生任何结果(没有有效的8位数素数回文),因此我决定将其删除并重构为该版本。


我认为您可以通过删除t变量来节省一些字节:TIO
benj2240 '18

@ benj2240是的!谢谢!
克里斯蒂安·卢帕斯库

4

Python 2中116个 107 128 122 119字节

def g(n=9**8):
 while n<1e9:
  n+=2;m=n/100%100
  if 0<m<13and n%100<31+(m+m/8)%2and`n`[::-1]==`n`and 2**n%n==2:print n

第四条线的下半部分受到mxdsp 对另一个高尔夫球问题回答的启发。

说明

该函数g()仅接受参数以n使用其默认值初始化变量。初始值是一个奇数,它应尽可能短且尽可能大,同时仍小于第一个有效答案100111001。

循环n播放直到到达日期范围10 9的结尾。递增n2. m是日期的月份n

如果n是有效日期,回文和素数,请打印:

  • 日期:
    • 0 < m < 13检查m是否为有效月份。
    • n % 100 < 31 + (m+m/8)%2检查n该月的某天是否有效。(m+m/8)%2加上131天的所有月份。值得称赞的ArmanX的答案。2月29日至30日没有素数。
  • 回文:`n`[::-1] == `n`。反引号串n[::-1]反转字符串。
  • 素数2**n % n == 2Fermat素数测试。该测试仅是概率性的。也有匹配的非素数。但不在我们正在寻找的数字范围内。

使用Fermat的素数测试的好人!
8:51

3

APL(Dyalog Unicode),155字节

CY'dfns'
n←⍕x
m←(⍎2↑¯4n)
d←(⍎¯2n)
:If n≡⌽n
:AndIf 1 pco x
:AndIf m<13
:AndIf d<32
:If m d2 29
:AndIf (400|⍎((≢n)-4)↑n)=0
⎕←x
f x+72
:End
⎕←x
:End
f x+1

在线尝试!

这是一个Tradfn(TRAD itional ˚F unctio Ñ)它有一个参数arg = yyyymmddarg = yyyyymmdd。用法是f arg

参数开始于时不会输出任何内容,10000101因为它在60秒内找不到原始回文日期。

这是一种不太精打细算的方法,将输出OP的示例输出

100111001
100131001
100161001

在线尝试!

请注意,直到下一个日期递归调用函数之前,这两个代码完全相同。虽然golfed版本只是调用它f arg+1,就越golfed代码跳转从一天31到一天01和一个月12到一个月01,这其加速不少。

这个怎么运作:

CY'dfns'                    Copy (⎕CY) all dfns to enable the use of pco.
n←⍕x                         Assign (←) the input to the variable n.
m←(⍎2↑¯4n)                  Take (↑) the last 4 4) elements of n, then take the first 2 elements of that and assign to m. 
d←(⍎¯2n)                    Take the last 2 2) elements of n, and assign to d.
:If n≡⌽n                     If n matches (≡) its reverse (⌽) (is a palindrome)
:AndIf 1 pco x               And a prime (1 pco)
:AndIf m<13                  And month < 13
:AndIf d<32                  And day < 32
:If m d2 29                 If it is 2/29
:AndIf (400|⍎((≢n)-4)↑n)=0   And the year mod 400 = 0
⎕←x                          Print x
f x+72                       call f with arg year0301
:End
⎕←x                          Print x
:End
f x+1                        call f for the next date.

2

Python 3,163个字节

r=range
for m in r(1,13):
 for d in r(1,31+(m%2==(m<8))-2*(m==2)):
  t="%02d"*2%(m,d)
  for i in r(10):x=int(t[::-1]+str(i)+t);all(x%i for i in r(2,x))and print(x)

解决方案相当长(可能会有所改进),但是不使用任何内置函数进行质数/日期/回文校验。为了清晰起见,有些不符合实际的版本:

for month in range(1,13):
    for day in range(1,31 + (month%2==(month<8)) - 2*(month==2)):
        t = "%02d%02d" % (month, day)
        for i in range(10):
            x = int(t[::-1] + str(i) + t)
            if all(x%i for i in range(2,x)):print(x)

有效日期是通过选择月份和日期生成的。如前所述,仅需考虑尺寸9。另请注意,未考虑leap年。由于幸运的巧合,根本不存在长度为9的回文素数(以0229结尾)的幸运,所以这不是必需的(出于相同的原因,其他日期异常(如1712年2月30日也可以被丢弃))。

接下来,自由选择中间的数字,并执行素数测试。由于主要测试必须尽可能短,因此非常幼稚,因此速度很慢。使用外部库可以解决此问题(并节省一些字节),但是如前所述,我不想使用任何外部库。


计算字节数时,应该使代码看起来完全正确(在这种情况下,通过缩进缩进间隔)。另外,很高兴您提供非高尔夫版本,但通常高尔夫版本
排名

@wnnmaw我在答案中提供的版本之间唯一的区别是,我使用制表符而不是这里使用的空格。据我所知,标签会自动转换,因此我看不到任何解决方法。
Def

@Def IIRC Python也允许您将空格用作缩进,这样在您的答案中它也可能看起来相同。如果我在第一部分上错了,请纠正我。
元素绑定

@elementbound的确如此,感谢您的建议。
Def

2

Wolfram语言(Mathematica)187字节

可能会发现尺寸有所减小。后续说明...

t=ToString;p=PadLeft;d=DateObject;Cases[""<>{t/@p[#,If[Length@#<5,4, 5]],t/@ p[#2,2],t/@p[#3,2]}&@@@(IntegerDigits/@#[[1]]&/@DayRange[d@#,d@#2]),x_/;PalindromeQ@x&&PrimeQ@ToExpression@x]&

测试用例

t = ToString; p = PadLeft; d = DateObject;
Cases["" <> {t /@ p[#, If[Length@# < 5, 4, 5]], t /@ p[#2, 2], 
   t /@ p[#3, 2]} & @@@ (IntegerDigits /@ #[[1]] & /@ DayRange[d@#, d@#2]), 
   x_ /; PalindromeQ@x && PrimeQ@ToExpression@x] &[{10011, 10, 1}, {10017, 1, 1}]

(* {“ 100111001”,“ 100131001”,“ 100161001”} *)

代码说明

DayRange[d@#,d@#2]返回{10011, 10, 1}和之间的所有日期{10017, 1, 1}。在这种情况下,它将返回大约5年零4个月的日期(精确为1920个日期)。考虑到年。

日期以Wolfram标准格式返回。例如,第一个日期将显示为DateObject[List[1,1,1],"Day","Gregorian",-5.]`

#[[1]] & /@将删除每个日期中与我们有关的部分。在示例中,DateObject[List[1,3,7],"Day","Gregorian",-5.]返回缩写日期{1,3,7}

t/@p[#3,2]}ToString/@Padleft[#3,2]填充第三个元素,即“第7个月的7” "07"。为三月份的一位数字符号提供了类似的填充,即3以返回"03"

p[#, If[Length@# < 5, 4, 5]]用零填充年份以达到4或5位数字字符串的长度。在这种情况下,一月,即1返回为“ 00001”。

"" <>...连接字符串。在这种情况下,它返回"000010307"

Cases[...x_ /; PalindromeQ@x && PrimeQ@ToExpression@x] 返回1920年日期中的回文和素数的那些案例。


2

使用Javascript187 177

假设:没有匹配的4位数字的年份;2月29-30日之间没有匹配的日子

p=n=>(n<10?'0':'')+n;f=n=>n[3]+n[2]+n[1]+n[0];for(m=13;--m;)for(d=31+(m+(0|m/8))%2;--d;){for(y=10;y--;){z=p(m)+p(d);Y=+(f(z)+y+z);for(i=2;Y%i&&i*i<Y;i++);if(Y%i)console.log(Y)}}

它是这样的:

p=n=>(n<10?'0':'')+n;       //Prepend a 0 for 1-digit numbers and convert to a string
f=n=>n[3]+n[2]+n[1]+n[0];   //Flip four digits
for(m=13;--m;)              //Month loop, from 12 to 1
 for(d=
       31+(m+(0|m/8))%2     //Calculate the days in the month, allowing  Feb. 29 & 30
                       ;--d;){ //Day loop
  for(y=10;y--;){           //Middle digit loop
   z=p(m)+p(d);             //Prepend zeros to the month and day
   Y=+(f(z)+y+z);           //Flip the digits; append the middle digit,
                            //month, and day; convert back to an integer
   for(i=2;Y%i&&i*i<Y;i++); //Check if it's a prime
    if(Y%i)console.log(Y)}} //If it doesn't divide evenly, it's not prime. Print it!

历史:

  • 187至177:没有2月29或30日为主要回文日期,因此我们可以假装2月为30天并保存10个字符。

笔记:

通过测试,我发现没有有效的匹配数是4位数字的年份或者是2月29日或30日。不幸的是,出于代码的原因,在各个月的31日恰好有五个(无效)结果只有31天。


2

爪哇10,329 327 320 318 312个 308 307 264字节

v->{for(int y=9999,m,d;++y<1e5;)for(m=0;++m<13;)for(d=0;++d<32;)try{java.time.LocalDate.of(y,m,d);var t=y+"".format("%02d%02d",m,d);long n=new Long(t),x=1;for(;n%++x%n>0;);if(t.contains(new StringBuffer(t).reverse())&n==x)System.out.println(t);}finally{continue;}}

-1个字节感谢@assylias

说明:

在线尝试(请注意:素数检查部分已被更有效的分离方法代替,尽管即使它在60秒后仍然超时,仅输出第一个〜115个回文素数日期)。
来自本地运行的所有197个输出的Pastebin。

v->{                           // Method without empty unused parameter and no return-type
  for(int y=9999,m,d;++y<1e5;) //  Loop over the years in the range [1000,9999]:
    for(m=0;++m<13;)           //   Inner loop over the months in the range [1,12]:
      for(d=0;++d<32;){        //    Inner loop over the days in the range [1,31]:
        try{java.time.LocalDate.of(y,m,d);
                               //     If it's a valid date:
          var t=y+"".format("%02d%02d",m,d);
                               //      Convert the numbers to a String in format "yyyyyMMdd"
          long n=new Long(t),  //      Convert this String to a long
          x=1;for(;n%++x%n>0;);//      Prime-checking loop
          if(t.contains(new StringBuffer(t).reverse())
                               //      If the string is palindromic
             &n==x)            //      and the long is a prime:
            System.out.println(t);
                               //       Print the string with trailing newline
        }finally{              //     If it isn't a valid date:
          continue;}}}         //      Continue to the next iteration of the inner-most loop

1
if(t.equals(new StringBuffer(t).reverse()+"")-> if(t.contains(new StringBuffer(t).reverse())保存1个字符(之所以起作用,是因为我们知道两个字符串的长度相同)。那不是很多:-(
assylias

@assylias Smart,我喜欢。谢谢!尽管1个字节并不多,但仍然是1个字节。Codegolf总是要使它尽可能短,因此每个字节都很重要。:)
Kevin Cruijssen

1

VBA,347

Sub PalindromeDate()
Dim DateString As String
For i = 0 To 9999
    For j = 1 To 12
        For k = 1 To 31
        DateString = Format(i, "0000") & Format(j, "00") & Format(k, "00")
        If DateString = StrReverse(DateString) Then
        Debug.Print DateString
        Else
        End If
        Next k
        Next j
        Next i

End Sub

欢迎来到PPCG!我不知道VBA,但看起来您可以打些空白。
FantaC

我也不是很了解VBA,但是我认为这DateString是一个任意的变量名,因此您应该可以将其简化为单个字符,对吗?
马丁·恩德

3
而且我认为您错过了“回文期” 的主要部分。
墨卡托

将会有一些用于计算leap年的代码(一个有2月29日)
RosLuP

也缺少5位数字的年份,并且没有其他必要。

0

干净262 ... 213字节

import StdEnv
@ =(rem)
f=[d\\d<-[a*10^4+b*100+c\\a<-[10^4..99999],b<-[1..12],c<-[1..28+[0,3,if(@a 400<1|| @a 4<1&& @a 100>0)1 0,3,2,3,2,3,3,2,3,2,3]!!b]]|(\k=k==reverse k)[p\\p<-:toString d]&&all((<)0o@d)[2..d-1]]

在线尝试!


0

使用Javascript234个 229字节

有点笨重,但是发布它可以使JS球滚动。任何建议欢迎!

f=n=>100+10*n+n/10|0
p=n=>{for(i=2;i<n;n=n%i++<1?0:n);return n>1}
q=n=>(''+(100+n)).slice(-2)
r=_=>{for(m=13;--m;)for(d=32;--d;)for(x=10;--x+1;){s=q(f(d))+q(f(m))+x+q(m)+q(d);if(p(s|0)&&d<(m==2?29:31+(m+m/8|0)%2))console.log(s)}}

取消高尔夫:

// Flip a one- or two-digit number
f=n=>100+10*n+n/10|0

// Primality test
// For initial testing, you can replace this line with:
//      p=require('primality')
// This uses the primality npm module and is way faster
p=n=>{for(i=2;i<n;n=n%i++<1?0:n);return n>1}

// Convert number to string, pad with zeroes if necessary
q=n=>(''+(100+n)).slice(-2)

r=_=>{
    // Loop months
    for(m=13;--m;)
        // Loop days
        for(d=32;--d;)
            // Loop middle digit
            for(x=10;--x+1;) {
                // Construct 'date'
                s = 
                    // Start with day and month, each flipped
                    q(f(d))+q(f(m)) + 
                    // Add middle digit ( will be casted to string since the previous expression is also a string)
                    x + 
                    // Add month and date as they are
                    q(m)+q(d);

                if(
                    // Check for primality
                    p(s|0) && 
                    // Check if it's a valid date by validating day ( month and year will always be valid)
                    d<(
                        // For February, we always assume 28 days ( check for 29 because we use less than)
                        m==2?29 : 
                        // For other months, it alternates between 31 and 30
                        // EXCEPT July and August both have 31 days, then continues alternating
                        31+(m+m/8|0)%2))
                    console.log(s)
            }
}

这个怎么运作:

数字翻转魔术主要基于实验。
我首先确定要减去的数字以获得翻转后的版本。我只关心最后两位数字。
因此,如果采取的话n,找到k那个n+k=flip(n)。对于,10<n<20 k从101开始,并且以9的增量增加。但是,对于n<10,它是100。我假设k每跳10都会增加,并且经过一番摆弄之后,我认为它是正确的。
因此,k=100+9*n+n//10// //表示整数除法。

因此,我们得到n+k = n+(100+9*n+n//10) = 100+10*n+n//10 = flipped(n)

我无法证明,也不能声称这适用于任何数字,但是对于此处使用的数字,它产生了正确的结果。

对于素数测试,请相信Kevin Cruijssen的回答。我的版本较短,但无法正确显示:

p=n=>{for(i=n;--i-1;)if(!(n%i))return 1;}

我跳过了回文测试,通过循环了几个月,几天和一个中间的数字,因此可以将字符串构建为dDmMxMmDd,其中D一天的第一个数字d是第二个数字,依此类推。

历史

摆脱q的条件部分,节省了5个字节

q=n=>n<10?'0'+n:(''+n).slice(-2) // from
q=n=>(''+(100+n)).slice(-2)      // to

很抱歉弄乱了字节数。意外滑入了一些软标签。现在应该是正确的。
元素绑定

您只将f's'的结果用作to的参数q,因此切掉中间人并写f=n=>''+n%10+(n/10|0),并且q的结果总是用作字符串,因此您可以写q=n=>n<10?'0'+n:n
尼尔

0

APL NARS 626字节,313个字符

f;y;m;d;i;k;v;x;t
t←{60⊥3↑3↓⎕TS}⋄t0←50+t
x←2 12⍴v,v←31 28 31 30 31 30 31 31 30 31 30 31
x[2;2]←29⋄m←d←1⋄y←10000
X:  i←{(0=4∣⍵)∧0≠100∣⍵:1⋄0=400∣⍵:1⋄0}y
A:  →0×⍳y≥1e5
    →0×⍳t≥t0
    k←d+100×m+y×100
    →B×⍳∼k=⍎⌽⍕k⋄→B×⍳∼0πk⋄⎕←k
B:  d+←1
    →A×⍳d≤x[1+i;m]
    d←1⋄→C×⍳∼m=12⋄m←1⋄y+←1⋄→X
C:  m+←1⋄→A

此打印将在50秒内找到什么,然后停止自身(因为否则我将无法停止程序进行复制粘贴测试,因为我不知道如何在不关闭解释器窗口的情况下停止程序)测试:

  f
100111001
100131001
100161001
101030101
101060101
101141101
101171101
102040201
102070201
103000301
103060301
104000401
104030401
104040401

0

朱莉娅0.6,109字节

链接转到更长的版本,有两个区别:

  1. 由于Prime软件包在TIO上不可用,因此需要检查具有手写功能的灌注剂。
  2. 迭代不同的日期范围以不超时。
[s for s in Dates.format(Date(0,1,1):Date(100000,1,1),"YYYYmmdd") if Primes.isprime(parse(s))&&s==reverse(s)]

在线尝试!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.