Challenge
Given two positive integers \1ドル \le m \le 12\$ and \1ドル\le d \le 31\$, representing a month and days into the month, output the amount of days that have passed since January 1st, on a non-leap year. You can assume that the number of days passed will always be constrained by the number of days in the month (so \$m = 2, d = 31\$ will never be an input)
This is code-golf so the shortest code in bytes wins.
Examples
For example, \$m = 2, d = 11\$ represents February 11th. This is the 42nd day of the year (31 days in January + 11 days), so the output is 42.
32 Answers 32
Haskell, 27 bytes
m%d=div(275*m)9-30+d-mod 2m
This is a "closed-form" answer (in a C-like language it would be 275*m/9-30+d-2%m).
-
\$\begingroup\$ Looks like this still works: Try it online Though I wonder if some rational approximation with
divwould be shorter. \$\endgroup\$xnor– xnor2021年06月29日 22:24:09 +00:00Commented Jun 29, 2021 at 22:24 -
\$\begingroup\$ @xnor Nice idea! I found one that seems to work. \$\endgroup\$lynn– lynn2021年06月29日 22:29:50 +00:00Commented Jun 29, 2021 at 22:29
-
\$\begingroup\$ It looks like
m%d=div(275*m)9-30+d-mod 2 mwould work for 28. \$\endgroup\$dingledooper– dingledooper2021年06月29日 23:10:35 +00:00Commented Jun 29, 2021 at 23:10 -
\$\begingroup\$ @dingledooper Brilliant! \$\endgroup\$lynn– lynn2021年06月29日 23:12:08 +00:00Commented Jun 29, 2021 at 23:12
-
2\$\begingroup\$ Isn't it usual to credit commenters like @Lynn for shortenings of the original solution? \$\endgroup\$LSpice– LSpice2021年06月30日 14:06:36 +00:00Commented Jun 30, 2021 at 14:06
JavaScript (ES6), (削除) 40 37 (削除ここまで) 36 bytes
Expects (day)(month).
d=>g=m=>--m?31-(4/m&2)+~m%9%2+g(m):d
How?
This is a recursive function that computes the number of days in each full month (i.e. lower than \$m\$), sums them all together and finally adds \$d\$ on the last iteration.
We use 4 / m & 2 to distinguish between February and all other months:
- For January,
4 / 1 & 2is4 & 2, which is \0ドル\$ - For February,
4 / 2 & 2is2 & 2, which is \2ドル\$ - For \$m>2\$,
4 / m & 2is \0ドル\$ because \0ドル<4/m<2\$
We use ~m % 9 % 2 to subtract \1ドル\$ for months that do not have \31ドル\$ days:
m | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11
~m | -2 | -3 | -4 | -5 | -6 | -7 | -8 | -9 | -10 | -11 | -12
mod 9 | -2 | -3 | -4 | -5 | -6 | -7 | -8 | 0 | -1 | -2 | -3
mod 2 | 0 | -1 | 0 | -1 | 0 | -1 | 0 | 0 | -1 | 0 | -1
(This also works for December, but we never have to compute the total number of days in this month.)
Gaia, 6 bytes
A dyadic function taking the month above the day. Gaia has a nice collection of date/time builtins.
(∂k<Σ+
( # decrement the month
∂k # push list [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] (builtin)
< # take the first month-1 elements from this list
Σ # sum them
+ # add the day
JavaScript (Node.js), (削除) 35 (削除ここまで) 32 bytes
m=>d=>--m*31+d-'003344555667'[m]
Thanks to A username for pro golf tips!
-
2\$\begingroup\$ Nice! A 3 byte golf puts you in the lead! \$\endgroup\$emanresu A– emanresu A2021年06月30日 04:22:35 +00:00Commented Jun 30, 2021 at 4:22
C (gcc), (削除) 47 (削除ここまで) 27 bytes
f(d,m){m=275*m/9-30+d-2%m;}
Uses formula from Lynn's Haskell answer.
Bash, 16
date -d1ドル/1 +%-j
Input is given on the command-line as slash-separated integers, with month first.
-
1\$\begingroup\$ i first understood the same, but after reading other answers, should always be a non-leap year. but it depends on current year. \$\endgroup\$Nahuel Fouilleul– Nahuel Fouilleul2021年06月29日 19:46:29 +00:00Commented Jun 29, 2021 at 19:46
-
\$\begingroup\$ @NahuelFouilleul good point. I added 3 bytes so this is no longer dependent on whether or not the current year is a leap year. \$\endgroup\$Digital Trauma– Digital Trauma2021年06月29日 19:58:10 +00:00Commented Jun 29, 2021 at 19:58
Excel formula, 18 Bytes
=DATE(1,A1,B1)-366
- Cell
A1contains the input month. - Cell
B1contains the input day.
Saved 8 bytes from answer by Crissov by evaluating the offset as 366, then added 2 bytes by converting named ranges m and d into cell references.
If leap years were allowed, then it could be shortened to a single function =DATE(0,A1,B1)
-
\$\begingroup\$ Welcome to Code Golf, and nice first answer! This is currently a snippet, as it assumes the input is saved in the variables
MandD. To make it valid by our site rules, you should changeMandDto cell references (e.g.A1andA2) for an additional 2 bytes \$\endgroup\$2021年06月30日 15:21:45 +00:00Commented Jun 30, 2021 at 15:21 -
\$\begingroup\$ Of course,
DATE(1,1,0)is constant! 🤦♂️ \$\endgroup\$Crissov– Crissov2021年07月01日 12:37:10 +00:00Commented Jul 1, 2021 at 12:37 -
\$\begingroup\$ Not worth any bytes here, but you could drop the
0in the leap year option.=DATE(,A1,B1)works the same. \$\endgroup\$Engineer Toast– Engineer Toast2022年11月18日 20:45:02 +00:00Commented Nov 18, 2022 at 20:45
Python 3, (削除) 60 (削除ここまで) (削除) 55 (削除ここまで) 51 bytes, 1-based month
lambda function that accepts the month (1-based) and the day.
-5 bytes: used a "31-days" default month, and the list s accounts for the cumulate (absolute) difference between the actual days of months and 31
-4 bytes: the list is removed from the function parameters, thanks to @Hunaphu and @mic_e
lambda m,d,a=[3,0,3,2,3,2,3,3,2,3,2]:28*(m-1)+sum(a[:m-1])+d # original version
lambda m,d,s=[0,0,3,3,4,4,5,5,5,6,6,7]:31*m-31-s[m-1]+d
lambda m,d:31*m-31-[0,0,3,3,4,4,5,5,5,6,6,7][m-1]+d
Explanation (original version):
m,d: input month and daya[...]: list of days to add to the "base" 28-day month, from january to novemeber, passed as optional argument28*(m-1): the total number of days in the previous "28-days" months+sum(a[:m-1]): add the remaining days of the previous months (as difference actual days - 28)+d: add the days of the selected month
Python 3, (削除) 56 (削除ここまで) (削除) 50 (削除ここまで) 46 bytes, 0-based month
-4 bytes (compared to 1-based month number): if 0-based month number is allowed as input
-6 bytes: used the "31-days" approach
-4 bytes: the list is removed from the function parameters, thanks to @Hunaphu and @mic_e
lambda m,d,a=[3,0,3,2,3,2,3,3,2,3,2]:28*(m)+sum(a[:m])+d # original version
lambda m,d,s=[0,0,3,3,4,4,5,5,5,6,6,7]:31*m-s[m]+d
lambda m,d:31*m-[0,0,3,3,4,4,5,5,5,6,6,7][m]+d
-
2\$\begingroup\$ Turn the list into a byte-string for more compact representation. You need an offset, unfortunately the constant of 31 does not work so I used 32 and added a
+1. Define the list inline in the expression to get rid of thes=. Prepend an extra item to the list to get a 1-based month:lambda m,d:31*m+1-b"X ##$$%%%&&'"[m]+dyielding 39 bytes. \$\endgroup\$mic_e– mic_e2021年06月30日 16:13:09 +00:00Commented Jun 30, 2021 at 16:13 -
1\$\begingroup\$ why not
lambda m,d:31*m-[0,0,3,3,4,4,5,5,5,6,6,7][m]+d? \$\endgroup\$Hunaphu– Hunaphu2021年06月30日 20:38:48 +00:00Commented Jun 30, 2021 at 20:38 -
1\$\begingroup\$ @Hunaphu I don't know, i completely missed that! Thanks! \$\endgroup\$SevC_10– SevC_102021年07月01日 06:47:27 +00:00Commented Jul 1, 2021 at 6:47
-
\$\begingroup\$ @mic_e Thank you, i understand the byte string, a new trick learned! ;) For now, i keep my original approach with the list. \$\endgroup\$SevC_10– SevC_102021年07月01日 06:50:17 +00:00Commented Jul 1, 2021 at 6:50
Japt, 16 bytes
Well, this ain't right :\ Normally Japt would be ruling the roost in a date based challenge but not this time, despite all the tricks I can muster. Which makes me seriously worried that, after 16 long months, I've lost my edge when it comes to golfing on me phone over a few pints down the boozer!
ÒÐBì)nÐUi1z864e5
-
\$\begingroup\$ +1 for typing all that on the phone, and for making me laugh! \$\endgroup\$Luis Mendo– Luis Mendo2021年06月29日 21:59:37 +00:00Commented Jun 29, 2021 at 21:59
-
\$\begingroup\$ @LuisMendo, clearly these 16 months have been longer for you than for me; you forget what I should be capable of on a phone after a feed of pints! \$\endgroup\$Shaggy– Shaggy2021年06月29日 22:05:21 +00:00Commented Jun 29, 2021 at 22:05
-
\$\begingroup\$ I know, I know, you always say that. But I still find it funny :-) I wonder what the people in the pub will think if they see those strange characters on your screen \$\endgroup\$Luis Mendo– Luis Mendo2021年06月29日 22:09:08 +00:00Commented Jun 29, 2021 at 22:09
-
1\$\begingroup\$ @LuisMendo, if they can see straight enough to see my screen then somebody isn't doing their job properly! \$\endgroup\$Shaggy– Shaggy2021年06月30日 08:25:59 +00:00Commented Jun 30, 2021 at 8:25
Factor, 29 bytes
[ 1 -rot <date> day-of-year ]
1 -rot <date>Create a timestamp from the year 1 and the two inputs. (1 is not a leap year according to Factor's calendar vocabulary.) This is the shortest way I know of to create a timestamp object from a month and day.day-of-yearFactor has a builtin for this once you have a timestamp.
Pip, (削除) 24 (削除ここまで) (削除) 23 (削除ここまで) 17 bytes
275*a//9-30+b-2%a
Uses the formula from lynn's Haskell solution. Attempt This Online!
Original approach, 23 bytes:
b+$+A*""@<Da
The code contains unprintable characters. Here's a hexdump:
00000000: 622b 242b 412a 221f 1c1f 1e1f 1e1f 1f1e b+$+A*".........
00000010: 1f1e 2240 3c44 61 .."@<Da
Explanation
a (month) and b (day) are command-line arguments
"..........." String containing characters with codes 31, 28, 31, etc.
for the months January through November
A* Get the ASCII code of each character
Da Decrement a
@< The first (^ that many) items of the list of charcodes
$+ Sum
b+ Add b
APL (Dyalog Unicode), 11 bytes
Full program. Prompts for [month,day]
1⎕DT⊂1900,⎕
Try it on TryAPL! (⎕ is stdin, but is emulated with the variable ∆ since TryAPL doesn't allow stdin)
⎕ prompt for [month,day]; [2,11]
1900, prepend 1900; [1900,2,11]
⊂ enclose to represent as scalar time stamp; [[1900,2,11]]
1⎕DT convert DateTime to days since 1899年12月31日; 42
Vyxal s, 14 bytes
‹»HȦð9E»fẎ28+p
Try it Online! Port of @caird's Jelly solution
‹»HȦð9E»fẎ28+p
»HȦð9E» Push compressed integer 303232332323
f Convert to digits
‹ Ẏ Slice [0:m-1]
28+ Add 28 to each list element
p Prepend to the day of the month
s flag: Sums the top of the stack and outputs the sum.
Jelly, (削除) 16 (削除ここまで) 15 bytes
"LɓịNH’D+288;ḣS
Takes \$d\$ then \$m\$ on the command line
"LɓịNH’D+288;ḣS - Main link. Takes d on the left and m on the right
"LɓịNH’ - Compressed integer; 303232332323
D - Convert to digits; [3, 0, 3, 2, 3, 2, 3, 3, 2, 3, 2, 3]
+28 - Plus 28 to each; [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
8; - Prepend d; [d, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
ḣ - Take the first m
S - Sum
-
1\$\begingroup\$ Do you need the last
3? \$\endgroup\$Neil– Neil2021年06月29日 18:46:51 +00:00Commented Jun 29, 2021 at 18:46 -
\$\begingroup\$ @Neil No, but that's still 16 bytes :/ \$\endgroup\$2021年06月29日 19:04:09 +00:00Commented Jun 29, 2021 at 19:04
-
1\$\begingroup\$ Seems to give the wrong output for \$m=4\,ドル \$d=15\$? It's outputting \46ドル\$ instead of \105ドル\$(which I think should be the right output). \$\endgroup\$Aiden Chow– Aiden Chow2021年06月29日 21:25:22 +00:00Commented Jun 29, 2021 at 21:25
Desmos, (削除) 90 (削除ここまで) (削除) 82 (削除ここまで) 59 bytes
f(m,d)=total([0,31,28,31,30,31,30,31,31,30,31,30][1...m])+d
Saved 23 bytes 'cause I was so dumb... I've been trying to do some clever list manipulation to save bytes, but it never came to my mind to just put the list itself.
Very Brief Explanation:
[0,31,28,31,30,31,30,31,31,30,31,30]: The number of days in each month(excluding December), with an extra 0 element at the beginning.
total( ... [1...m])+d: Sum of the first m elements of the list explained above, then add d.
Try It On Desmos! - Prettified
Solution using Lynn's "closed form" formula, 34 bytes
f(m,d)=floor(275m/9)-30+d-mod(2,m)
This works on my PowerShell 5 on my computer; I can't get it working on TIO:
PowerShell 5, 97 bytes
function s($m,$d){1+(New-Timespan -st (Get-Date -day 1 -mo 1) -e (Get-Date -day $d -mo $m)).Days}
Call as s 2 11 for the example date (month before day-of-month).
Golfed by @mazzy, 82 bytes
PowerShell, 82 bytes
param($m,$d)1+(New-Timespan -st (Date -day 1 -mo 1) -e (Date -day $d -mo $m)).Days
The golfing relies on an alias or implementation of command (Date) that does not exist in a default Windows 10 installation of PowerShell 5. The TIO PowerShell is PowerShell 6 on Linux.
-
\$\begingroup\$ you can omit
get-and you can to useparam($m,$d)insteadfunction s($m,$d):param($m,$d)1+(New-Timespan -st (Date -day 1 -mo 1) -e (Date -day $d -mo $m)).Days. Try it online! \$\endgroup\$mazzy– mazzy2021年06月30日 05:55:35 +00:00Commented Jun 30, 2021 at 5:55 -
\$\begingroup\$ @mazzy -
Datedoesn't work on a default installation of PowerShell 5 on Windows 10. TIO uses PowerShell 6 with Linux as the substrate. \$\endgroup\$Jeff Zeitlin– Jeff Zeitlin2021年06月30日 10:45:10 +00:00Commented Jun 30, 2021 at 10:45 -
\$\begingroup\$ I've tested it now on Windows. It's work with PS5, PS4. see also Joey's tip \$\endgroup\$mazzy– mazzy2021年06月30日 14:26:57 +00:00Commented Jun 30, 2021 at 14:26
-
\$\begingroup\$ It doesn't work with mine - it tells me that
The term 'date' is not recognized as the name of a cmdlet, function, script file, or operable program.. \$\endgroup\$Jeff Zeitlin– Jeff Zeitlin2021年06月30日 14:29:56 +00:00Commented Jun 30, 2021 at 14:29 -
1\$\begingroup\$ FWIW, I never assume that any particular alias exists when I write PowerShell code. \$\endgroup\$Jeff Zeitlin– Jeff Zeitlin2021年06月30日 14:36:22 +00:00Commented Jun 30, 2021 at 14:36
R, 57 bytes
(my own attempt)
function(m,d){F[c(8:14,2:8)]=30:31;F[3]=28;sum(F[1:m],d)}
An alternative R solution to pajonk's answer, without using any date built-ins.
R, 34 bytes
(port of Lynn's answer)
function(m,d)(275*m)%/%9-30+d-2%%m
K (ngn/k), (削除) 25 (削除ここまで) 20 bytes
Solution:
{+/y,x#28+43390446円}
Explanation:
Assumes months are 0-indexed!
Naive approach, there are likely better ones out there.
{+/y,x#28+43390446円} / the solution
{ } / lambda taking implicit x, y args
43390446円 / creates 3 0 3 2 3 2 3 3 2 3 2 from base-4
28+ / add 28 to each item (vectorised)
x# / take 'month' items from this list (January = 0)
y, / prepend 'days'
+/ / sum up
Edits:
- -5 bytes; using deltas against 28 instead of days-per-month
Extra:
- +2 bytes for 1-indexed month
{+/y,x#0,28+43390446円}
Mathematica, 30 bytes
{1}~DateDifference~{1,#,#2+1}&
Returns as a quantity object: Example screenshot
Using the DateDifference builtin and the fact that {y} is treated as January 1st on year y. I thought of {1}~DateDifference~{##}& at first, but sadly DateDifference starts from 0 days instead of 1.
Charcoal, 20 bytes
I+↨E...")"M⟧2"⊖N−31ι1N
Try it online! Link is to verbose version of code. Explanation:
")"M⟧2" Compressed string `03010100101`
... Truncated to length
N Month as an integer
⊖ Decremented
E Map over characters
31 Literal integer `31`
− Subtract
ι Current value
↨ 1 Take the sum
+ Plus
N Day as an integer
I Cast to string
Implicitly print
Base 1 conversion is used in case the list is empty (i.e. January).
MATL, 9 bytes
14Liq:)hs
Explanation
14L % Push [31 28 31 30 31 30 31 31 30 31 30 31]: month lengths (predefined literal)
i % Input: month, m
q % Subtract 1
: % Inclusive range from 1 to that
) % Index into the array of month lengths: gives its first m-1 terms
h % Implicit input: day, d. Concatenate with previous array
s % Sum of array. Implicit display
R, 40 bytes
function(m,d)format(ISOdate(1,m,d),"%j")
Using buildins, returning as string.
Returning as a number (also using buildins):
R, 44 bytes
function(m,d)as.POSIXlt(ISOdate(1,m,d))$yd+1
PHP, 42 bytes
fn($m,$d)=>date(z,mktime(0,0,0,$m,$d,1))+1
Pretty much builtin. The year parameter could be omitted, but the current year would then be used. To avoid a leap year 1 was used (it actually corresponds to 2001 according to the doc). 1 is added because the result is zero indexed.
This is satisfying, the byte count is The Answer, which is also the answer to the test case!
1 byte shorter but less satisfying:
PHP, 41 bytes
fn($m,$d)=>date(z,strtotime("1-$m-$d"))+1
-
1\$\begingroup\$ @Crissov my bad, should have been 1 like in the first version, same count (note that when 0 is used, it's actually the year 2000, which was a leap year too) \$\endgroup\$Kaddath– Kaddath2021年06月30日 12:51:43 +00:00Commented Jun 30, 2021 at 12:51
Excel, (削除) 30 (削除ここまで) 24 bytes
=DATE(1,m,d)-DATE(1,1,0)[24]=DAYS(DATE(1,m,d),DATE(1,1,0))[30]
Edit: I used the year 2001 before, because I do not trust Excel with dates before 1905.
TI-Basic, 12 bytes
dbd(101.1,Ans+.1
Takes input in Ans as an integer in the format DDMM (for example, November 23 is 2311).
0for January,1for February etc.)? \$\endgroup\$