Elencare tutte le prime date palindromiche tra l'esercizio01-01 e 99999-12-31


11

Sai cosa sono un palindromo , un numero primo e una data .

Il tuo compito è elencare tutte le date in 100 mila anni che soddisfano tutte e tre le caratteristiche.

Nevermind nulla ma i numeri, utilizzare i seguenti formati: AAAAMMGG e YYYYYMMDD .

Le date tra l'uso01-01 e 9999-12-31 devono essere stampate come date palindromi a 8 cifre (se ce ne sono?) E le date tra 10000-01-01 e 99999-12-31 dovrebbero essere stampate come palindromi a 9 cifre .

Non è obbligatorio elencare le date in ordine cronologico.

Parte di esempio di output valido.

Prime tre date palindromiche prime a 9 cifre:

...
100111001
100131001
100161001
...

Regole

Si applicano scappatoie standard .


Regola: 02-29esiste solo per anni che sono divisibili per 400 o (divisibili per 4 e non divisibili per 100).
user202729,

@ user202729 Sì, penso di sì, ad esempio non credo che il 2017-02-29, il 29/02/2018 e il 1900-02-29 possano essere considerati "date".
Erik the Outgolfer,

4
Non ci sono date palindromiche a 8 cifre che sono anche numeri primi. Ecco un incolla l'elenco che dovremmo restituire / stampare (197 in totale) . @Plarsen è corretto?
Kevin Cruijssen,

1
Dovremmo consentire il 30 febbraio? > timeanddate.com/date/february-30.html
jrtapsell,

Risposte:


5

Rubino , 144 141 byte (134 + 7 per la -rprimebandiera)

3 byte salvati grazie a benj2240 !

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

Provalo online!

L'algoritmo:

  • genera tutte le possibili combinazioni MMDD, da "0101" a "1231"
  • genera tutti gli anni per quella data che si tradurrebbe in un palindromo, invertendo la stringa MMDD e aggiungendo a metà, a sua volta, tutti i caratteri nell'intervallo (0..9)
  • controllare se è una data valida creando Timeun'istanza con le proposta y, m, dvalori. Se l'oggetto tempo risultante ha un #dayvalore uguale a d, quella era una data valida. Altrimenti, cambierebbe la data (ad esempio, i Time.new 2018,2,30ritorni 2018-03-02).
  • controlla se anche la data valida del palindromo è un numero primo e visualizzala se lo è.

Il ciclo interno era inizialmente una funzione chiamata per ciascun elemento (?0..?9)nell'intervallo, nonché per la stringa vuota.

Dal momento che la stringa vuota non ha prodotto risultati (non ci sono palindromi primi a 8 cifre validi), ho deciso di rimuoverlo e rifattorizzare su questa versione.


Penso che puoi salvare qualche byte rimuovendo la tvariabile: TIO
benj2240

@ benj2240 Proprio così! Grazie!
Cristian Lupascu,

4

Python 2 , 116 107 128 122 119 byte

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

La seconda metà del 4 ° linea si ispira mxdsp 's risposta qui ad un'altra domanda di golf .

Spiegazione

La funzione g()accetta un argomento solo per inizializzare la nvariabile usando il suo valore predefinito. Il valore iniziale è un numero dispari il più breve possibile e il più grande possibile pur rimanendo inferiore alla prima risposta valida 100111001.

Ripeti fino a nraggiungere la fine dell'intervallo di date 10 9 . L'incremento ndi 2. mè il mese della data n.

Se nè una data, un palindromo e un numero primi validi, stampalo:

  • Data:
    • 0 < m < 13controlla che msia un mese valido.
    • n % 100 < 31 + (m+m/8)%2controlla che nil giorno del mese sia valido. (m+m/8)%2aggiunge 1per tutti i mesi con 31 giorni. Il merito è della risposta di ArmanX . Non ci sono numeri primi per il 29-30 febbraio.
  • Palindromo: `n`[::-1] == `n`. I backtick si stringono n. [::-1]inverte la stringa.
  • Prime: 2**n % n == 2è un test di primalità di Fermat . Quel test è solo probabilistico. Ci sono anche non primi che corrispondono. Ma non nell'intervallo di numeri che stiamo osservando.

Bello usando il test di primalità di Fermat!
agtoever,

3

APL (Dyalog Unicode) , 155 byte

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

Provalo online!

Questo è un Tradfn ( trad pre- sentano f unctio n ) che accetta un argomento arg = yyyymmddo arg = yyyyymmdd. L'uso è f arg.

Questo non produrrà nulla quando inizia l'argomento 10000101perché non trova una data del primo centro in 60 secondi.

Ecco un approccio meno golfistico che produrrà l'output di esempio dell'OP di

100111001
100131001
100161001

( Provalo online! )

Si noti che entrambi i codici sono identici fino a quando non si chiama la funzione ricorsivamente per la data successiva. Mentre la versione golfata lo chiama semplicemente come f arg+1, il codice meno golfato salta di giorno 31in giorno 01e di mese 12in mese 01, il che accelera un po '.

Come funziona:

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 byte

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)

La soluzione è piuttosto lunga (e probabilmente può essere migliorata), ma non utilizza alcuna funzione integrata per il controllo di prime / date / palindrome. Una versione in qualche modo ungolfed per chiarezza:

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)

Le date valide vengono generate scegliendo un mese e un giorno. Come già detto, è necessario considerare solo la dimensione 9. Si noti inoltre che gli anni bisestili non sono considerati. Ciò non è necessario a causa della fortunata coincidenza che i numeri primi di palindromo di lunghezza 9 che terminano con 0229 semplicemente non esistono (altre anomalie di data come il 30 febbraio 1712 possono essere scartate per lo stesso motivo).

Successivamente la cifra centrale viene scelta liberamente e viene eseguito un test primo. Dato che il test principale doveva essere il più breve possibile, è molto ingenuo e quindi paralizzante. L'uso di una libreria esterna potrebbe risolvere questo problema (e salvare alcuni byte), ma come detto prima non volevo usarne nessuno.


Dovresti fare in modo che il tuo codice appaia esattamente come funziona quando hai contato i byte (in questo caso comprimendo la spaziatura del rientro). Inoltre, è bello che hai incluso una versione ungolfed, ma di solito la versione di golf è nominata per prima
wnnmaw

@wnnmaw L'unica differenza tra la versione che ho contato su quella fornita nella risposta, è che ho usato le schede invece degli spazi che vengono utilizzati qui. Come noto, le schede vengono convertite automaticamente, quindi non vedo alcun modo per risolvere questo problema.
Def

@Def IIRC Python ti consente di utilizzare anche gli spazi come rientri, in questo modo potrebbe apparire uguale anche nella tua risposta. Correggimi se sbaglio nella prima parte però.
elementbound

@elementbound Lo fa davvero, grazie per il suggerimento.
Def

2

WolframLanguage (Mathematica) 187 byte

Potrebbe esserci una certa riduzione delle dimensioni. Spiegazione da seguire ...

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

Casi test

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

Spiegazione del codice

DayRange[d@#,d@#2]restituisce tutte le date tra {10011, 10, 1}e {10017, 1, 1}. In questo caso, restituisce circa 5 anni, 4 mesi di date (precisamente 1920 date). Gli anni bisestili sono presi in considerazione.

Le date vengono restituite nella formattazione standard di Wolfram. Ad esempio, la prima data apparirà come DateObject[List[1,1,1],"Day","Gregorian",-5.] `

#[[1]] & /@rimuoverà la parte della data, in ciascuna data, che ci riguarda. Nell'esempio, DateObject[List[1,3,7],"Day","Gregorian",-5.]restituisce la data abbreviato, {1,3,7}.

t/@p[#3,2]}o ToString/@Padleft[#3,2]riempie il terzo elemento, vale a dire, il 7 in piedi "per il 7 ° giorno del mese" come "07". Un'imbottitura simile viene fornita per il simbolo a una cifra per il mese di marzo, ovvero 3viene restituito come "03".

p[#, If[Length@# < 5, 4, 5]]sposta l'anno con zeri per raggiungere la lunghezza di una stringa di 4 o 5 cifre. In questo caso, gennaio, vale a dire 1, viene restituito come "" 00001 "'.

"" <>...unisce le stringhe. In questo caso, ritorna "000010307".

Cases[...x_ /; PalindromeQ@x && PrimeQ@ToExpression@x] restituisce quei casi, tra le date del 1920, che sono palindromi e numeri primi.


2

Javascript , 187 177

Presupposti: nessun anno corrispondente a 4 cifre; nessun giorno corrispondente a febbraio tra il 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)}}

Funziona così:

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!

Storia:

  • Da 187 a 177: non ci sono date del primo palindromo che cadono il 29 o 30 febbraio, quindi possiamo far finta che febbraio abbia 30 giorni e risparmi 10 caratteri.

Appunti:

Attraverso i test, ho scoperto che non ci sono corrispondenze valide che sono anni a 4 cifre o cadono il 29 o 30 febbraio. Sfortunatamente, per motivi di codice, ci sono esattamente cinque risultati (non validi) che cadono il 31 di vari mesi che hanno solo 31 giorni.


2

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

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 grazie a @assylias .

Spiegazione:

Provalo online (nota: la parte di verifica primaria è stata sostituita con un metodo separato più efficiente, anche se nonostante ciò si interrompe ancora dopo 60 secondi, producendo solo le prime ~ 115 prime date palindromiche).
Pastebin di tutte le 197 uscite da una corsa locale.

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())per salvare 1 carattere (funziona perché sappiamo che entrambe le stringhe hanno la stessa lunghezza). Non è molto :-(
assylias

@assylias Smart, mi piace. Grazie! E sebbene 1 byte non sia molto, è comunque 1 byte. Codegolf mira sempre a renderlo il più breve possibile, quindi ogni byte conta. :)
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

Benvenuti in PPCG! Non conosco VBA, ma sembra che potresti giocare a golf con uno spazio vuoto.
FantaC,

Inoltre non conosco davvero VBA, ma penso che DateStringsia un nome di variabile arbitrario, quindi dovresti essere in grado di ridurlo a un singolo carattere, giusto?
Martin Ender,

3
E penso che ti sia sfuggita la parte principale delle "prime date palindromiche".
mercatore,

Ci sarebbe un codice per calcolare gli anni bisestili (quello ha 29 febbraio giorni)
RosLuP

Mancano anche anni a 5 cifre e Else non è necessario.
Weijun Zhou,

0

Pulito , 262 ... 213 byte

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

Provalo online!


0

Javascript , 234 229 byte

Un po 'ingombrante, ma pubblicandolo per far rotolare la palla JS. Eventuali suggerimenti sono benvenuti!

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

Come funziona:

La magia lanciando cifre si basa principalmente sulla sperimentazione.
Ho iniziato a capire da quale numero sottrarre per ottenere la versione capovolta. Mi importava solo delle ultime due cifre.
Quindi, se prendiamo n, scopriamo kche n+k=flip(n). Per 10<n<20 kiniziato a 101 e aumentato con incrementi di 9. Tuttavia, per n<10questo era 100. Ho assunto un kaumento per ogni salto di 10, e dopo un po 'di giocherellamento ho pensato che fosse corretto.
Quindi, k=100+9*n+n//10dove // ​​significa divisione intera.

Quindi otteniamo n+k = n+(100+9*n+n//10) = 100+10*n+n//10 = flipped(n).

Non posso provare, né affermare che questo funziona per qualsiasi numero, ma ha prodotto risultati corretti per i numeri usati qui.

Per il test di primalità, merito alla risposta di Kevin Cruijssen . Avevo una versione un po 'più corta, ma non sono riuscito a farlo bene:

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

Ho saltato il test del palindromo, ripetendo ciclicamente mesi, giorni e una cifra media in modo da poter costruire stringhe come dDmMxMmDd, dove Dè la prima cifra del giorno, dè la seconda, ecc.

Storia

5 byte salvati eliminando la parte condizionale di q

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

Ci scusiamo per il pasticcio con i conteggi dei byte. Scivolato accidentalmente in alcune linguette. Dovrebbe essere corretto ora.
elementbound

Stai solo usando fil risultato come parametro per q, quindi taglia il middle man e scrivi f=n=>''+n%10+(n/10|0), e il risultato di q è sempre usato come una stringa, così puoi scrivere q=n=>n<10?'0'+n:n.
Neil,

0

APL NARS 626 byte, 313 caratteri

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

questa stampa cosa trova in 50 secondi, che si ferma (perché altrimenti non riesco a fermare il programma per copiare incolla il test, perché non so come fermare il programma senza chiudere le finestre dell'interprete) test:

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

0

Julia 0.6 , 109 byte

Il collegamento passa a una versione più lunga con due differenze:

  1. Verifica la presenza di numeri primi con funzione scritta a mano, poiché il pacchetto Primes non è disponibile su TIO.
  2. Scorre in un intervallo di date diverso per non scadere.
[s for s in Dates.format(Date(0,1,1):Date(100000,1,1),"YYYYmmdd") if Primes.isprime(parse(s))&&s==reverse(s)]

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.