Daftar semua tanggal utama palindromic antara 0000-01-01 dan 99999-12-31

11

Anda tahu apa itu palindrome , prime, dan kencan .

Tugas Anda adalah membuat daftar semua tanggal dalam 100 ribu tahun yang memenuhi ketiga karakteristik.

Jangan pikirkan apa pun selain angka, gunakan format berikut: YYYYMMDD dan YYYYYMMDD .

Tanggal antara 0000-01-01 dan 9999-12-31 harus dicetak sebagai tanggal 8 digit palindrom (Jika ada?) Dan tanggal antara 10000-01-01 dan 99999-12-31 harus dicetak sebagai palindrom 9 digit .

Tidak wajib mencantumkan tanggal dalam urutan kronologis.

Contoh bagian dari output yang valid.

Tiga tanggal 9 digit pertama palindromik prima:

...
100111001
100131001
100161001
...

Aturan

Celah standar berlaku.

Plarsen
sumber
Aturan: 02-29hanya ada selama bertahun-tahun yang dapat dibagi 400 atau (habis dibagi 4 dan tidak habis dibagi 100).
user202729
@ user202729 Ya, saya kira begitu, misalnya saya tidak berpikir 2017-02-29, 2018-02-29 dan 1900-02-29 dapat dianggap "tanggal".
Erik the Outgolfer
4
Tidak ada tanggal palindromik 8 digit yang juga merupakan bilangan prima. Ini adalah pastebin dari daftar yang seharusnya kita kembalikan / cetak (total 197) . Apakah ini benar @Plarsen?
Kevin Cruijssen
1
Haruskah kita mengizinkan 30 Februari? > timeanddate.com/date/february-30.html
jrtapsell

Jawaban:

5

Ruby , 144 141 byte (134 + 7 untuk -rprimebendera)

Disimpan 3 byte berkat 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)}}}

Cobalah online!

Algoritma:

  • menghasilkan semua kemungkinan kombinasi MMDD, dari "0101" hingga "1231"
  • menghasilkan semua tahun untuk tanggal itu yang akan menghasilkan palindrome, dengan membalikkan string MMDD dan menambahkan di tengah, pada gilirannya, semua karakter dalam kisaran (0..9)
  • memeriksa apakah itu adalah tanggal yang valid dengan menciptakan Timemisalnya dengan diberikan y, m, dnilai-nilai. Jika objek waktu yang dihasilkan memiliki #daynilai yang sama dengan d, maka itu adalah tanggal yang valid. Kalau tidak, itu akan menggeser tanggal (misalnya, Time.new 2018,2,30kembali 2018-03-02).
  • periksa apakah tanggal palindrom yang valid juga merupakan prima dan tampilkan jika itu.

Loop dalam awalnya merupakan fungsi yang dipanggil untuk setiap elemen dalam (?0..?9)rentang, serta untuk string kosong.

Karena string kosong tidak membuahkan hasil (tidak ada palindrom prime 8 digit yang valid), saya memutuskan untuk menghapusnya dan melakukan refactor ke versi ini.

Cristian Lupascu
sumber
Saya pikir Anda dapat menyimpan beberapa byte dengan menghapus tvariabel: TIO
benj2240
@ benj2240 Benar! Terima kasih!
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

Paruh kedua dari baris ke-4 terinspirasi oleh jawaban mxdsp di sini untuk pertanyaan golf lainnya .

Penjelasan

Fungsi hanya g()membutuhkan argumen untuk menginisialisasi nvariabel menggunakan nilai standarnya. Nilai awal adalah angka ganjil yang sesingkat mungkin dan sebesar mungkin sementara masih kurang dari jawaban valid pertama 100111001.

Ulangi hingga nmencapai akhir rentang tanggal 10 9 . Kenaikan nmenurut 2. madalah bulan tanggal n.

Jika ntanggal yang valid, palindrome dan prime, cetak:

  • Tanggal:
    • 0 < m < 13memeriksa itu madalah bulan yang valid.
    • n % 100 < 31 + (m+m/8)%2memeriksa bahwa nhari dalam bulan itu valid. (m+m/8)%2menambahkan 1semua bulan dengan 31 hari. Penghargaan untuk itu berlaku untuk jawaban ArmanX . Tidak ada bilangan prima untuk 29-30 Februari.
  • Palindrom: `n`[::-1] == `n`. The backticks menguat n. [::-1]membalikkan string.
  • Prime: 2**n % n == 2adalah tes primitif Fermat . Tes itu hanya probabilistik. Ada juga non-prima yang cocok. Tetapi tidak dalam kisaran angka yang kita lihat.
mercator
sumber
Bagus menggunakan tes primitif 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

Cobalah online!

Ini adalah Tradfn ( trad itional f unctio n ) yang mengambil satu argumen arg = yyyymmddatau arg = yyyyymmdd. Penggunaan adalah f arg.

Ini tidak akan menghasilkan apa pun ketika argumen dimulai 10000101karena tidak menemukan tanggal palindrom utama dalam 60 detik.

Berikut adalah pendekatan yang kurang golf yang akan menampilkan output contoh OP

100111001
100131001
100161001

( Cobalah Online! )

Perhatikan bahwa kedua kode sama persis sampai tepat sebelum memanggil fungsi secara rekursif untuk tanggal berikutnya. Sementara versi golf hanya menyebutnya sebagai f arg+1, kode yang kurang golf melompat dari hari 31ke hari01 dan dari bulan 12ke bulan 01, yang mempercepatnya sedikit.

Bagaimana itu bekerja:

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é
sumber
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)

Solusi cukup panjang (dan mungkin bisa diperbaiki), tetapi tidak menggunakan fungsi bawaan untuk pemeriksaan prime / date / palindrome. Versi yang agak tidak jernih untuk kejelasan:

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)

Tanggal yang valid dihasilkan dengan memilih satu bulan dan satu hari. Seperti yang dikomentari sebelumnya, hanya ukuran 9 yang perlu dipertimbangkan. Perhatikan juga bahwa tahun kabisat tidak dipertimbangkan. Ini tidak diperlukan karena kebetulan kebetulan bahwa bilangan prima palindrome dengan panjang 9 yang berakhir pada 0229 tidak ada (anomali tanggal lainnya seperti 30 Februari 1712 dapat dibuang karena alasan yang sama).

Berikutnya digit tengah dipilih secara bebas, dan tes utama dilakukan. Karena tes prima harus sesingkat mungkin, sangat naif dan dengan demikian lambat. Menggunakan perpustakaan eksternal dapat menyelesaikan ini (dan menyimpan beberapa byte), tetapi seperti yang disebutkan sebelumnya saya tidak ingin menggunakan.

Def
sumber
Anda harus membuat kode Anda terlihat persis seperti yang dilakukannya ketika Anda menghitung byte (dalam hal ini dengan menciutkan spasi indentasi). Juga, sangat bagus bahwa Anda memasukkan versi yang tidak disunat, tetapi biasanya versi golf didaftar pertama
wnnmaw
@wnnmaw Satu-satunya perbedaan antara versi yang saya hitung pada versi yang disediakan dalam jawaban, adalah saya menggunakan tab alih-alih spasi yang digunakan di sini. Seperti yang saya ketahui, tab dapat dikonversi secara otomatis, jadi saya tidak melihat cara untuk memperbaikinya.
Def
@Def IIRC Python memungkinkan Anda untuk menggunakan spasi sebagai lekukan juga, dengan cara itu bisa terlihat sama dalam jawaban Anda juga. Koreksi saya jika saya salah pada bagian pertama.
Elementbound
@elementbound Memang, terima kasih atas sarannya.
Def
2

Bahasa Wolfram (Mathematica) 187 byte

Mungkin ada beberapa pengurangan ukuran yang bisa ditemukan. Penjelasan untuk mengikuti ...

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

Uji kasus

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

Penjelasan kode

DayRange[d@#,d@#2]mengembalikan semua tanggal antara {10011, 10, 1}dan{10017, 1, 1} . Dalam hal ini, ia mengembalikan sekitar 5 tahun, 4 bulan tanggal (tepatnya 1920 tanggal). Tahun kabisat diperhitungkan.

Tanggal dikembalikan dalam format standar Wolfram. Misalnya, tanggal pertama akan muncul sebagai DateObject[List[1,1,1],"Day","Gregorian",-5.] `

#[[1]] & /@akan menghapus bagian tanggal, di setiap tanggal, yang menjadi perhatian kami. Dalam contoh, DateObject[List[1,3,7],"Day","Gregorian",-5.]kembalikan tanggal yang disingkat {1,3,7},.

t/@p[#3,2]}atau ToString/@Padleft[#3,2]bantalan elemen ketiga, yaitu, 7 berdiri "untuk hari ke 7 bulan itu" sebagai "07". Padding serupa disediakan untuk simbol satu digit untuk bulan Maret, yaitu, 3dikembalikan sebagai "03".

p[#, If[Length@# < 5, 4, 5]]mengisi tahun dengan nol untuk mencapai panjang string 4 atau 5 digit. Dalam hal ini, Januari, yaitu 1, dikembalikan sebagai `" 00001 "'.

"" <>...bergabung dengan string. Dalam hal ini, ia kembali "000010307".

Cases[...x_ /; PalindromeQ@x && PrimeQ@ToExpression@x] mengembalikan kasus-kasus itu, di antara tahun 1920, yang merupakan palindrom dan bilangan prima.

DavidC
sumber
2

Javascript , 187 177

Asumsi: tidak ada pencocokan 4 digit tahun; tidak ada hari yang cocok di bulan Februari antara 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)}}

Ini berfungsi seperti ini:

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!

Sejarah:

  • 187 hingga 177: Tidak ada tanggal palindrom utama yang jatuh pada 29 atau 30 Februari, sehingga kita dapat berpura-pura bahwa Feb memiliki 30 hari dan menyimpan 10 karakter.

Catatan:

Melalui pengujian, saya menemukan tidak ada kecocokan yang valid yaitu 4 digit tahun atau jatuh pada 29 atau 30 Februari. Sayangnya, hanya demi kode, lima hasil (tidak valid) tepat jatuh pada tanggal 31 dari berbagai bulan yang hanya memiliki 31 hari.

ArmanX
sumber
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 terima kasih kepada @assylias .

Penjelasan:

Cobalah secara online (catatan: bagian pengecekan utama telah diganti dengan metode terpisah yang lebih efisien, meskipun dengan itu masih habis setelah 60 detik, hanya mengeluarkan tanggal utama ~ 115 palindromik utama).
Pastebin dari ke-197 keluaran dari proses lokal.

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
sumber
1
if(t.equals(new StringBuffer(t).reverse()+"")-> if(t.contains(new StringBuffer(t).reverse())untuk menyimpan 1 karakter (berfungsi karena kita tahu kedua string memiliki panjang yang sama). Itu tidak banyak :-(
assylias
@assylias Smart, saya menyukainya. Terima kasih! Dan meskipun 1 byte tidak banyak, itu masih 1 byte. Codegolf selalu tentang membuatnya sesingkat mungkin, jadi setiap byte penting. :)
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
sumber
Selamat datang di PPCG! Saya tidak tahu VBA, tapi sepertinya Anda bisa bermain golf di luar angkasa.
FantaC
Saya juga tidak benar-benar tahu VBA, tetapi saya pikir DateStringini adalah nama variabel yang berubah-ubah, jadi Anda harus dapat menguranginya menjadi satu karakter, bukan?
Martin Ender
3
Dan saya pikir Anda melewatkan bagian utama dari "tanggal utama palindrom".
Mercator
Akan ada beberapa kode untuk menghitung tahun kabisat (yang memiliki 29 hari Februari)
RosLuP
Tahun 5-digit juga hilang, dan Lain-lain tidak perlu.
Weijun Zhou
0

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

Cobalah online!

Suram
sumber
0

Javascript , 234 229 byte

Agak tebal, tapi mempostingnya untuk membuat bola JS bergulir. Ada saran!

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

Tidak Disatukan:

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

Bagaimana itu bekerja:

Digit flipping magic sebagian besar didasarkan pada percobaan.
Saya mulai dengan mencari tahu nomor apa yang harus dikurangi untuk mendapatkan versi terbalik. Saya hanya peduli dengan dua digit terakhir.
Jadi, jika kita ambil n, temukan kitu n+k=flip(n). Untuk 10<n<20 kmulai dari 101 dan meningkat secara bertahap 9. Namun, untuk n<10, ini adalah 100. Saya mengasumsikan kmeningkat untuk setiap lompatan 10, dan setelah sedikit mengutak-atik saya pikir itu benar.
Begitu,k=100+9*n+n//10 mana // berarti pembagian integer.

Jadi, kita dapatkan n+k = n+(100+9*n+n//10) = 100+10*n+n//10 = flipped(n).

Saya tidak dapat membuktikan, juga tidak mengklaim bahwa ini berfungsi untuk nomor apa pun, tetapi ini menghasilkan hasil yang benar untuk nomor yang digunakan di sini.

Untuk tes primality, berikan penghargaan untuk jawaban Kevin Cruijssen . Saya memiliki versi yang sedikit lebih pendek, tetapi saya tidak dapat melakukannya dengan benar:

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

Saya melewatkan tes palindrome, dengan memutar selama berbulan-bulan, berhari-hari, dan digit tengah sehingga saya dapat membangun string dDmMxMmDd, di mana Ddigit pertama hari itu, dadalah yang kedua, dll.

Sejarah

Disimpan 5 byte dengan menyingkirkan bagian bersyarat dari q

q=n=>n<10?'0'+n:(''+n).slice(-2) // from
q=n=>(''+(100+n)).slice(-2)      // to
terikat elemen
sumber
Maaf untuk bermain-main dengan jumlah byte. Tergelincir dalam beberapa tab lunak secara tidak sengaja. Seharusnya benar sekarang.
elementbound
Anda hanya menggunakan fhasil sebagai parameter q, jadi hilangkan perantara dan tulis f=n=>''+n%10+(n/10|0), dan hasil q selalu digunakan sebagai string, sehingga Anda dapat menulis q=n=>n<10?'0'+n:n.
Neil
0

APL NARS 626 byte, 313 karakter

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

cetak ini menemukan apa dalam 50 detik, daripada berhenti sendiri (karena kalau tidak saya tidak dapat menghentikan program untuk menyalin paste tes, karena saya tidak tahu bagaimana menghentikan program tanpa menutup jendela penerjemah) tes:

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

Julia 0,6 , 109 byte

Tautan menuju ke versi yang lebih panjang dengan dua perbedaan:

  1. Memeriksa bilangan prima dengan fungsi tulisan tangan, karena paket Primes tidak tersedia di TIO.
  2. Iterate pada rentang tanggal yang berbeda untuk tidak time out
[s for s in Dates.format(Date(0,1,1):Date(100000,1,1),"YYYYmmdd") if Primes.isprime(parse(s))&&s==reverse(s)]

Cobalah online!

gggg
sumber