18
\$\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.

\$\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\$
    – Adám
    Commented Jun 29, 2021 at 18:15

32 Answers 32

16
\$\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).

\$\endgroup\$
7
  • \$\begingroup\$ Looks like this still works: Try it online Though I wonder if some rational approximation with div would be shorter. \$\endgroup\$
    – xnor
    Commented Jun 29, 2021 at 22:24
  • \$\begingroup\$ @xnor Nice idea! I found one that seems to work. \$\endgroup\$
    – lynn
    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\$
    – lynn
    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\$
    – LSpice
    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.)

\$\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
\$\endgroup\$
7
\$\begingroup\$

JavaScript, 33 bytes

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

Try it online!

\$\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!

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Nice! A 3 byte golf puts you in the lead! \$\endgroup\$
    – emanresu A
    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.

\$\endgroup\$
5
\$\begingroup\$

Bash, 16

date -d$1/1 +%-j

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

Try it online!

\$\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)

\$\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\$
    – Crissov
    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
\$\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\$
    – mic_e
    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\$
    – Hunaphu
    Commented Jun 30, 2021 at 20:38
  • 1
    \$\begingroup\$ @Hunaphu I don't know, i completely missed that! Thanks! \$\endgroup\$
    – SevC_10
    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\$
    – SevC_10
    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ÐUi¹z864e5

Try it

\$\endgroup\$
4
  • \$\begingroup\$ +1 for typing all that on the phone, and for making me laugh! \$\endgroup\$
    – Luis Mendo
    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\$
    – Shaggy
    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\$
    – Luis Mendo
    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\$
    – Shaggy
    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.
\$\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

\$\endgroup\$
2
\$\begingroup\$

Red, 36 bytes

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

Try it online!

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

\$\endgroup\$
2
\$\begingroup\$

Jelly, 16 15 bytes

“LɓịNH’D+28⁸;ḣS

Try it online!

Takes \$d\$ then \$m\$ on the command line

“LɓịNH’D+28⁸;ḣ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]
           ⁸;   - Prepend d; [d, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
             ḣ  - Take the first m
              S - Sum
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Do you need the last 3? \$\endgroup\$
    – Neil
    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\$

Pip, 24 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 1f22 403c 4461                      ..."@<Da

If you put that into xxd -r, save the results in a file, and then run the file as Pip code with the two inputs as command-line arguments, you can try it here! Or, here's a 25-byte version in Pip Classic: Try it online!

Explanation

                          a (month) and b (day) are command-line arguments
      ""      String containing characters with codes 31, 28, 31, 30, etc.
    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
\$\endgroup\$
2
\$\begingroup\$

Vyxal, 17 bytes

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

Try it Online! Works now, and -2.

\$\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\$
    – Aiden Chow
    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)
\$\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.

\$\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\$
    – mazzy
    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\$
    – mazzy
    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!

\$\endgroup\$
2
\$\begingroup\$

K (ngn/k), 25 20 bytes

Solution:

{+/y,x#28+4\3390446}

Try it online!

Explanation:

Assumes months are 0-indexed!

Naive approach, there are likely better ones out there.

{+/y,x#28+4\3390446} / the solution
{                  } / lambda taking implicit x, y args
          4\3390446  / 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+4\3390446}
\$\endgroup\$
1
\$\begingroup\$

Charcoal, 20 bytes

I⁺↨E…”)“M⟧₂”⊖N⁻³¹ι¹N

Try it online! Link is to verbose version of code. Explanation:

     ”)“M⟧₂”            Compressed string `03010100101`
    …                    Truncated to length
             N          Month as an integer
            ⊖           Decremented
   E                     Map over characters
                ³¹       Literal integer `31`
               ⁻         Subtract
                  ι      Current value
  ↨                ¹     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).

\$\endgroup\$
1
\$\begingroup\$

Perl 5 (-p), 36 bytes

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

Try it online!

\$\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
\$\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!

\$\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!

\$\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\$
    – Kaddath
    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!

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

\$\endgroup\$
1
\$\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.

\$\endgroup\$
0
\$\begingroup\$

Java, 141 bytes

int d(int d,int m){for(int i=1;i<m;i++){switch(i){case(2):d+=28;break;case(4):case(6):case(9):case(11):d+=30;break;default:d+=31;}}return d;}
\$\endgroup\$
6
  • 3
    \$\begingroup\$ We don't allow submissions in the form of code snippets - that is, input/output cannot be taken or provided in the form of predefined variables. For Java, you can either submit a full program, or a more common format is to submit a function (and Function<T, U> objects in the form of lambdas are considered acceptable). \$\endgroup\$
    – hyperneutrino
    Commented Jun 29, 2021 at 17:48
  • \$\begingroup\$ thanks, edited so now its a method. \$\endgroup\$ Commented Jun 29, 2021 at 17:54
  • 6
    \$\begingroup\$ While answering your own challenge is perfectly acceptable, I recommend waiting a week before doing so, in order that other using your language get a chance. This is especially so when your chosen programming language is one of widespread use like Java. Remember that while you've had time to think about approaches to the problem when writing the specification, others have not had this luxury. \$\endgroup\$
    – Adám
    Commented Jun 29, 2021 at 18:20
  • 5
    \$\begingroup\$ m->d->java.time.LocalDate.of(1,m,d).getDayOfYear() should save you a lot of bytes \$\endgroup\$ Commented Jun 29, 2021 at 21:15
  • 1
    \$\begingroup\$ @karottenbunker but then, that's only codegolf to an extend. To totally codegolf, builtins must be considered and used if good. \$\endgroup\$ Commented Jun 30, 2021 at 7:05

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.