Это ежегодная задача, хорошо

22

Для числа 1≤n≤365 выведите n-й день года в формате «день-число-месяц». Например, если задано 1, вы должны вывести «1 января», без «of».

Будет использоваться григорианский календарь, и программа не должна учитывать високосные годы, поэтому ваша программа никогда не должна выводить «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 get «th», числа, заканчивающиеся на «1» get «st», «2» get «nd», «3» получите "rd", а все остальные - "th".
адам
9
Вау, не принимай ответы так быстро. Особенно не неправильные ответы!
адам
6
Вы должны добавить по крайней мере 11(11 - е января) и 21(21 - го января) для тестовых случаев.
Арно
1
И пока вы редактируете тестовые наборы, возможно, укажите, какой именно у вас формат тестового набора. Пара респондентов подумала, что 123=это часть требуемого результата. Или просто редактировать свои тестовые случаи , чтобы прочитать что - то вроде: 365дает31st December
адам

Ответы:

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 формат даты для вывода.

640 КБ
источник
зачем это -nнужно?
Вент
@Ven это может быть не во всех случаях, а просто отключает любые настройки в локальном php.ini, которые могут привести к нестабильному поведению.
640KB
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
Я согласен с @Ven , отличный трюк! Он также сохранил байт в моем ответе 05AB1E по сравнению со сжатой строкой, "thstndrd"разделенной на части размером 2 ( .•oθ2(w•2ô), так что спасибо. :)
Кевин Круйссен
1
Это должна быть одна из самых длинных программ желе, которые я когда-либо видел.
JAD
6

C # (интерактивный компилятор Visual C #) , 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 с моей стороны
Воплощение Невежества
110 байтов, я думаю
мое местоимение monicareinstate
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 благодаря Гуу .
-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 вам, сэр!
640KB
@ Ха, ха-ха, я не знал, что у меня может быть программа высшего уровня. Я отредактирую мой, чтобы сделать его также на высшем уровне, и найду способ получить лучший результат ;-)
Ven
1
@gwaugh Сделал мой взломать взамен.
Вент
1
Возможно, вы захотите указать параметр не-високосного года для вашего mktime()вызова, иначе он вернет неправильный вывод, если будет работать в високосный год. (должен был сделать мой ответ).
640KB
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]

Попробуйте онлайн!

Arnauld
источник
Сбой 11, 12, 13 числа каждого месяца
Истек срок действия данных
1
@ExpiredData Спасибо за сообщение об этом. Исправлено сейчас.
Арно
Не обращайте внимания на мой комментарий, я сделал ошибку ID10T.
asgallant
Я не уверен, как nodejs обрабатывает языковые теги, но кажется, что использование 0будет работать как использование "en". И изменение в toLocaleStringсэкономит 4 байта. 110 байт
TSH
@tsh Кажется, что toLocaleStringиспользуются системные настройки по умолчанию, когда передается нераспознанная строка или числовое значение. Так что это может быть что угодно. Этот параметр в основном неэффективен для экземпляра TIO, потому что в любом случае устанавливаются только английские локали .
Арно
4

Smalltalk, 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 #) , 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 Интерактивный компилятор, похоже, не поддерживает изменение уровня языка на «предварительный просмотр», однако.
Arcanox
116 байт
Воплощение Невежества
Я почти уверен, что вы должны добавить точку с запятой послеDataTime s
Embodiment of Ignorance
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'))

Попробуйте онлайн!

CT Hall
источник
1
Как насчет tio.run/##HYxBCsIwEEWvIoEwMzDVRldi40K8hQgdmwQV20oSd949xm4e/… для 134 байтов
Ник Кеннеди
Да, мне нужно учиться `if`лучше. Спасибо.
Зал CT
3

MySQL, 47 45 42 байта

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

1901 год можно заменить любым годом, который был / не является високосным.

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

NicolasB
источник
Можете ли вы удалить пробелы между 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₂+, но, к сожалению, ваш -3 гольф не работает. Индексирование автоматически оборачивается в 05AB1E, поэтому 5st,6nd,7rd,25st,26nd,27rd,29stбудет неправильно. PS: если бы это сработало, могло бы быть еще -1. :)
Кевин Круйссен
1
-1 снова (использование «th стандартов» вместо «стандарта» устраняет необходимость Á).
Grimmy
1
-1 ( •C.ñÒā•для •ΘÏF•º, дополнительные цифры не имеют значения)
Grimmy
2

Баш, 82 80 байт

-2 байта благодаря @ ASCII-only

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

TIO

bash + GNU date, 77 байт

a=(th st nd rd);set `date -d@$[$1*86399] +%e\ %B`;echo $1${a[$1%30%20]-th} $2
Науэль Фуйе
источник
80?
Только для ASCII
@ Только для ASCII, да вычитая 100 с за каждый день, 100 * 365 = 36500 с, что меньше одного дня (86400), работает также с 86399 (вычитать 1 с в день)
Науэль Фуийе
: / до сих пор выглядит очень долго, но лучшего способа пока не нашел
ASCII-only
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.

Нил
источник
я видел этот ответ после того, как у меня, может спасти 18bytes с помощью одной SED команды, а также sв daysмогут быть удалены, а 19в1969
Науэль 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, это требует дополнительной настройки. Хорошо, что Red знает названия месяцев :)

Гален Иванов
источник
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) для получения длины каждого месяца ... test:

  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 
RosLuP
источник
-2

Python 3 , 95 байт

Дата это: P

from datetime import *;f=lambda s:(datetime(2019,1,1)+timedelta(days=s-1)).strftime("%d of %B")

Попробуйте онлайн!

Kerosenic
источник
2
Это не производит порядковые суффиксы, и имеет ведущие нули в номере дня. Это ofтакже не нужно
Джо Кинг