Перелічіть усі найголовніші паліндромні дати між 0000-01-01 та 99999-12-31


11

Ви знаєте, що таке паліндром , прем’єр і побачення .

Ваше завдання - перерахувати всі дати за 100 тисяч років, які відповідають усім трьом характеристикам.

Не забудьте нічого, окрім цифр, використовуйте наступні формати: РРРРММДД та РРРРРММДД .

Дати між 0000-01-01 та 9999-12-31 повинні бути надруковані як 8-значні дати паліндром (якщо такі є?), А дати між 10000-01-01 та 99999-12-31 повинні друкуватися як 9-значні паліндроми.

Перераховувати дати в хронологічному порядку не обов'язково.

Приклад частини дійсного виводу.

Перші три 9-значні прості паліндромні дати:

...
100111001
100131001
100161001
...

Правила

Застосовуються стандартні лазівки .


Правило: 02-29існує лише роки, які діляться на 400 або (діляться на 4, а не діляться на 100).
користувач202729

@ user202729 Так, я думаю, що так, наприклад, я не думаю, що 2017-02-29, 2018-02-29 та 1900-02-29 можна вважати "датами".
Ерік Аутгольфер

4
Немає жодних 8-значних паліндромних дат, які також є простими. Ось список, який ми маємо повернути / надрукувати (усього 197) . Це правильно @Plarsen?
Кевін Кройсейсен

1
Чи повинні ми дозволити 30 лютого? > timeanddate.com/date/february-30.html
jrtapsell

Відповіді:


5

Ruby , 144 141 байт (134 + 7 для -rprimeпрапора)

Збережено 3 байти завдяки 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)}}}

Спробуйте в Інтернеті!

Алгоритм:

  • генерувати всі можливі комбінації MMDD, від "0101" до "1231"
  • генерувати всі роки для цієї дати, що призведе до паліндрому, перевернувши рядок MMDD і додавши в середину, в свою чергу, всі знаки в діапазоні (0..9)
  • перевірити, що є дійсною датою шляхом створення Timeекземпляра з урахуванням y, m, dзначення. Якщо отриманий часовий об'єкт має #dayзначення, рівне d, то це була дійсна дата. В іншому випадку вона змістить дату (наприклад, Time.new 2018,2,30повернення 2018-03-02).
  • перевірте, чи дійсна дата паліндром також є простим, і покажіть її, якщо вона є.

Внутрішній цикл спочатку був функцією, яка викликалася для кожного елемента в (?0..?9)діапазоні, а також для порожнього рядка.

Оскільки порожній рядок не дав результатів (немає дійсних 8-значних простих паліндромів), я вирішив видалити його та рефактор до цієї версії.


Я думаю, що ви можете зберегти кілька байтів, видаливши tзмінну: TIO
benj2240

@ benj2240 Правильно! Дякую!
Крістіан Лупаску

4

Python 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 «s відповіді тут на інше питання гольфу .

Пояснення

Функція g()бере аргумент лише для ініціалізації nзмінної, використовуючи її значення за замовчуванням. Початкове значення - непарне число, яке є максимально коротким і максимально великим, хоча воно все ще менше, ніж перша дійсна відповідь 100111001.

Цикл, поки не nдосягне кінця діапазону дат 10 9 . Збільшення nна 2. m- це дата дати n.

Якщо nдійсна дата, паліндром і прайм, роздрукуйте його:

  • Дата:
    • 0 < m < 13перевіряє mчинність місяця.
    • n % 100 < 31 + (m+m/8)%2перевіряє, nчи дійсний день місяця. (m+m/8)%2додає 1за всі місяці з 31 дня. Кредит на який йде до відповіді ArmanX в . 29-30 лютого немає прайменів.
  • Паліндром : `n`[::-1] == `n`. Повернення посилань посилено n. [::-1]обертає рядок.
  • Prime: 2**n % n == 2це тест ферма . Цей тест є лише вірогідним. Також є непрості, які відповідають. Але не в діапазоні чисел, які ми дивимося.

Хороший, використовуючи тест перманентності Ферма!
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 х unctio п ) , який приймає один аргумент arg = yyyymmddабо arg = yyyyymmdd. Використання є f arg.

Це не призведе до появи нічого, коли аргумент починається, 10000101оскільки він не знаходить першої дати паліндром за 60 секунд.

Ось менш гольф-підхід, який дозволить отримати приклад ОП

100111001
100131001
100161001

( Спробуйте в Інтернеті! )

Зауважте, що обидва коди абсолютно однакові до правого часу, перш ніж викликати функцію рекурсивно на наступну дату. Хоча версія для гольфу просто називає це так f arg+1, менш гольф-код перескакує з дня 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)

Рішення досить довге (і, ймовірно, може бути вдосконалено), але не використовує жодних вбудованих функцій для перевірки простим / датою / паліндром. Дещо неозорений варіант для наочності:

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. Також зауважте, що високосні роки не враховуються. Цього не потрібно через вдалий збіг обставин, що паліндромні прайми довжиною 9, які закінчуються 0229 року, просто не існують (інші аномалії дати, такі як 30 лютого 1712 року, можуть бути відкинуті з тієї ж причини).

Далі середня цифра вибирається вільно, і виконується основний тест. Через те, що першочергове випробування повинно було бути якомога коротшим, воно дуже наївне і, таким чином, калічить повільно. Використання зовнішньої бібліотеки могло б вирішити це (і зберегти деякі байти), але, як згадувалося раніше, я не хотів використовувати жоден.


Ви повинні змусити ваш код виглядати саме так, як він працює під час підрахунку байтів (у цьому випадку шляхом згортання проміжків між відступами). Крім того, чудово, що ви включили версію без гольфу, але зазвичай перша версія гольфу вказується вперше
wnnmaw

@wnnmaw Єдина відмінність між версією, яку я розраховував у тій, що надана у відповіді, полягає в тому, що я використовував вкладки замість пробілів, які тут використовуються. Як мені відомо, вкладки автоматично перетворюються, тому я не бачу жодного способу виправити це.
Деф

@Def IIRC Python дозволяє також використовувати пробіли як відступи, таким чином, це може виглядати так само і у вашій відповіді. Виправте мене, якщо я помиляюся в першій частині.
стихійний зв'язок

@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повертаються як "03".

p[#, If[Length@# < 5, 4, 5]]прокладки року з нулями, щоб досягти довжини 4 або 5-значного рядка. У цьому випадку січень 1повертається як "00001".

"" <>...приєднується до струн. У цьому випадку вона повертається "000010307".

Cases[...x_ /; PalindromeQ@x && PrimeQ@ToExpression@x] повертає ті випадки серед дат 1920 р., що є паліндромами та праймерами.


2

Javascript , 187 177

Припущення: немає відповідних чотиризначних років; немає відповідних днів у лютому між 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: Немає найважливіших дат паліндрому, які припадають на 29 або 30 лютого, тому ми можемо зробити вигляд, що лют має 30 днів і збереже 10 символів.

Примітки:

Перевіривши тест, я виявив, що немає жодних дійсних збігів, які мають чотиризначний рік або припадають на 29 або 30 лютого. На жаль, заради коду, рівно п’ять (недійсних) результатів, які припадають на 31 число різних місяців які мають лише 31 день.


2

Java 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;}}

-1 байт завдяки @assylias .

Пояснення:

Спробуйте в режимі он-лайн (зауважте: деталь, що перевіряє прайм, була замінена на більш ефективний відокремлений метод, хоча навіть при тому, що він все-таки вичерпується через 60 секунд, виводячи лише перші ~ 115 паліндромних дат).
Пастебін усіх 197 виходів з локального циклу.

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 завжди полягає в тому, щоб зробити його якомога коротшим, тому кожен байт рахується. :)
Кевін Кройсейсен

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
І я думаю, ви пропустили основну частину "паліндромних прем'єр-побачень".
меркатор

Буде якийсь код для розрахунку високосних років (у цього є 29 лютого)
RosLuP

П'ятизначні роки також відсутні, а Ельзе не потрібно.
Вейджун Чжоу


0

Javascript , 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 і збільшував з кроком у 9. Однак, для n<10цього було 100. Я припускав, що kзбільшується за кожен стрибок у 10, і після трохи хитрування я зрозумів, що це правильно.
Отже, k=100+9*n+n//10де // означає ціле ділення.

Таким чином, ми отримуємо n+k = n+(100+9*n+n//10) = 100+10*n+n//10 = flipped(n).

Я не можу ні довести, ні стверджувати, що це працює для будь-якого числа, але це дало правильні результати для використаних тут чисел.

Для тесту на первинність заслужите відповідь Кевіна Кройссена . У мене була трохи коротша версія, але я не зміг її виправити:

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

Я пропустив тест на паліндром, циклічаючи за місяцями, днями та середньою цифрою, щоб я міг будувати рядки як dDmMxMmDd, де Dперша цифра дня, dдруга - тощо.

Історія

Збережено 5 байт, позбувшись умовної частини q

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

Вибачте за те, що возитися з підрахунками байтів. Випадково потрапив у деякі програмні програми. Має бути правильним зараз.
стимуляція

Ви використовуєте fрезультат лише як параметр для q, тому виріжте середню людину і напишіть f=n=>''+n%10+(n/10|0), а результат q завжди використовується як рядок, щоб ви могли писати q=n=>n<10?'0'+n:n.
Ніл

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 байт

Посилання переходить до більш тривалої версії з двома відмінностями:

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

Спробуйте в Інтернеті!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.