Це щорічне завдання, добре


22

Враховуючи число 1≤n≤365, виведіть n-й день року у форматі «Місячний день дня». Наприклад, задавши 1, слід вивести "1 січня", без "з".

Буде використаний григоріанський календар, і програма не повинна враховувати високосні роки, тому ваша програма ніколи не повинна виводити "29 лютого" за будь-яких обставин. Можна застосовувати будь-який метод, якщо він дотримується згаданого раніше формату "Місячний день". Ваша програма також повинна виводити порядкові параметри, це означає, що вона завжди повинна виводити 1-й, 2-й, 3-й, якщо 1, 2 або 3 повинні бути відповідно днями для будь-якого введення. Допускаються провідні місця або інші відступи.

Це кодовий гольф, тому найкоротше рішення за символами виграє.

Тестові приклади:

1 gives 1st January
2 gives 2nd January
3 gives 3rd January
365 gives 31st December
60 gives 1st March
11 gives 11th January

4
Також чи потрібно змусити повідомлення про помилку на числах> 365? Чи може програма припустити, що це недійсне введення, і йому це не потрібно буде обробляти?
Rɪᴋᴇʀ

5
Оскільки не кожен є носієм англійської мови, ви можете додати, що числа дня 11, 12 і 13 отримують "го", числа, що закінчуються на "1", отримують "st", "2" отримують "nd", "3" отримати "rd", а всі інші отримати "th".
Адам

9
Ого, не приймай відповіді так швидко. Особливо невірні відповіді!
Адам

6
Ви повинні додати принаймні 11(11 - е січня) і 21(21 - го січня) для тестових випадків.
Арнольд

1
І хоча ви редагуєте тестові приклади, можливо, вкажіть, який саме ваш тестовий формат. Кілька відповідей вважали, що 123=це частина необхідного результату. Або просто відредагуйте свої тестові приклади, щоб прочитати щось на кшталт: 365дає31st December
Adám

Відповіді:


9

PHP ,38 40 30 28 байт

<?=date("jS F",86399*$argn);

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

Запуск із php -nFвведенням від STDIN. Приклад (вище названий сценарій y.php):

$ echo 1|php -nF y.php
1st January
$ echo 2| php -nF y.php
2nd January
$ echo 3| php -nF y.php
3rd January
$ echo 11|php -nF y.php
11th January
$ echo 21|php -nF y.php
21st January
$ echo 60|php -nF y.php
1st March
$ echo 365|php -nF y.php
31st December

Пояснення

Побудуйте часову позначку епохи на бажаний день у 1970 році (зручно не високосний рік), помноживши на day number * number of seconds per day(86400). Однак це дасть на один день вище, тому замість цього помножте на number of seconds in a day - 1(86399), що для діапазону вхідних чисел (1 ≤ n≤365) призведе до часової позначки кінця кожного правильного дня. Тоді просто використовуйте вбудований формат дати PHP для виводу.


чому це -nнеобхідно?
Вен

@Вен може бути не у всіх випадках, але просто вимикає будь-які налаштування в локальному php.ini, які могли б створити непослідовну поведінку.
640 Кб

6

Желе ,  79 78  77 байт

-1 виправлення помилки :) (не слід попередньо транспонування , щоб знайти індекс, має розміщувати зворотний хід, але тоді ми можемо хвіст , а не голова)
-1 з допомогою відображення ( ⁽©ṅB+30_2¦2-> ⁽0ṗb4+28m0)

⁽0ṗb4+28m0SRṁRƲœiµṪȮ%30%20«4ị“nḄƲf⁷»s3¤Ṗ,ị“£ṢtẒ⁽ẹ½MḊxɲȧėAṅ ɓaṾ¥D¹ṀẏD8÷ṬØ»Ḳ¤$K

Повна програма, яка друкує результат

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

Як?

буде оновлено пізніше ...

⁽©ṅB+30_2¦2SRṁRƲZœiµḢȮ%30%20«4ị“nḄƲf⁷»s3¤Ṗ,ị“...»Ḳ¤$K - Main Link: integer, n
⁽©ṅB+30_2¦2SRṁRƲZœi - f(n) to get list of integers, [day, month]
⁽©ṅ                 - compressed literal 2741
   B                - to a list of binary digits -> [ 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1]
    +30             - add thirty                    [31,30,31,30,31,30,31,31,30,31,30,31]
         ¦          - sparse application...
        2           - ...to indices: [2]
       _  2         - ...action: subtract two       [31,28,31,30,31,30,31,31,30,31,30,31]
               Ʋ    - last four links as a monad - i.e. f(x):
           S        -   sum x                       365
            R       -   range                       [1..365]
              R     -   range x (vectorises)        [[1..31],[1..28],...]
             ṁ      -   mould like                  [[1..31],[32..59],...]
                Z   - transpose                     [[1,32,...],[2,33,...],...]
                 œi - 1st multi-dimensional index of n  -> [day, month]

µḢȮ%30%20«4ị“nḄƲf⁷»s3¤Ṗ,ị“...»Ḳ¤$K - given [day, month] format and print
µ                                  - start a new monadic chain - i.e. f(x=[day, month])
 Ḣ                                 - head -- get the day leaving x as [month])
  Ȯ                                - print it (with no newline) and yield it
   %30                             - modulo by thirty
      %20                          - modulo by twenty
         «4                        - minimum of that and four
                     ¤             - nilad followed by link(s) as a nilad:
            “nḄƲf⁷»                -   dictionary words "standard"+" the" = "standard the"
                   s3              -   split into threes = ["sta","nda","rd ","the"]
           ị                       - index into
                      Ṗ            - remove rightmost character
                               ¤   - nilad followed by link(s) as a nilad:
                         “...»     -   dictionary words "January"+" February"+...
                              Ḳ    -   split at spaces = ["January","February",...]
                        ị          - index into (vectorises across [month])
                       ,           - pair                  e.g. ["th", ["February"]]
                                K  - join with spaces           ["th ", "February"]
                                   - print (implicitly smashes)   th February

4
"Стандартний" трюк дивовижний.
Вен

Я згоден з @ Ven , чудовий трюк! Це також зберегло байт у моїй відповіді 05AB1E порівняно зі стислим рядком, "thstndrd"розділеним на частини розміром 2 ( .•oθ2(w•2ô), тому дякую. :)
Kevin Cruijssen

1
Це має бути однією з найдовших програм Jelly, яку я коли-небудь бачив.
JAD

6

C # (Visual C # Interactive Compiler) , 115 113 109 98 байт

g=>$"{f=(g=p.AddDays(g-1)).Day}{"tsnr"[f=f%30%20<4?f%10:0]}{"htdd"[f]} {g:MMMM}";DateTime p;int f;

Завдяки @someone за збереження 9 байт

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


1
@KevinCruijssen У мене вийшли модулі з ладу, зараз слід виправити.
Втілення Невідомості

.code.tio(2,22): error CS0165: Use of unassigned local variable 'p'Здається, що структура структура не працює.
JAD

var g=new DateTime().AddDays(n-1)працює хоча
JAD

Помилка @JAD з мого боку, виправлена
Втілення


5

Python 3.8 (передвипуск) , 112 байт

lambda x:str(d:=(t:=gmtime(x*86399)).tm_mday)+'tsnrhtdd'[d%5*(d%30%20<4)::4]+strftime(' %B',t)
from time import*

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

Як не дивно, мені не доведеться скористатися дужками d:=(t:=gmtime(~-x*86400), мабуть, тому, що інтерпретатор перевіряє, чи є ()символи навколо виразу присвоєння, а не те, що сам вираз є в дужках.

-2 завдяки gwaugh .
-5 завдяки xnor .


5

Perl 6 , 166 161 байт

{~(.day~(<th st nd rd>[.day%30%20]||'th'),<January February March April May June July August September October November December>[.month-1])}o*+Date.new(1,1,1)-1

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

Жорсткі коди називають усі місяці, що займає більшу частину місця. Людина, Perl 6 дійсно потребує належного форматера дати.


4

Хак, 115 59 39 байт

$x==>date("jS F",mktime(0,0,0,1,$x));

Оскільки @gwaugh дійшов до того ж рішення, що і мій, коли я займався гольфом, я розміщую це замість у Hack :).


Нічого собі, чудові розуми думають однаково. :) +1 вам, пане!
640 Кб

@gwaugh haha, я не знав, що можу просто мати програму вищого рівня. Я буду правити моїм , щоб зробити це на вищому рівні теж, і знайти спосіб , щоб отримати кращий СКОР е ;-)
Вен

1
@gwaugh Зробив замість цього мій хак.
Вен

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

4

JavaScript (ES6),  117  113 байт

Збережено 4 байти завдяки @tsh

d=>(n=(d=new Date(1,0,d)).getDate())+([,'st','nd','rd'][n%30%20]||'th')+' '+d.toLocaleString('en',{month:'long'})

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

Прокоментував

d =>                     // d = input day
  ( n =                  //
    ( d =                // convert d to
      new Date(1, 0, d)  //   a Date object for the non leap year 1901
    ).getDate()          // save the corresponding day of month into n
  ) + (                  //
    [, 'st', 'nd', 'rd'] // ordinal suffixes
    [n % 30 % 20]        // map { 1, 2, 3, 21, 22, 23, 31 } to { 'st', 'nd', 'rd' }
    || 'th'              // or use 'th' for everything else
  ) + ' ' +              // append a space
  d.toLocaleString(      // convert d to ...
    'en',                // ... the English ...
    { month: 'long' }    // ... month name
  )                      //

Без вбудованих дат, 188 байт

f=(d,m=0)=>d>(k=31-(1115212>>m*2&3))?f(d-k,m+1):d+([,'st','nd','rd'][d%30%20]||'th')+' '+`JanuaryFebruaryMarchAprilMayJuneJulyAugustSeptemberOctoberNovemberDecember`.match(/.[a-z]*/g)[m]

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


Помилка для 11-го, 12-го, 13-го числа кожного місяця
Термін дії закінчився

1
@ExpiredData Дякую за повідомлення про це. Виправлено зараз.
Арнольд

Ігноруйте мій коментар, я зробив помилку ID10T.
асгалант

Я не впевнений, як nodejs обробляє мовні теги, але здається, що використання 0буде працювати як використання "en". А перехід до toLocaleStringврятував би 4 байти. 110 байт
tsh

@tsh Здається, що toLocaleStringвикористовується налаштування системи за замовчуванням, коли він передається невпізнаним рядком або числовим значенням. Отже, це може бути що завгодно. Цей параметр в основному неефективний для екземпляра TIO, оскільки все-таки встановлені лише англійські мови .
Арнольд

4

Маленька розмова, 126 байт

d:=Date year:1day:n.k:=m:=d dayOfMonth.10<k&(k<14)and:[k:=0].o:={#st.#nd.#rd}at:k\\10ifAbsent:#th.m asString,o,' ',d monthName

1
Я не знаю Smalltalk, але це правильно 11th,12th,13th? Якщо я правильно прочитав, ви ціле число діліть день на 10, але це означатиме, що це призведе до 11st,12nd,13rd, якщо щось інше в коді не виправить це, поки я про це не знаю.
Кевін Кройсейсен

@KevinCruijssen Ви праві. Дякуємо, що звернули мою увагу з цього приводу. Щоб виправити це, мені потрібно витратити ще кілька байт.
Леандро Канілья

1
@KevinCruijssen, Готово. Знову дякую.
Леандро Канілья

3

C # (Visual C # Interactive Compiler) , 141 139 133 124 122 байт

a=>{var d=s.AddDays(a-1);int x=d.Day,m=x%30%20;return x+"thstndrd".Substring(m<4?m*2:0,2)+d.ToString(" MMMM");};DateTime s

Завдяки Арноульду за швидший метод видалення 11,12,13-го збереження 4 байтів

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


Використовуючи C # 8, це може бути зведено до: a=>{var d=s.AddDays(a-1);int x=d.Day,m=x%30%20;return x+"thstndrd"[(m<4?m*2:0)..2]+$" {d:MMMM}";};DateTime s Інтерактивний компілятор, схоже, не підтримує зміни свого рівня мови на "попередній перегляд".
Арканокс


Я впевнений, що вам слід додати крапку з двокрапкою післяDataTime s
Втілення Невідомості

3

R , 158 134 байт

-24 байт @ Нік Кеннеді для гри в гольф 'st', 'nd', 'rd' та 'th'. Спасибі!

f=format;paste0(a<-as.double(f(d<-as.Date(scan(,''),'%j'),'%e')),`if`((a-1)%%10>2|a%/%10==1,'th',c("st","nd","rd")[a%%10]),f(d,' %B'))

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



Так, мені потрібно `if`краще вчитися . Спасибі.
Зал КТ

3

MySQL, 47 45 42 байт

SELECT DATE_FORMAT(MAKEDATE(1,n),"%D %M")

1901 можна замінити будь-яким роком, який був / не є високосним.

Редагувати: збережено два байти, видаливши пробіли та ще три байти, змінивши рік на 1, завдяки @Embodyment of Ignorance .


Чи можете ви видалити пробіли між 1901, nі рядком?
Втілення Невідомості

@EmbodimentofIgnorance так, я можу, спасибі!
NicolasB

Крім того, чому б не замінити 1901 рік, як 1? 1 не високосний рік, і це на 3 байти коротше
втілення невігластва

@EmbodimentofIgnorance зроблено і зроблено :-)
NicolasB

3

05AB1E , 81 79 78 76 75 74 73 71 70 69 байт

•ΘÏF•ºS₂+.¥-D0›©ÏθDT‰ć≠*4šß„—ÊØ3ôsè¨ð”……‚應…ä†ï€¿…Ë…ê†Ä…æ…Ì…Í”#®OèJ

-9 байт завдяки @Grimy .
-1 байт завдяки standard theхитрістю @ JonathanAllan th,st,nd,rd, яку він використав у своїй відповіді на Jelly .

Спробуйте в Інтернеті або перевірте всі можливі тестові випадки .

Пояснення:

•ΘÏF        # Push compressed integer 5254545
     º       # Mirror it vertically: 52545455454525
      S      # Converted to a list of digits: [5,2,5,4,5,4,5,5,4,5,4,5,2,5]
       ₂+    # And 26 to each: [31,28,31,30,31,30,31,31,30,31,30,31,28,31]
             # (the additional trailing 28,31 won't cause any issues)
           # Undelta this list (with automatic leading 0):
             #  [0,31,59,90,120,151,181,212,243,273,304,334,365,393,424]
  -          # Subtract each from the (implicit) input-integer
   D0       # Duplicate the list, and check for each if it's positive (> 0)
      ©      # Store the resulting list in the register (without popping)
       Ï     # Only leave the values at those truthy indices
        θ    # And get the last value from the list, which is our day
D            # Duplicate this day
 T          # Take the divmod-10 of this day: [day//10, day%10]
   ć         # Extract the head; pop and push the remainder-list and head: [day%10], day//10
            # Check whether the day//10 is NOT 1 (0 if day//10 == 1; 1 otherwise)
     *       # Multiply that by the [day%10] value
      4š     # Prepend a 4 to this list
        ß    # Pop and push the minimum of the two (so the result is one of [0,1,2,3,4],
             # where the values are mapped like this: 1..3→1..3; 4..9→4; 10..19→0; 20..23→0..3; 24..29→4; 30,31→0,1)
 thŠØ       # Push dictionary string "th standards"
      3ô     # Split it into parts of size 3: ["th ","sta","nda","rds"]
        sè   # Swap and index the integer into this list (4 wraps around to index 0)
          ¨  # And remove the trailing character from this string
ð            # Push a space " "
”……‚應…ä†ï€¿…Ë…ê†Ä…æ…Ì…Í”
             # Push dictionary string "December January February March April May June July August September October November"
 #           # Split on spaces
  ®          # Push the list of truthy/falsey values from the register again
   O         # Get the amount of truthy values by taking the sum
    è        # Use that to index into the string-list of months (12 wraps around to index 0)
J            # Join everything on the stack together to a single string
             # (and output the result implicitly)

Ознайомтеся з цією підказкою 05AB1E, щоб зрозуміти, чому:

  • (розділ Як користуватися словником? ) ”……‚應…ä†ï€¿…Ë…ê†Ä…æ…Ì…Í”є"December January February March April May June July August September October November"
  • (розділ Як користуватися словником? ) …thŠØє"th standards"
  • (Розділ Як стиснути великі цілі числа? ) •ΘÏF•Є5254545

1
-2 байти, використовуючи 5в28 + для стиснення: TIO
Grimmy

1
Використання S - хороша ідея, знову-таки -1 байт: TIO
Grimmy

1
@Grimy Дякую за -1 байт за •EË7Óæ•S₂+, але твій гольф на жаль не працює. Індексація автоматично завершується в 05AB1E, тож 5st,6nd,7rd,25st,26nd,27rd,29stпомилка буде. PS: якби це спрацювало, могло б бути додатково -1. :)
Кевін Круїссен

1
-1 знову (використання "-их стандартів" замість "стандартних" знімає потребу в Á).
Grimmy

1
-1 ( •C.ñÒā•до •ΘÏF•º, зайві цифри не мають значення)
Grimmy

2

bash, 82 80 байт

-2 байти завдяки @ ASCII

a=(th st nd rd);set `printf "%(%e %B)T" $[$1*86399]`;echo $1${a[$1%30%20]-th} $2

ТІО

bash + дата GNU, 77 байт

a=(th st nd rd);set `date -d@$[$1*86399] +%e\ %B`;echo $1${a[$1%30%20]-th} $2


@ Тільки ASCII, так, віднімаючи 100 на кожен день, 100 * 365 = 36500, що менше одного дня (86400), працює також з 86399 (віднімайте 1 день у день)
Nahuel Fouilleul

: / все ще виглядає дуже довго, але ще не знайшли кращого способу
лише ASCII

2

Shell + coreutils, 112 90 байт

date -d0-12-31\ $1day +%-dth\ %B|sed 's/1th/1st/;s/2th/2nd/;s/3th/3rd/;s/\(1.\).. /\1th /'

Спробуйте в Інтернеті! Посилання включає тестові випадки. Редагувати: Збережено 22 байти завдяки @NahuelFouilleul. Пояснення:

date -d0-12-31\ $1day

Обчисліть кількість днів (-ів) після першого дня, що передує не високосному. (На жаль, ви не можете зробити розрахунки відносних дат @-1.)

+%-dth\ %B|sed

Виведіть день місяця (без нуля) thта повну назву місяця.

's/1th/1st/;s/2th/2nd/;s/3th/3rd/;

Виправити 1st, 2nd, 3rd, 21st, 22nd, 23rdі 31st.

s/\(1.\).. /\1th /'

Відновити 11thдо 13th.


Я бачив цю відповідь після моєї, міг би зберегти 18 байт за допомогою однієї команди sed, також sу daysможе бути видалений, і 19в1969
Nahuel Fouilleul

@NahuelFouilleul Цей останній використовує Bash-ism, тому його слід розмістити як окрему відповідь, але дякую за інші поради!
Ніл

2

Желе , 115 114 101 97 байт

%30%20¹0<?4Ḥ+ؽị“thstndrd”ṭ
“5<Ḟ’b4+28ÄŻ_@µ>0T,>0$ƇZṪµ1ịị“£ṢtẒ⁽ẹ½MḊxɲȧėAṅ ɓaṾ¥D¹ṀẏD8÷ṬØ»Ḳ¤,2ịÇƊṚK

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

Довго за стандартами желей, але зроблено з перших принципів.

Завдяки @JonathanAllan за економію 13 байт завдяки кращому розумінню стиснення рядків.


“£ṢtẒ⁽ẹ½MḊxɲȧėAṅ ɓaṾ¥D¹ṀẏD8÷ṬØ»Ḳ¤заощадив би 13 (Compress.dictionary шукає провідний простір і має для нього спеціальну обробку).
Джонатан Аллан


1

Червоний , 124 байти

func[n][d: 1-1-1 + n - 1[rejoin[d/4 either 5 > t: d/4 % 30 % 20[pick[th st nd rd]t + 1]['th]]pick system/locale/months d/3]]

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

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


1

APL (NARS), 235 символів, 470 байт

{k←↑⍸0<w←+\v←(1-⍵),(12⍴28)+13561787⊤⍨12⍴4⋄k<2:¯1⋄d←1+v[k]-w[k]⋄(⍕d),({d∊11..13:'th'⋄1=10∣d:'st'⋄2=10∣d:'nd'⋄3=10∣d:'rd'⋄'th'}),' ',(k-1)⊃(m≠' ')⊂m←'January February March April May June July August September October November December'}

13561787 - це число, яке в базі 4 можна підсумовувати (12⍴28) для отримання тривалості кожного місяця ... тест:

  f←{k←↑⍸0<w←+\v←(1-⍵),(12⍴28)+13561787⊤⍨12⍴4⋄k<2:¯1⋄d←1+v[k]-w[k]⋄(⍕d),({d∊11..13:'th'⋄1=10∣d:'st'⋄2=10∣d:'nd'⋄3=10∣d:'rd'⋄'th'}),' ',(k-1)⊃(m≠' ')⊂m←'January February March April May June July August September October November December'}     
  ⊃f¨1 2 3 365 60 11
1st January  
2nd January  
3rd January  
31st December
1st March    
11th January 


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