Listen Sie alle palindromischen Primdaten zwischen 0000-01-01 und 99999-12-31 auf

11

Sie wissen, was ein Palindrom , eine Primzahl und ein Datum sind.

Ihre Aufgabe ist es, alle Daten in 100.000 Jahren aufzulisten, die alle drei Merkmale erfüllen.

Vergiss alles andere als die Zahlen, verwenden Sie die folgenden Formate: YYYYMMDD und JJJJjMMTT .

Daten zwischen 0000-01-01 und 9999-12-31 sollten als 8-stellige Palindromdaten (falls vorhanden?) Und Daten zwischen 10000-01-01 und 99999-12-31 als 9-stellige Palindrome gedruckt werden .

Es ist nicht zwingend erforderlich, die Daten in chronologischer Reihenfolge aufzulisten.

Beispielteil einer gültigen Ausgabe.

Die ersten drei 9-stelligen palindromischen Hauptdaten:

...
100111001
100131001
100161001
...

Regeln

Es gelten Standardlücken .

Plarsen
quelle
Regel: 02-29existiert nur für Jahre, die durch 400 oder (teilbar durch 4 und nicht teilbar durch 100) teilbar sind.
user202729
@ user202729 Ja, ich denke schon, zum Beispiel denke ich nicht, dass 2017-02-29, 2018-02-29 und 1900-02-29 als "Daten" betrachtet werden können.
Erik der Outgolfer
4
Es gibt keine 8-stelligen palindromischen Daten, die auch Primzahlen sind. Hier ist ein Pastebin der Liste, die wir zurückgeben / drucken sollen (insgesamt 197) . Ist das richtig @Plarsen?
Kevin Cruijssen
1
Sollten wir den 30. Februar zulassen? > timeanddate.com/date/february-30.html
jrtapsell
3
Jahr 0000 ist nie passiert
Jonathan Allan

Antworten:

5

Ruby , 144 141 Bytes (134 + 7 für die -rprimeFlagge)

3 Bytes dank benj2240 gespeichert !

('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)}}}

Probieren Sie es online aus!

Der Algorithmus:

  • Generieren Sie alle möglichen MMDD-Kombinationen von "0101" bis "1231".
  • Generieren Sie alle Jahre für dieses Datum, die zu einem Palindrom führen würden, indem Sie die MMDD-Zeichenfolge umkehren und in der Mitte alle Zeichen im Bereich (0..9) hinzufügen
  • überprüfen , ob das ein gültiges Datum durch die Schaffung eines ist Timebeispielsweise mit den gegebenen y, m, dWerten. Wenn das resultierende Zeitobjekt einen #dayWert von dhat, war dies ein gültiges Datum. Andernfalls würde sich das Datum verschieben (z. B. Time.new 2018,2,30Rückgabe 2018-03-02).
  • Überprüfen Sie, ob das gültige Palindromdatum auch eine Primzahl ist, und zeigen Sie es an, wenn dies der Fall ist.

Die innere Schleife war ursprünglich eine Funktion, die für jedes Element im (?0..?9)Bereich sowie für die leere Zeichenfolge aufgerufen wurde .

Da die leere Zeichenfolge keine Ergebnisse lieferte (es gibt keine gültigen 8-stelligen Prim-Palindrome), habe ich beschlossen, sie zu entfernen und auf diese Version umzugestalten.

Cristian Lupascu
quelle
Ich denke, Sie können ein paar Bytes sparen, indem Sie die tVariable entfernen : TIO
benj2240
@ benj2240 Das stimmt! Vielen Dank!
Cristian Lupascu
4

Python 2 , 116 107 128 122 119 Bytes

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

Die zweite Hälfte der 4. Zeile ist inspiriert von der Antwort von mxdsp auf eine andere Golffrage .

Erläuterung

Die Funktion verwendet g()nur ein Argument, um die nVariable mit ihrem Standardwert zu initialisieren . Der Anfangswert ist eine ungerade Zahl, die so kurz wie möglich und so groß wie möglich ist und dennoch kleiner als die erste gültige Antwort 100111001 ist.

Schleife bis nzum Ende des Datumsbereichs 10 9 . Inkrement num 2. mist der Monat des Datums n.

Wenn nes sich um ein gültiges Datum, Palindrom und Primzahl handelt, drucken Sie es aus:

  • Datum:
    • 0 < m < 13prüft, ob dies mein gültiger Monat ist.
    • n % 100 < 31 + (m+m/8)%2prüft, ob nder Tag des Monats gültig ist. (m+m/8)%2fügt 1für alle Monate mit 31 Tagen hinzu. Der Verdienst dafür geht an die Antwort von ArmanX . Für den 29. bis 30. Februar gibt es keine Primzahlen.
  • Palindrom : `n`[::-1] == `n`. Die Backticks stringifizieren n. [::-1]kehrt den String um.
  • Prime: 2**n % n == 2ist ein Fermat-Primalitätstest . Dieser Test ist nur probabilistisch. Es gibt auch Nicht-Primzahlen, die übereinstimmen. Aber nicht im Zahlenbereich, den wir betrachten.
Mercator
quelle
Netter mit dem Fermat-Primalitätstest!
Bis zum
3

APL (Dyalog Unicode) , 155 Bytes

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

Probieren Sie es online aus!

Dies ist ein Tradfn ( einf itional f unctio n ) , die ein Argument arg = yyyymmddoder arg = yyyyymmdd. Verwendung ist f arg.

Dies gibt nichts aus, wenn das Argument beginnt, 10000101da es in 60 Sekunden kein primäres Palindromdatum findet.

Hier ist ein weniger Golf-Ansatz, der die Beispielausgabe des OP von ausgibt

100111001
100131001
100161001

( Probieren Sie es online! )

Beachten Sie, dass beide Codes bis kurz vor dem rekursiven Aufrufen der Funktion für das nächste Datum exakt gleich sind. Während die Golfversion es einfach so nennt f arg+1, springt der weniger Golfcode von Tag 31zu Tag 01und von Monat 12zu Monat 01, was es ziemlich beschleunigt.

Wie es funktioniert:

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.
J. Sallé
quelle
2

Python 3, 163 Bytes

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)

Die Lösung ist ziemlich lang (und kann wahrscheinlich verbessert werden), verwendet jedoch keine integrierten Funktionen für die Überprüfung von Prim / Datum / Palindrom. Eine etwas ungolfed Version für Klarheit:

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)

Gültige Daten werden durch Auswahl eines Monats und eines Tages generiert. Wie bereits erwähnt, muss nur Größe 9 berücksichtigt werden. Beachten Sie auch, dass Schaltjahre nicht berücksichtigt werden. Dies ist aufgrund des glücklichen Zufalls nicht erforderlich, dass Palindrom-Primzahlen der Länge 9, die auf 0229 enden, einfach nicht existieren (andere Datumsanomalien wie der 30. Februar 1712 können aus demselben Grund verworfen werden).

Als nächstes wird die mittlere Ziffer frei gewählt und ein Primärtest durchgeführt. Da der Primetest so kurz wie möglich sein musste, ist er sehr naiv und damit lähmend langsam. Die Verwendung einer externen Bibliothek könnte dies lösen (und einige Bytes sparen), aber wie bereits erwähnt, wollte ich keine verwenden.

Def
quelle
Sie sollten Ihren Code genau so aussehen lassen, wie er beim Zählen von Bytes funktioniert (in diesem Fall durch Reduzieren des Einzugsabstands). Es ist auch großartig, dass Sie eine ungolfed Version aufgenommen haben, aber normalerweise wird die
Golfversion
@wnnmaw Der einzige Unterschied zwischen der Version, die ich mit der in der Antwort angegebenen Version gezählt habe, besteht darin, dass ich anstelle der hier verwendeten Leerzeichen Tabulatoren verwendet habe. Wie ich weiß, werden Registerkarten automatisch konvertiert, sodass ich keine Möglichkeit sehe, dies zu beheben.
Def
Mit @Def IIRC Python können Sie Leerzeichen auch als Einrückungen verwenden. Auf diese Weise könnte es auch in Ihrer Antwort gleich aussehen. Korrigieren Sie mich, wenn ich im ersten Teil falsch liege.
elementbound
@elementbound Das tut es in der Tat, danke für den Vorschlag.
Def
2

WolframLanguage (Mathematica) 187 Bytes

Möglicherweise ist eine gewisse Größenreduzierung festzustellen. Erklärung folgt ...

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]&

Testfälle

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"} *)

Erklärung des Codes

DayRange[d@#,d@#2]Gibt alle Daten zwischen {10011, 10, 1}und zurück {10017, 1, 1}. In diesem Fall werden ungefähr 5 Jahre und 4 Monate (genau 1920) zurückgegeben. Schaltjahre werden berücksichtigt.

Die Daten werden in Wolfram-Standardformatierung zurückgegeben. Das erste Datum wird beispielsweise als DateObject[List[1,1,1],"Day","Gregorian",-5.] `angezeigt

#[[1]] & /@wird den Teil des Datums in jedem Datum entfernen, der uns betrifft. Gibt im Beispiel DateObject[List[1,3,7],"Day","Gregorian",-5.]das abgekürzte Datum zurück {1,3,7}.

t/@p[#3,2]}oder ToString/@Padleft[#3,2]füllt das dritte Element auf, nämlich die 7, die "für den 7. Tag des Monats" steht "07". Eine ähnliche Auffüllung ist für das einstellige Symbol für den Monat März vorgesehen, dh es 3wird zurückgegeben als "03".

p[#, If[Length@# < 5, 4, 5]]füllt das Jahr mit Nullen auf, um die Länge einer 4- oder 5-stelligen Zeichenfolge zu erreichen. In diesem Fall wird der Januar nämlich 1als "00001" zurückgegeben.

"" <>...verbindet die Saiten. In diesem Fall wird zurückgegeben "000010307".

Cases[...x_ /; PalindromeQ@x && PrimeQ@ToExpression@x] gibt jene Fälle unter den 1920er Daten zurück, die Palindrome und Primzahlen sind.

DavidC
quelle
2

Javascript , 187 177

Annahmen: keine übereinstimmenden 4-stelligen Jahre; Keine passenden Tage im Februar zwischen 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)}}

Es funktioniert so:

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!

Geschichte:

  • 187 bis 177: Es gibt keine Hauptdaten für Palindrome, die auf den 29. oder 30. Februar fallen. Wir können also so tun, als hätte der Februar 30 Tage und 10 Zeichen gespeichert.

Anmerkungen:

Beim Testen habe ich festgestellt, dass es keine gültigen Übereinstimmungen gibt, die 4-stellige Jahre sind oder am 29. oder 30. Februar liegen. Leider gibt es aus Gründen des Codes genau fünf (ungültige) Ergebnisse, die auf den 31. verschiedener Monate fallen das haben nur 31 tage.

ArmanX
quelle
2

Java 10, 329 327 320 318 312 308 307 264 Bytes

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 Byte dank @assylias .

Erläuterung:

Probieren Sie es online aus (Hinweis: Der Teil zur Überprüfung der Primzahl wurde durch eine effizientere getrennte Methode ersetzt, obwohl selbst nach 60 Sekunden eine Zeitüberschreitung auftritt und nur die ersten ~ 115 palindromischen Primzahlen ausgegeben werden).
Pastebin aller 197 Ausgaben eines lokalen Laufs.

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
Kevin Cruijssen
quelle
1
if(t.equals(new StringBuffer(t).reverse()+"")-> if(t.contains(new StringBuffer(t).reverse())um 1 Zeichen zu speichern (funktioniert, weil wir wissen, dass beide Zeichenfolgen die gleiche Länge haben). Das ist nicht viel :-(
Assylias
@assylias Smart, ich mag es. Vielen Dank! Und obwohl 1 Byte nicht viel ist, ist es immer noch 1 Byte. Bei Codegolf geht es immer darum, es so kurz wie möglich zu halten, damit jedes Byte zählt. :)
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
Selkie
quelle
Willkommen bei PPCG! Ich kenne VBA nicht, aber es sieht so aus, als könnten Sie ein paar Leerzeichen abspielen.
FantaC
Ich kenne VBA auch nicht wirklich, aber ich denke, es DateStringist ein beliebiger Variablenname, also sollten Sie das auf ein einziges Zeichen reduzieren können, oder?
Martin Ender
3
Und ich glaube , Sie die verpasste prime Teil von „Primzahlpalindrom Daten“.
Mercator
Es würde einen Code für die Berechnung von Schaltjahren geben (der hat 29 Februar Tage)
RosLuP
Es fehlen auch 5-stellige Jahre, sonst ist dies nicht erforderlich.
Weijun Zhou
0

Sauber , 262 ... 213 Bytes

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]]

Probieren Sie es online aus!

Οurous
quelle
0

Javascript , 234 229 Bytes

Ein bisschen sperrig, aber es zu posten, um den JS-Ball ins Rollen zu bringen. Anregungen willkommen!

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)}}

Ungolfed:

// 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)
            }
}

Wie es funktioniert:

Die Magie des Ziffernwechsels basiert hauptsächlich auf Experimenten.
Ich begann damit, herauszufinden, von welcher Zahl ich subtrahieren sollte, um die gespiegelte Version zu erhalten. Ich habe mich nur um die letzten beiden Ziffern gekümmert.
Also, wenn wir nehmen n, finden Sie kdas n+k=flip(n). Für 10<n<20 kbegann bei 101 und erhöhte sich in Schritten von 9. Für n<10war dies jedoch 100. Ich nahm an, kdass es für jeden Sprung von 10 erhöht wurde, und nach einigem Fummeln stellte ich fest, dass es richtig war.
Also, k=100+9*n+n//10wo // ganzzahlige Division bedeutet.

So bekommen wir n+k = n+(100+9*n+n//10) = 100+10*n+n//10 = flipped(n).

Ich kann weder beweisen noch behaupten, dass dies für irgendeine Zahl funktioniert, aber es hat zu korrekten Ergebnissen für die hier verwendeten Zahlen geführt.

Für den Primalitätstest gilt die Antwort von Kevin Cruijssen . Ich hatte eine etwas kürzere Version, aber ich konnte es nicht richtig machen:

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

Ich habe den Palindrom-Test übersprungen, indem ich Monate, Tage und eine mittlere Ziffer durchlaufen habe, damit ich Zeichenfolgen erstellen kann dDmMxMmDd, wobei Ddie erste Ziffer des Tages ddie zweite usw. ist.

Geschichte

5 Bytes wurden gespeichert, indem der bedingte Teil von q entfernt wurde

q=n=>n<10?'0'+n:(''+n).slice(-2) // from
q=n=>(''+(100+n)).slice(-2)      // to
elementgebunden
quelle
Tut mir leid, dass ich mit der Anzahl der Bytes herumgespielt habe. Versehentlich in einige Soft-Tabs gerutscht. Sollte jetzt richtig sein.
Elementgebunden
Sie verwenden immer nur fdas Ergebnis als Parameter für q, schneiden Sie also den mittleren Mann aus und schreiben Sie f=n=>''+n%10+(n/10|0), und das Ergebnis von q wird immer als Zeichenfolge verwendet, damit Sie schreiben können q=n=>n<10?'0'+n:n.
Neil
0

APL NARS 626 Bytes, 313 Zeichen

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

Dieser Druck, was in 50 Sekunden gefunden wird, als sich selbst zu stoppen (weil ich sonst das Programm zum Kopieren nicht stoppen kann, füge den Test ein, weil ich nicht weiß, wie ich das Programm stoppen kann, ohne die Fenster des Interpreters zu schließen) Test:

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

Julia 0,6 , 109 Bytes

Link geht zu einer längeren Version mit zwei Unterschieden:

  1. Prüft auf Primzahlen mit handgeschriebener Funktion, da das Primzahlenpaket auf TIO nicht verfügbar ist.
  2. Iteriert über einen anderen Datumsbereich, um keine Zeitüberschreitung zu verursachen.
[s for s in Dates.format(Date(0,1,1):Date(100000,1,1),"YYYYmmdd") if Primes.isprime(parse(s))&&s==reverse(s)]

Probieren Sie es online aus!

gggg
quelle