0000-01-01과 99999-12-31 사이의 모든 회문 주요 날짜를 나열하십시오.


11

회문 , 프라임날짜 가 무엇인지 알고 있습니다.

당신의 임무는 세 가지 특성을 모두 만족시키는 10 만 년의 모든 날짜를 나열하는 것입니다.

숫자 이외의 것을 신경 쓰지 말고 YYYYMMDDYYYYYMMDD 형식을 사용하십시오 .

0000-01-01과 9999-12-31 사이의 날짜는 8 자리 회문 날짜 (있는 경우?)로 인쇄해야하며 10000-01-01과 99999-12-31 사이의 날짜는 9 자리 회문 으로 인쇄해야합니다 .

날짜를 시간순으로 나열 할 필요는 없습니다.

유효한 출력의 예 부분.

첫 3 자리 9 자리 총 회문 날짜 :

...
100111001
100131001
100161001
...

규칙

표준 허점이 적용됩니다.


규칙 : 02-29400으로 나눌 수 있거나 4로 나눌 수 있고 100으로 나눌 수없는 년 동안 만 존재합니다.
user202729

@ user202729 예, 예를 들어 2017-02-29, 2018-02-29 및 1900-02-29를 "날짜"로 간주 할 수 없다고 생각합니다.
Outgolfer Erik

4
소수도 8 자리 회문 날짜가 없습니다. 다음은 우리가 반환 / 인쇄 해야하는 목록의 목록입니다 (총 197 개) . 이것이 올바른 @Plarsen입니까?
Kevin Cruijssen

1
2 월 30 일을 허용해야합니까? > timeanddate.com/date/february-30.html
jrtapsell

답변:


5

Ruby , 144141 바이트 ( -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주어진 인스턴스와 y, m, d값. 결과 시간 개체의 #dayd이 인 경우 유효한 날짜입니다. 그렇지 않으면 날짜가 이동합니다 (예 Time.new 2018,2,30:) 2018-03-02.
  • 유효한 회문 날짜도 프라임인지 확인하고 그 날짜를 표시하십시오.

내부 루프는 처음에는 (?0..?9)빈 문자열뿐만 아니라 범위의 각 요소에 대해 호출 된 함수였습니다 .

빈 문자열은 결과를 얻지 못했기 때문에 (유효한 8 자리 소수 회문이 없습니다), 나는 그것을 제거하고이 버전으로 리팩토링하기로 결정했습니다.


t변수 를 제거하여 몇 바이트를 절약 할 수 있다고 생각합니다 . TIO
benj2240

@ benj2240 맞습니다! 감사!
Cristian Lupascu

4

파이썬 (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

4 번째 라인의 후반부는 다른 골프 질문에 대한 mxdsp답변에서 영감을 얻었습니다 .

설명

이 함수 g()n기본값을 사용 하여 변수 를 초기화하는 데만 인수를 사용합니다. 초기 값은 가능한 한 짧고 가능한 한 큰 홀수이며 여전히 첫 번째 유효한 답변 100111001보다 작습니다.

n날짜 범위 10 9 의 끝에 도달 할 때까지 반복 하십시오 . n2 씩 증가 하는 m날짜는 월입니다 n.

경우 n유효한 날짜, 회문 프라임이며, 그것을 인쇄 :

  • 데이트:
    • 0 < m < 13m유효한 월인지 확인합니다 .
    • n % 100 < 31 + (m+m/8)%2것을 확인 n달의 날이 유효합니다. 31 일로 모든 달에 (m+m/8)%2추가 1됩니다. 이에 대한 크레딧은 ArmanX의 답변에 갑니다 . 2 월 29 일 ~ 30 일에는 소수가 없습니다.
  • 회문 : `n`[::-1] == `n`. 백틱은 stringify n입니다. [::-1]문자열을 반대로 바꿉니다.
  • 프라임 : 2**n % n == 2A는 페르마 소수도 테스트 . 그 시험은 단지 확률 적입니다. 일치하는 비 프라임도 있습니다. 그러나 우리 가보고있는 숫자 범위에는 없습니다.

Fermat의 원시성 테스트를 사용하는 것이 좋습니다!
agtoever

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 (인 트라 itional F unctio N 개의 인수 소요) arg = yyyymmdd또는 arg = yyyyymmdd. 사용법은 f arg입니다.

인수가 시작될 때 1000010160 초 내에 주요 회문 날짜를 찾지 못하므로 아무 것도 출력 하지 않습니다.

다음은 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

파이썬 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)

해결책은 상당히 길지만 (아마도 향상 될 수는 있지만) 소수 / 날짜 / 회문 검사에 내장 함수를 사용하지 않습니다. 명확성을 위해 다소 ungolfed 버전 :

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 만 고려하면됩니다. 또한 윤년은 고려되지 않습니다. 이것은 0229로 끝나는 길이 9의 회문 소수가 단순히 존재하지 않는다는 운이 우연의 일치 때문에 필요하지 않습니다 (1712 년 2 월 30 일과 같은 다른 날짜의 예외는 같은 이유로 폐기 될 수 있습니다).

다음으로 중간 자릿수가 자유롭게 선택되고 프라임 테스트가 수행됩니다. 프라임 테스트는 가능한 한 짧아야했기 때문에 매우 순진하고 속도가 느립니다. 외부 라이브러리를 사용하면이 문제를 해결할 수 있으며 바이트를 절약 할 수는 있지만 언급하지 않았으므로 사용하고 싶지 않습니다.


바이트를 계산할 때 (이 경우 들여 쓰기 간격을 축소하여) 코드가 정확히 어떻게 작동하는지 확인해야합니다. 또한, 당신이 ungolfed 버전을 포함하지만, 일반적으로 골프 버전이 먼저 나열되어 있는지 좋아요
wnnmaw

@wnnmaw 대답에 제공된 버전에서 계산 한 버전의 유일한 차이점은 여기에 사용되는 공백 대신 탭을 사용한다는 것입니다. 탭이 자동 변환된다는 것을 알고 있으므로이 문제를 해결할 방법이 없습니다.
데프

@Def IIRC Python을 사용하면 공백도 들여 쓰기로 사용할 수 있으므로 답에서도 똑같이 보일 수 있습니다. 그래도 처음에 틀렸다면 정정하십시오.
elementbound

@elementbound 제안에 감사드립니다.
데프

2

WolframLanguage (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 월의 한 자리 기호에 대해 유사한 패딩이 제공 3됩니다 "03". 즉, 로 반환됩니다 .

p[#, If[Length@# < 5, 4, 5]]연도를 0으로 채워 4 자리 또는 5 자리 문자열의 길이에 도달합니다. 이 경우 1 월, 즉 1‘00001’이 반환됩니다.

"" <>...문자열을 조인합니다. 이 경우을 반환합니다 "000010307".

Cases[...x_ /; PalindromeQ@x && PrimeQ@ToExpression@x] 1920 년 날짜 중 회문 및 소수 인 사례를 반환합니다.


2

자바 스크립트 , 187 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 일에 정확히 5 개의 잘못된 결과가 있습니다. 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;}}

@assylias 덕분에 -1 바이트 .

설명:

온라인으로 시도해보십시오 (참고 : 소수 검사 부분은 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
그리고 나는 당신 이 "palindromic prime date" 의 주요 부분 을 놓쳤다 고 생각합니다 .
mercator

윤년을 계산하는 코드가있을 것입니다 (2 월 29 일이 있습니다)
RosLuP

5 자리 연도도 누락되었으므로 Else가 필요하지 않습니다.
Weijun Zhou

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

자바 스크립트 , 234 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)에서 시작을 위해, 그러나 제 씩 증가 n<10, 이는 I (100)이 가정되었다 k(10)의 모든 점프 증가하고 하구 조금 후에 I는 정확 나타냈다.
따라서 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

바이트 수를 망쳐 서 죄송합니다. 실수로 일부 소프트 탭에서 미끄러졌습니다. 지금 맞아야합니다.
elementbound

f의 결과를 매개 변수 로만 사용 q하므로 중간 남자를 잘라 내고 쓰십시오 f=n=>''+n%10+(n/10|0).q의 결과는 항상 문자열로 사용되므로 쓸 수 있습니다 q=n=>n<10?'0'+n:n.
Neil

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 바이트

Link는 두 가지 차이점이있는 더 긴 버전으로 이동합니다.

  1. Primes 패키지는 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)]

온라인으로 사용해보십시오!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.