Скільки днів на місяць?


25

Враховуючи текстове зображення (повне ім’я без регістру або абревіатура з 3 символами) місяця повертайте кількість днів у місяці.

Так , наприклад, december, DECі decвсі повинні повернутися 31.

Лютий може мати або 28, або 29 днів.

Припустимо, що введення - це місяць в одній з правильних форм.


19
Напевно, ви повинні перерахувати всі варіанти назв місяців, які ми повинні мати можливість прийняти.
Джузеппе

1
Для всіх, хто може ним скористатися, порядкові підсумки ASCII перших трьох символів є унікальними.
абсолютнолюдсько

19
Це було далеко, занадто рано, щоб прийняти рішення.
Shaggy

5
Я думаю, що це було б приємніше, якби введення було лише місяцем у фіксованому форматі, оскільки формат тепер, як правило, вимагає перетворення у фіксований регістр і лише дивлячись на перші 3 букви.
xnor

4
Оскільки це коштує, схоже , ви хочете отримати відповіді обробляти всі з перерахованих форм - «Так , наприклад, december, DECі decповинні все повернення 31» - Цей намір?
Джонатан Аллан

Відповіді:


4

Пайк , 9 байт

l4C9@~%R@

Спробуйте тут!

l4        -   input.title()
    @     -  v.index(^)
  C9      -   ['PADDING', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
        @ - v[^]
     ~%R  -  ['Padding', 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

Або 15 байт, якщо потрібні всі вхідні формати

l43<C9 3L<@~%R@

Спробуйте тут!

l43<            -   input.title()[:3]
          @     -  v.index(^)
    C9 3L<      -   ['PAD', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
              @ - v[^]
           ~%R  -  ['Padding', 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

6
Це повертає 31 для FEB.
Лайконі

2
Я вважаю , що @ точка Laikoni є дійсною (він також повертає 31 для Apr, Jun, Sepі Nov) , але і думати , що це вимагає трохи уточнення в ОП (див мого питання ).
Джонатан Аллан

@JonathanAllan Добре, що ОП прийняла цю відповідь, тож я гадаю, що вона правильна?
Ерік Аутгольфер

4
@EriktheOutgolfer Я б не підходив до цього висновку особисто.
Джонатан Аллан

У мене було враження, що потрібно працювати лише над однією формою входів
Blue

33

JavaScript (ES6),  48 47 44 43  42 байт

m=>31^'311'[parseInt(m[1]+m[2],34)*3%49%8]

Демо

Як?

Ці операції призводять до таблиці пошуку з 8 записів, що було б не дуже цікаво, якби значення були розподілені випадковим чином. Але будь-який результат, більший за 2 , відображається на 31 день. Тому потрібно зберігати лише перші 3 записи.

Month | [1:2] | Base 34 -> dec. | * 3  | % 49 | % 8 | Days
------+-------+-----------------+------+------+-----+-----
  JAN |    AN |             363 | 1089 |   11 |   3 |  31
  FEB |    EB |             487 | 1461 |   40 |   0 |  28
  MAR |    AR |             367 | 1101 |   23 |   7 |  31
  APR |    PR |             877 | 2631 |   34 |   2 |  30
  MAY |    AY |              10 |   30 |   30 |   6 |  31
  JUN |    UN |            1043 | 3129 |   42 |   2 |  30
  JUL |    UL |            1041 | 3123 |   36 |   4 |  31
  AUG |    UG |            1036 | 3108 |   21 |   5 |  31
  SEP |    EP |             501 | 1503 |   33 |   1 |  30
  OCT |    CT |             437 | 1311 |   37 |   5 |  31
  NOV |    OV |             847 | 2541 |   42 |   2 |  30
  DEC |    EC |             488 | 1464 |   43 |   3 |  31

14
чесно, як на землі ти продовжуєш робити ці дивовижні дивні подання з шаленими математиками Д: чи є у вас програма, щоб знайти їх чи ви просто занадто хороші для нас?
HyperNeutrino

1
@HyperNeutrino Перше, що я намагаюся, - це завжди знайти базову конверсію, а потім - необов'язкове множення з наступною однією або декількома операціями модуля. Це було знайдено швидко таким чином. Але я перечитав виклик і спершу подумав, що цього .substr(0,3)не потрібно. Отже, по-друге, це може бути не найкращим підходом.
Арнольд

substr? slice!
Ніл

Мій тривіальний підхід становить лише <s> 2 </s> 3 байти довше, тому він може бути не оптимальним через це, але все ще дуже вражає :)
HyperNeutrino

1
Хтось із редакторів видалив цю частину, але одна з причин, яку я спочатку заборонила, це те, що я хотів побачити відповіді, як ця. Мені подобається база 34 для вирішення питання про капіталізацію та різні формати.
qw3n

15

Javascript (ES6), 36 33 байт

-3 байти завдяки @JustinMariner та @Neil

m=>31-new Date(m+31).getDate()%31

Вибачте @Arnauld, зловживання JavaScript дивністю коротше, ніж ваші фантазійні базові конверсії.

Як це працює

Чомусь JavaScript дозволяє вводити дати поза вказаним місяцем. Код підраховує кількість днів поза місяцем, щоб дати визначити кількість днів у місяці. Приклади:
"FEB31"Thu Mar 02 200031 - 2 % 3129
"October31"Tue Oct 31 200031 - 31 % 3131

Тестові справи


MS Excel також робить це .. Січень 0 - це завжди грудень Останній день, тому = DAY ("01.01.2017") призведе до 31
DavChana

Схоже, що Javascript дозволяє лише рядки дат, де день до 31. Якщо ви спробуєте ввести "feb 32", це перекладається на 2032-02-01, а якщо ви спробуєте примусити його застосувати "0-feb-32" (або подібний рядок), він просто говорить "Недійсна дата". Як не дивно, якщо ви встановите день на 0 ("feb 0"), це означає як 2000-02-01, а не 2000-01-31.
TehPers

Ви можете зберегти байт, скинувши пробіл раніше 31. Здається, це працює в Chrome, new Date("feb31")наприклад.
Джастін Марінер

Насправді, можливо, ви можете використовувати +31економію трьох байтів загалом. Ніщо з цього не працює у Firefox.
Ніл


7

Баш , 21 байт

cal $1|xargs|tail -c3

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

Приймає введення як аргумент командного рядка та виводить з наступного нового рядка. Кількість днів для лютого залежить від поточного року

Потрібно 2,29 Util-Linux версії cal, яка є один доступний на TIO . Також залежить від локальної точки , тому LC_TIME потрібно змінити на не-англійських системах (дякую @Dennis за роз’яснення).

Ідея проходження трубопроводу xargsдо результату обрізки calвиходить з цього відповіді ТА .


2
Це не просто баш. Як правило, це sh, але це, мабуть, майже кожна реалізація оболонки, яка підтримує пошук шляхів і труб, в системі з cal, хвостом та xargs.
kojiro

5

Протон , 50 байт

k=>31-((e=k.lower()[1to3])in"eprunov")-3*(e=="eb")

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

-14 байт завдяки Джонатану Фреху

Тридцять днів має вересень, квітень, червень та листопад. Всі решта мали арахісове масло. Усі, крім моєї бабусі; у неї був невеликий червоний трік, але я його вкрав. муахахахахаха

(Я чекав, щоб розповісти цей жарт (джерело: мій професор математики) протягом століть на цьому сайті: D: D: D)


@Riker ой, ой, що там не було, коли я почав писати це: /
HyperNeutrino

1
Існує нове правило, яке потрібно перевірити на недійсний місяць і повернути 0. Я сподіваюся, що його буде видалено
Level River St

1
Не зважаючи на зміну Я видаляю цю частину
qw3n

Я думаю, ви можете використовувати один рядок 'sepaprjunnov'замість списку рядків.
Джонатан Фрех

@JonathanFrech можливо; Я спробую це, спасибі
HyperNeutrino

4

C # (.NET Core) , 52 + 13 = 65 38 + 24 = 62 байти

m=>D.DaysInMonth(1,D.Parse(1+m).Month)

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

+24 для using D=System.DateTime;

Подяка

-3 байти завдяки Гжегожу Пулавському.


Це працює без using System;? Або ви можете виключити це з числа байтів?
Матті

@Matty Це хороший момент; тепер додано.
Ayb4btu

Пізня порада, але -3 байти: using D=System.DateTime;і m=>D.DaysInMonth(1,D.Parse(1+m).Month)як ось тут: tio.run/##jc5BSwMxEAXgs/…
Grzegorz Puławski

3

Python 3 , 60 байт

x=input().lower()[1:3];print(31-(x in"eprunov")-3*(x=="eb"))

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

Перенесення мого рішення протон

-10 байт завдяки абсолютнолюдському


Краще, ніж мій хе
Томас Уорд


: P вбудовані часом занадто довгі: P
HyperNeutrino

@totallyhuman oh rly wow. +1 thanks :P
HyperNeutrino




2

Python 3 - 93 86 84 82 bytes

Variants of answer (showing the progression of time, and bytes for each, with TIO links):

Original Answer (93 bytes)

-7 bytes thanks to Jonathan Frech. (86 bytes)

-2 more bytes thanks to my own further testing of the monthrange results, with the second value always being the higher value. (84 bytes) 1

-2 more by using import calendar as c and referencing it with c.monthrange. (82 bytes, current revision)


lambda x:c.monthrange(1,time.strptime(x[:3],'%b')[1])[1];import time,calendar as c

Obviously not as nice as HyperNeutrino's answer which doesn't use built-ins, but this still works.


Footnotes

1: Test cases via TIO.run showing the proof for how I'm handling those monthrange values, for a varying number of month test cases.



@JonathanFrech Thanks. Further revised downwards by my having tested more of how monthrange works, and also by using import ...,calendar as c so as not having to type 'calendar' twice.
Thomas Ward


2

Haskell, 65 63 62 bytes

f.map((`mod`32).fromEnum)
f(_:b:c:_)|c<3=28|c>13,b>3=30
f _=31

Try it online!

Pattern matching approach. The first line is to handle the case-insensitivity. Then we return 28 if the third letter is smaller than C (number 3), 30 if the second letter is larger than C and the third one larger than M, or 31 otherwise.

Edit: -1 byte thanks to Leo


Alternative (65 64 bytes)

f s|let i#n=n<mod(fromEnum$s!!i)32=sum$29:[2|2#2]++[-1|2#13,1#3]

Try it online!


1
Clever one! You can save a byte by checking for c<3 instead of a==6 (February is the first month if you order them by their third letter, followed by December)
Leo

2

APL (Dyalog), 32 bytes*

Tacit prefix function. Assumes ⎕IO (Index Origin) 0, which is default on many systems.

31 28 30⊃⍨∘⊃'.p|un|no|f'S 11

Try it online!

⍠1 case insensitively

1 return the length of the

⎕S PCRE Search for

'.p|un|no|f' any-char,"p" or "un" or "no" or "f"

⊃⍨∘⊃ and use the first element of that (0 if none) to pick from

31 28 30 this list

Thus:

  • Apr, Sep, Jun, and Nov will select the number at index 2, namely 30

  • Feb will select the number at index 1, namely 28

  • anything else will select the number at index 0, namely 31


* Using Classic and counting as ⎕OPT.



1

MATL, 22 bytes

14L22Y2c3:Z)Z{kj3:)km)

Try it online!

Explanation

14L    % Push numeric array of month lengths: [31 28 ... 31]
22Y2   % Push cell array of strings with month names: {'January', ..., 'December'}
c      % Convert to 2D char array, right-padding with spaces
3:Z)   % Keep first 3 columns
Z{     % Split into cell array of strings, one each row
k      % Convert to lower case
j      % Input string
3:)    % Keep first 3 characcters
k      % Convert to lower case
m      % Ismember: gives a logical index with one match
)      % Use that as index into array of month lengths. Implicit display

1

Wolfram Language (Mathematica), 46 30 bytes

#~NextDate~"Month"~DayCount~#&

Try it online!

Will give either 28 or 29 for February depending on whether the current year is a leap year.

How it works

All date commands in Mathematica will interpret input such April, APR, ApRiL, and so on as the first day of the corresponding month in the current year. (As a bonus, input such as "February 2016" or {2016,2} also works as expected.)

#~NextDate~"Month" gives the first day of the month after that, and DayCount gives the number of days between its two arguments. The number of days between April 1st and May 1st is 30, the number of days in April.




1

q/kdb+, 36 bytes

Solution:

28 30 31@2^1&(*)"ebeprunov"ss(_)1_3#

Examples:

q)28 30 31@2^1&(*)"ebeprunov"ss(_)1_3#"January"
31
q)28 30 31@2^1&(*)"ebeprunov"ss(_)1_3#"FEB"
28
q)28 30 31@2^1&(*)"ebeprunov"ss(_)1_3#"jun"
30

Explanation:

There are a million ways to skin a cat. I think is slightly different to the others. Take the 2nd and 3rd letters of the input, lowercase them, then look them up in the string "ebeprunov". If they are at location 0, then this is February, if they are at a location >0 they are a 30-dayer, if they are not in the string, they are a 31-dayer.

28 30 31@2^1&first"ebeprunov"ss lower 1_3# / ungolfed solution
                                        3# / take first 3 items from list, January => Jan
                                      1_   / drop the first item from the list, Jan => an
                                lower      / lower-case, an => an
                  "ebeprunov"ss            / string-search in "ebeprunov", an => ,0N (enlisted null)
             first                         / take the first, ,0N => 0N
           1&                              / take max (&) with 1, 0N => 0N
         2^                                / fill nulls with 2, 0N => 2
        @                                  / index into
28 30 31                                   / list 28,30,31

1

Excel VBA, 47 43 Bytes

Anonymous VBE immediate window function that takes input, as month name, abbreviation, or number, from range [A1] and outputs the length of that month in the year 2001 to the VBE immediate window function.

?31-Day(DateValue("1 "&[A1]&" 1")+30)Mod 31

Old Version

d=DateValue(["1 "&A1&" 1"]):?DateAdd("m",1,d)-d

1

PHP, 38 33+1 32+1 bytes

Saved 5 bytes thanks to Titus

<?=date(t,strtotime("$argn 1"));

Run as pipe with -nF

Try it online!


1
Hey, I don't think you need .' 1', it seems to work on TIO without it!
Dom Hastings

1
28+1 bytes: <?=date(t,strtotime($argn)); (run as pipe with -nF)
Titus

3
@DomHastings - so, before I posted, I had tested to see if it would work without the .' 1', but it wasn't working. After seeing your comment, I tried to figure out what I had done wrong. Because I was running it on the 31st of the month, it was taking the 31st (current) day for any month I put in, which would put it beyond the current month. Feb 31st turns into March 3rd, so the code returns 31 (the number of days in March). Because of this, every month was returning 31. So, it works without the .' 1' on any day <= 28th of the month.
Jo.

Ahhh, I forget about how PHP fills in the blanks! Thanks for explaining!
Dom Hastings

@Titus Thank you. I'm such a golf newbie! I don't know why I didn't realize the 't' -> t. Also, I had to do a bunch of searching to figure out how to "run as pipe with -nF" but I got it figured out (I think). :)
Jo.


0

QBIC, 49 35 bytes

?31-(instr(@aprjunsepnov feb`,;)%3)

Significantly shorter with some trickery.

Explanation

?                          PRINT
31-(                       31 minus
  instr(                   the position of
                      ,;   our input string
    @aprjunsepnov feb`  )  in the string cntaining all non-31 months                                
    %3)                    modulo 3 (this yields a 1 for each month except feb=2)


0

Ruby, 45 bytes

->m{((Date.parse(m)>>1)-1).day}
require'date'

Try it online!

Ruby's Date.parse accepts a month name on its own. What would normally be a right-shift (>>) actually adds to the month of the Date object. Subtraction affects the day of the month, which will wrap backwards to the last day of the previous month.


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