19
\$\begingroup\$

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 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.

Kjetil S
6,15911 silver badges23 bronze badges
asked Jun 29, 2021 at 17:42
\$\endgroup\$
9
  • \$\begingroup\$ What are the allowed/required formats for input? \$\endgroup\$ Commented Jun 29, 2021 at 17:47
  • 3
    \$\begingroup\$ @JeffZeitlin The default is that separation doesn't matter, nor does order \$\endgroup\$ Commented Jun 29, 2021 at 17:55
  • 1
    \$\begingroup\$ Can we take the month as zero indexed (e.g. 0 for January, 1 for February etc.)? \$\endgroup\$ Commented Jun 29, 2021 at 17:56
  • 2
    \$\begingroup\$ Welcome to Code Golf and nice first question! For future reference, we recommend using the Sandbox to get feedback on challenge ideas before posting them to main. I've cleared the question up a little bit, feel free to revert my changes if you want. I'd suggest you clarify slightly around "have passed since Jan 1st", as that could change the output by a day (e.g. if \$m = 1, d = 1\$ how many days have passed since that day?) \$\endgroup\$ Commented Jun 29, 2021 at 18:02
  • 3
    \$\begingroup\$ @JeffZeitlin You can assume all meta consensus'ed default input methods. \$\endgroup\$ Commented Jun 29, 2021 at 18:15

32 Answers 32

1
2
17
\$\begingroup\$

Haskell, 27 bytes

m%d=div(275*m)9-30+d-mod 2m

Try it online!

This is a "closed-form" answer (in a C-like language it would be 275*m/9-30+d-2%m).

answered Jun 29, 2021 at 19:24
\$\endgroup\$
7
  • \$\begingroup\$ Looks like this still works: Try it online Though I wonder if some rational approximation with div would be shorter. \$\endgroup\$ Commented Jun 29, 2021 at 22:24
  • \$\begingroup\$ @xnor Nice idea! I found one that seems to work. \$\endgroup\$ Commented Jun 29, 2021 at 22:29
  • \$\begingroup\$ It looks like m%d=div(275*m)9-30+d-mod 2 m would work for 28. \$\endgroup\$ Commented Jun 29, 2021 at 23:10
  • \$\begingroup\$ @dingledooper Brilliant! \$\endgroup\$ Commented Jun 29, 2021 at 23:12
  • 2
    \$\begingroup\$ Isn't it usual to credit commenters like @Lynn for shortenings of the original solution? \$\endgroup\$ Commented Jun 30, 2021 at 14:06
9
\$\begingroup\$

JavaScript (ES6), (削除) 40 37 (削除ここまで) 36 bytes

Expects (day)(month).

d=>g=m=>--m?31-(4/m&2)+~m%9%2+g(m):d

Try it online!

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 & 2 is 4 & 2, which is \0ドル\$
  • For February, 4 / 2 & 2 is 2 & 2, which is \2ドル\$
  • For \$m>2\$, 4 / m & 2 is \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.)

answered Jun 29, 2021 at 18:27
\$\endgroup\$
8
\$\begingroup\$

Gaia, 6 bytes

A dyadic function taking the month above the day. Gaia has a nice collection of date/time builtins.

(∂k<Σ+

Try it online!

( # 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
answered Jun 29, 2021 at 21:50
\$\endgroup\$
7
\$\begingroup\$

JavaScript, 33 bytes

m=>d=>((m+9)%12*51+99)*.6%365+d|0

Try it online!

answered Jun 30, 2021 at 2:35
\$\endgroup\$
7
\$\begingroup\$

JavaScript (Node.js), (削除) 35 (削除ここまで) 32 bytes

m=>d=>--m*31+d-'003344555667'[m]

Try it online!

Thanks to A username for pro golf tips!

answered Jun 30, 2021 at 0:01
\$\endgroup\$
1
  • 2
    \$\begingroup\$ Nice! A 3 byte golf puts you in the lead! \$\endgroup\$ Commented Jun 30, 2021 at 4:22
6
\$\begingroup\$

C (gcc), (削除) 47 (削除ここまで) 27 bytes

f(d,m){m=275*m/9-30+d-2%m;}

Try it online!

Uses formula from Lynn's Haskell answer.

answered Jun 29, 2021 at 21:50
\$\endgroup\$
5
\$\begingroup\$

Bash, 16

date -d1ドル/1 +%-j

Input is given on the command-line as slash-separated integers, with month first.

Try it online!

answered Jun 29, 2021 at 18:00
\$\endgroup\$
2
  • 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\$ Commented 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\$ Commented Jun 29, 2021 at 19:58
5
\$\begingroup\$

Excel formula, 18 Bytes

=DATE(1,A1,B1)-366
  • Cell A1 contains the input month.
  • Cell B1 contains 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)

answered Jun 30, 2021 at 14:37
\$\endgroup\$
3
  • \$\begingroup\$ Welcome to Code Golf, and nice first answer! This is currently a snippet, as it assumes the input is saved in the variables M and D. To make it valid by our site rules, you should change M and D to cell references (e.g. A1 and A2) for an additional 2 bytes \$\endgroup\$ Commented Jun 30, 2021 at 15:21
  • \$\begingroup\$ Of course, DATE(1,1,0) is constant! 🤦‍♂️ \$\endgroup\$ Commented Jul 1, 2021 at 12:37
  • \$\begingroup\$ Not worth any bytes here, but you could drop the 0 in the leap year option. =DATE(,A1,B1) works the same. \$\endgroup\$ Commented Nov 18, 2022 at 20:45
5
\$\begingroup\$

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

Try it online!

Explanation (original version):

  • m,d: input month and day
  • a[...]: list of days to add to the "base" 28-day month, from january to novemeber, passed as optional argument
  • 28*(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
answered Jun 30, 2021 at 11:01
\$\endgroup\$
4
  • 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 the s=. Prepend an extra item to the list to get a 1-based month: lambda m,d:31*m+1-b"X ##$$%%%&&'"[m]+d yielding 39 bytes. \$\endgroup\$ Commented 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\$ Commented Jun 30, 2021 at 20:38
  • 1
    \$\begingroup\$ @Hunaphu I don't know, i completely missed that! Thanks! \$\endgroup\$ Commented 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\$ Commented Jul 1, 2021 at 6:50
4
\$\begingroup\$

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

Try it

answered Jun 29, 2021 at 21:33
\$\endgroup\$
4
  • \$\begingroup\$ +1 for typing all that on the phone, and for making me laugh! \$\endgroup\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented Jun 30, 2021 at 8:25
4
\$\begingroup\$

Factor, 29 bytes

[ 1 -rot <date> day-of-year ]

Try it online!

  • 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-year Factor has a builtin for this once you have a timestamp.
answered Jun 29, 2021 at 21:58
\$\endgroup\$
3
\$\begingroup\$

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

Attempt This Online!

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
answered Jun 30, 2021 at 0:11
\$\endgroup\$
2
\$\begingroup\$

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

answered Jun 29, 2021 at 17:53
\$\endgroup\$
2
\$\begingroup\$

Red, 36 bytes

func[m d][pick to now reduce[d m]11]

Try it online!

answered Jun 29, 2021 at 18:35
\$\endgroup\$
2
\$\begingroup\$

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.

answered Jun 29, 2021 at 20:46
\$\endgroup\$
2
\$\begingroup\$

Jelly, (削除) 16 (削除ここまで) 15 bytes

"LɓịNH’D+288;ḣS

Try it online!

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
answered Jun 29, 2021 at 17:51
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Do you need the last 3? \$\endgroup\$ Commented Jun 29, 2021 at 18:46
  • \$\begingroup\$ @Neil No, but that's still 16 bytes :/ \$\endgroup\$ Commented Jun 29, 2021 at 19:04
2
\$\begingroup\$

Vyxal, 17 bytes

»∇ė{»4τ28+¦0p?‹i+

Try it Online! Works now, and -2.

answered Jun 29, 2021 at 20:47
\$\endgroup\$
1
  • 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\$ Commented Jun 29, 2021 at 21:25
2
\$\begingroup\$

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!

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)
answered Jun 29, 2021 at 21:28
\$\endgroup\$
2
\$\begingroup\$

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

Try it online!

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.

answered Jun 29, 2021 at 18:15
\$\endgroup\$
7
  • \$\begingroup\$ you can omit get- and you can to use param($m,$d) instead function 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\$ Commented Jun 30, 2021 at 5:55
  • \$\begingroup\$ @mazzy - Date doesn't work on a default installation of PowerShell 5 on Windows 10. TIO uses PowerShell 6 with Linux as the substrate. \$\endgroup\$ Commented 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\$ Commented 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\$ Commented Jun 30, 2021 at 14:29
  • 1
    \$\begingroup\$ FWIW, I never assume that any particular alias exists when I write PowerShell code. \$\endgroup\$ Commented Jun 30, 2021 at 14:36
2
\$\begingroup\$

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

Try it online!

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

Try it online!

answered Jun 30, 2021 at 12:12
\$\endgroup\$
2
\$\begingroup\$

K (ngn/k), (削除) 25 (削除ここまで) 20 bytes

Solution:

{+/y,x#28+43390446円}

Try it online!

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円}
answered Jul 2, 2021 at 10:35
\$\endgroup\$
2
\$\begingroup\$

Mathematica, 30 bytes

{1}~DateDifference~{1,#,#2+1}&

Try it here!

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.

answered Jul 2, 2021 at 18:37
\$\endgroup\$
1
\$\begingroup\$

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

answered Jun 29, 2021 at 18:50
\$\endgroup\$
1
\$\begingroup\$

Perl 5 (-p), 36 bytes

/ /;$_=strftime"%-j",(0)x3,$',$`-1,0

Try it online!

answered Jun 29, 2021 at 19:35
\$\endgroup\$
1
\$\begingroup\$

MATL, 9 bytes

14Liq:)hs

Try it online!

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
answered Jun 29, 2021 at 18:05
\$\endgroup\$
1
\$\begingroup\$

R, 40 bytes

function(m,d)format(ISOdate(1,m,d),"%j")

Try it online!

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

Try it online!

answered Jun 30, 2021 at 7:38
\$\endgroup\$
1
\$\begingroup\$

PHP, 42 bytes

fn($m,$d)=>date(z,mktime(0,0,0,$m,$d,1))+1

Try it online!

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

Try it online!

answered Jun 30, 2021 at 7:43
\$\endgroup\$
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\$ Commented Jun 30, 2021 at 12:51
1
\$\begingroup\$

Python 3, 41 bytes

lambda m,d:31*~-m-(539785049600>>3*m&7)+d

Try it online!

Python 3, 41 chars, 50 bytes

lambda m,d:d+ord('0\x00>v ́ðĮŪƨǦȢɠʜ'[m])/2

Try it online!

answered Jun 30, 2021 at 13:24
\$\endgroup\$
1
\$\begingroup\$

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.

answered Jun 30, 2021 at 12:43
\$\endgroup\$
1
\$\begingroup\$

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

answered Nov 18, 2022 at 2:43
\$\endgroup\$
1
2

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.