Wymień wszystkie palindromowe daty pierwsze między 0000-01-01 a 99999-12-31

11

Wiesz, czym jest palindrom , liczba pierwsza i randka .

Twoim zadaniem jest wymienić wszystkie daty w ciągu 100 tysięcy lat, które spełniają wszystkie trzy cechy.

Nie licz nic poza liczbami, użyj następujących formatów: RRRRMMDD i RRRRRMMDD .

Daty między 0000-01-01 a 9999-12-31 powinny być wydrukowane jako 8-cyfrowe daty palindromów (jeśli istnieją?), A daty między 10000-01-01 a 99999-12-31 powinny być wydrukowane jako 9-cyfrowe palindromy.

Podanie dat w porządku chronologicznym nie jest obowiązkowe.

Przykładowa część prawidłowego wyniku.

Pierwsze trzy 9-cyfrowe pierwsze palindromiczne daty:

...
100111001
100131001
100161001
...

Zasady

Obowiązują standardowe luki .

Plarsen
źródło
Reguła: 02-29istnieje tylko przez lata, które można podzielić przez 400 lub (podzielne przez 4 i niepodzielne przez 100).
user202729,
@ user202729 Tak, myślę, że tak, na przykład nie sądzę, aby 29.02.2017, 29.02.2018 i 1900-02-29 można uznać za „daty”.
Erik the Outgolfer
4
Nie ma żadnych 8-cyfrowych dat palindromicznych, które są również liczbami pierwszymi. Oto pasta z listy, którą mamy zwrócić / wydrukować (w sumie 197) . Czy to poprawne @Plarsen?
Kevin Cruijssen
1
Czy powinniśmy pozwolić 30 lutego? > timeanddate.com/date/f
February

Odpowiedzi:

5

Rubin , 144 141 bajtów (134 + 7 dla -rprimeflagi)

Zaoszczędź 3 bajty dzięki 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)}}}

Wypróbuj online!

Algorytm:

  • wygeneruj wszystkie możliwe kombinacje MMDD, od „0101” do „1231”
  • generuj wszystkie lata dla tej daty, co spowodowałoby palindrom, poprzez odwrócenie ciągu MMDD i dodanie w środku z kolei wszystkich znaków z zakresu (0..9)
  • sprawdzić, czy jest to ważna data tworząc Timeinstancję z danym y, m, dwartości. Jeśli wynikowy obiekt czasu ma #daywartość równą d, to była to prawidłowa data. W przeciwnym razie zmieniłaby datę (na przykład Time.new 2018,2,30zwraca 2018-03-02).
  • sprawdź, czy ważna data palindromu jest również liczbą pierwszą i wyświetl ją, jeśli tak jest.

Pętla wewnętrzna była początkowo funkcją wywoływaną dla każdego elementu w (?0..?9)zakresie, a także dla pustego łańcucha.

Ponieważ pusty ciąg nie przyniósł żadnych wyników (nie ma poprawnych 8-cyfrowych palindromów liczb pierwszych), postanowiłem go usunąć i przełączyć do tej wersji.

Cristian Lupascu
źródło
Myślę, że możesz zaoszczędzić kilka bajtów, usuwając tzmienną: TIO
benj2240
@ benj2240 Zgadza się! Dzięki!
Cristian Lupascu,
4

Python 2 , 116 107 128 122 119 bajtów

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

Druga połowa 4. wierszu jest inspirowana przez mxdsp jest odpowiedź na pytanie innego tutaj golfowego .

Wyjaśnienie

Funkcja g()przyjmuje argument tylko w celu zainicjowania nzmiennej przy użyciu jej wartości domyślnej. Wartością początkową jest liczba nieparzysta, która jest tak krótka, jak to możliwe i tak duża, jak to możliwe, a jednocześnie jest mniejsza niż pierwsza poprawna odpowiedź 100111001.

Pętla, aż nosiągnie koniec zakresu dat 10 9 . Przyrost no 2. mjest miesiącem daty n.

Jeśli njest prawidłową datą, palindromem i liczbą pierwszą, wydrukuj ją:

  • Data:
    • 0 < m < 13sprawdza, który mjest prawidłowy miesiąc.
    • n % 100 < 31 + (m+m/8)%2sprawdza, czy ndzień miesiąca jest ważny. (m+m/8)%2dodaje 1za wszystkie miesiące z 31 dniami. To zasługa odpowiedzi ArmanX . W dniach 29-30 lutego nie ma liczb pierwszych.
  • Palindrom: `n`[::-1] == `n`. Backticks strify n. [::-1]odwraca ciąg.
  • Prime: 2**n % n == 2jest testem pierwotności Fermata . Ten test jest tylko probabilistyczny. Istnieją również pasujące nie-liczby pierwsze. Ale nie w zakresie liczb, na które patrzymy.
mercator
źródło
Fajny przy użyciu testu pierwszeństwa Fermata!
agtoever
3

APL (Dyalog Unicode) , 155 bajtów

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

Wypróbuj online!

To Tradfn ( upr itional F unctio n ), który jeden argument arg = yyyymmddalbo arg = yyyyymmdd. Wykorzystanie jest f arg.

To nie wyświetli niczego, gdy argument rozpocznie się od, 10000101ponieważ nie znajdzie pierwszej daty palindromu w 60 sekund.

Oto mniej golfowe podejście, które da przykładowy wynik PO

100111001
100131001
100161001

( Wypróbuj online! )

Zauważ, że oba kody są dokładnie takie same, dopóki nie zostaną wywołane rekurencyjnie dla następnej daty. Podczas gdy wersja z golfem nazywa to po prostu f arg+1, mniej golfowy kod przeskakuje z dnia 31na dzień 01i z miesiąca 12na miesiąc 01, co znacznie przyspiesza.

Jak to działa:

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é
źródło
2

Python 3, 163 bajty

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)

Rozwiązanie jest dość długie (i prawdopodobnie można je ulepszyć), ale nie używa żadnych wbudowanych funkcji do sprawdzania liczby pierwszej / daty / palindromu. Nieco golfowa wersja dla przejrzystości:

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)

Prawidłowe daty są generowane przez wybranie miesiąca i dnia. Jak skomentowano wcześniej, należy wziąć pod uwagę tylko rozmiar 9. Należy również pamiętać, że lata przestępne nie są brane pod uwagę. Nie jest to wymagane ze względu na szczęśliwy zbieg okoliczności, że liczby pierwsze palindromu o długości 9, które kończą się 0229, po prostu nie istnieją (inne anomalie daty, takie jak 30 lutego 1712 r., Mogą zostać odrzucone z tego samego powodu).

Następnie środkowa cyfra jest wybierana dowolnie i przeprowadzany jest test podstawowy. Ponieważ pierwszy test musiał być jak najkrótszy, jest bardzo naiwny, a przez to kaleki powolny. Korzystanie z zewnętrznej biblioteki może rozwiązać ten problem (i zaoszczędzić trochę bajtów), ale jak wspomniano wcześniej, nie chciałem ich używać.

Def
źródło
Powinieneś sprawić, aby Twój kod wyglądał dokładnie tak, jak ma to miejsce podczas liczenia bajtów (w tym przypadku przez zwijanie odstępów wcięcia). Wspaniale, że dodałeś wersję bez golfa, ale zazwyczaj wersja golfowa jest wymieniona jako pierwsza
wnnmaw
@wnnmaw Jedyną różnicą między wersją, na którą liczyłem, a wersją podaną w odpowiedzi jest to, że użyłem tabulatorów zamiast spacji, które się tutaj wykorzystują. Jak wiem, zakładki są automatycznie konwertowane, więc nie widzę żadnego sposobu, aby to naprawić.
Def
@Def IIRC Python pozwala również używać spacji jako wcięć, w ten sposób może również wyglądać tak samo w odpowiedzi. Popraw mnie, jeśli się mylę w pierwszej części.
elementbound
@elementbound To prawda, dzięki za sugestię.
Def
2

WolframLanguage (Mathematica) 187 bajtów

Może wystąpić pewne zmniejszenie rozmiaru. Wyjaśnienie do naśladowania ...

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

Przypadki testowe

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

Objaśnienie kodu

DayRange[d@#,d@#2]zwraca wszystkie daty pomiędzy {10011, 10, 1}i {10017, 1, 1}. W tym przypadku zwraca około 5 lat, 4 miesiące dat (dokładnie 1920 dat). Lata przestępne są brane pod uwagę.

Daty są zwracane w standardowym formacie Wolfram. Na przykład pierwsza data pojawi się jako DateObject[List[1,1,1],"Day","Gregorian",-5.] `

#[[1]] & /@usunie część daty, w każdej dacie, która nas dotyczy. W tym przykładzie DateObject[List[1,3,7],"Day","Gregorian",-5.]zwraca skróconą datę {1,3,7}.

t/@p[#3,2]}lub ToString/@Padleft[#3,2]wypełnia trzeci element, mianowicie 7, stojąc „na 7 dzień miesiąca” jak "07". Podobne wypełnienie jest zapewnione dla jednocyfrowego symbolu dla marca, mianowicie 3jest zwracane jako "03".

p[#, If[Length@# < 5, 4, 5]]wypełnia rok zerami, aby osiągnąć długość 4 lub 5 cyfr ciągu. W tym przypadku styczeń 1jest zwrócony jako „00001”.

"" <>...łączy struny. W takim przypadku zwraca "000010307".

Cases[...x_ /; PalindromeQ@x && PrimeQ@ToExpression@x] zwraca te przypadki spośród dat z 1920 r., które są palindromami i liczbami pierwszymi.

DavidC
źródło
2

JavaScript , 187 177

Założenia: brak pasujących 4-cyfrowych lat; brak pasujących dni w lutym między 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)}}

Działa to tak:

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!

Historia:

  • 187–177: Nie ma żadnych pierwotnych dat palindromów, które wypadałyby 29 lub 30 lutego, więc możemy udawać, że luty ma 30 dni i zapisać 10 znaków.

Uwagi:

Dzięki testom odkryłem, że nie ma prawidłowych dopasowań, które mają 4-cyfrowe lata lub przypadają 29 lub 30 lutego. Niestety, ze względu na kod, dokładnie pięć (nieprawidłowych) wyników przypada na 31 różnych miesięcy które mają tylko 31 dni.

ArmanX
źródło
2

Java 10, 329 327 320 318 312 308 307 264 bajtów

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 bajt dzięki @assylias .

Wyjaśnienie:

Wypróbuj online (uwaga: część sprawdzania liczby pierwszych została zastąpiona bardziej wydajną metodą oddzielania, chociaż mimo to nadal upływa ona po 60 sekundach, generując tylko pierwsze ~ 115 palindromicznych dat pierwszych).
Wklejanie wszystkich 197 wyników z przebiegu lokalnego.

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
źródło
1
if(t.equals(new StringBuffer(t).reverse()+"")-> if(t.contains(new StringBuffer(t).reverse())aby zapisać 1 znak (działa, ponieważ wiemy, że oba ciągi mają tę samą długość). To niewiele :-(
assylias
@assylias Smart, podoba mi się. Dzięki! I chociaż 1 bajt to niewiele, to wciąż 1 bajt. Codegolf zawsze dąży do tego, aby był jak najkrótszy, więc liczy się każdy bajt. :)
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
źródło
Witamy w PPCG! Nie znam VBA, ale wygląda na to, że możesz pograć w golfa.
FantaC
Ja też tak naprawdę nie znam VBA, ale myślę, że DateStringto dowolna nazwa zmiennej, więc powinieneś być w stanie sprowadzić ją do jednego znaku, prawda?
Martin Ender
3
I myślę, że przegapiłeś główną część „palindromicznych głównych dat”.
mercator
Byłby trochę kodu do obliczania lat przestępnych (ten ma 29 lutego)
RosLuP
Brakuje również 5-cyfrowych lat, a Else nie jest konieczne.
Weijun Zhou,
0

Czysty , 262 ... 213 bajtów

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

Wypróbuj online!

Obrzydliwe
źródło
0

JavaScript , 234 229 bajtów

Trochę nieporęczne, ale opublikowanie go, aby rzucić piłkę JS. Wszelkie sugestie mile widziane!

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

Nie golfowany:

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

Jak to działa:

Magia rzucania cyframi opiera się głównie na eksperymentach.
Zacząłem od wymyślenia, którą liczbę odjąć, aby uzyskać wersję odwróconą. Zależy mi tylko na dwóch ostatnich cyfrach.
Więc jeśli weźmiemy n, znajdź kto n+k=flip(n). Dla początku 10<n<20 kzaczął się od 101 i wzrastał w przyrostach o 9. Jednak dla n<10, było to 100. Zakładałem kwzrost dla każdego skoku o 10, a po odrobinie majstrowania pomyślałem, że to prawda.
Więc, k=100+9*n+n//10gdzie // środki całkowitymi podziału.

Tak otrzymujemy n+k = n+(100+9*n+n//10) = 100+10*n+n//10 = flipped(n) .

Nie mogę udowodnić ani twierdzić, że działa to na dowolną liczbę, ale przyniosło prawidłowe wyniki dla liczb użytych tutaj.

W teście pierwotności podziękowania dla odpowiedzi Kevina Cruijssena . Miałem nieco krótszą wersję, ale nie mogłem tego zrobić poprawnie:

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

Pominąłem test palindromu, zapętlając miesiące, dni i środkową cyfrę, aby móc budować ciągi, ponieważ dDmMxMmDdgdzie Dpierwsza cyfra dnia djest druga, itd.

Historia

Zaoszczędzono 5 bajtów, pozbywając się warunkowej części q

q=n=>n<10?'0'+n:(''+n).slice(-2) // from
q=n=>(''+(100+n)).slice(-2)      // to
elementbound
źródło
Przepraszam za zamieszanie z liczbą bajtów. Przypadkowo wsunął kilka miękkich zakładek. Powinno być teraz poprawne.
elementbound
Zawsze używasz fwyniku jako parametru q, więc wytnij środkowego człowieka i pisz f=n=>''+n%10+(n/10|0), a wynik q jest zawsze używany jako ciąg znaków, więc możesz pisać q=n=>n<10?'0'+n:n.
Neil
0

APL NARS 626 bajtów, 313 znaków

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

wydrukuj to, co znajdę w 50 sekund, niż zatrzymaj się (bo inaczej nie mogę zatrzymać programu do kopiowania, wklej test, ponieważ nie wiem jak zatrzymać program bez zamykania okien interpretera) test:

  f
100111001
100131001
100161001
101030101
101060101
101141101
101171101
102040201
102070201
103000301
103060301
104000401
104030401
104040401
RosLuP
źródło
0

Julia 0.6 , 109 bajtów

Link przechodzi do dłuższej wersji z dwiema różnicami:

  1. Sprawdza liczby pierwsze z funkcją ręcznego pisania, ponieważ pakiet liczb pierwszych nie jest dostępny w TIO.
  2. Powtarza się w innym zakresie dat, aby nie przekroczyć limitu czasu.
[s for s in Dates.format(Date(0,1,1):Date(100000,1,1),"YYYYmmdd") if Primes.isprime(parse(s))&&s==reverse(s)]

Wypróbuj online!

gggg
źródło