A date can be represented by an unsigned integer as such: YYYYMMDD. What you need to do, is write the shortest program or function that figures out the most recent date whose number was divisible by a given number n (including today's date) and then returns that date in the format showed above. If there has never been a date (between 00000101 and today inclusive) divisible by the given integer, you should return -1.


Current Date     Input     Output

30 July, 2014      4       20140728
30 July, 2014      7       20140729
28 July, 2014      4       20140728
28 July, 2014      7       20140722
28 July,    5    90000     -1


You can read from STDIN or take a function argument or even expect the input to be stored in a variable. The input will be an unsigned integer.


Write to STDOUT or return (or save in a variable) the integer representing the date in the format YYYYMMDD.


You may use any standard library your language offers. Standard loopholes apply.

Winning conditions

This is a , so smallest program (in bytes) wins. In case of a tie, the answer with the most votes wins.

  • 4
    \$\begingroup\$ Date 00000101 does not exist. Year count starts by 1. en.wikipedia.org/wiki/0_%28year%29 \$\endgroup\$ – edc65 Jul 30 '14 at 14:35
  • 1
    \$\begingroup\$ @edc65 can we pretend it does exist? \$\endgroup\$ – overactor Jul 30 '14 at 14:37
  • 3
    \$\begingroup\$ What about Feb 29th? Do we need to apply full leap year rules to check for valid dates? en.wikipedia.org/wiki/Leap_year \$\endgroup\$ – Digital Trauma Jul 30 '14 at 14:52
  • 6
    \$\begingroup\$ What about the days lost due to the Julian-Gregorian calendar switch? Or are we going Gregorian all the way? en.wikipedia.org/wiki/Gregorian_calendar \$\endgroup\$ – Digital Trauma Jul 30 '14 at 14:56
  • 1
    \$\begingroup\$ Your input/output specs are rather loose. For example, should the "expect the input to be stored in a variable" count the variable declaration in a language like C? You say "write a program", yet you say "take a function argument" - does that mean we can write just a function rather than a full program? \$\endgroup\$ – Bob Jul 30 '14 at 16:43

21 Answers 21


Mathematica, 93 60 bytes


Expects the input to be stored in n.

Note that the vertical line is the unicode character for "divides", which I've counted as 3 bytes (UTF-8).

Edit: Found a neat trick to avoid the bloated DateString and format specification :).

Edit: Totally forgot about the -1 requirement. Fixed now.

Here is an explanation

For[i=0,            i--                        ,];         (* i is the number of days AFTER
                                                              today. Hence, we decrement 
                                                              it. *)
For[i=0,   DatePlus@i--                        ,];         (* If no reference date is
                                                              provided, DatePlus will add
                                                              the given number of days to
                                                              today's date. The result is a 
                                                              list of 3 integers, luckily 
                                                              in order {year,month,day} *)
For[i=0,   DatePlus@i--~FromDigits~100         ,];         (* Interpret these as the digits
                                                              of a base 100 number. The 
                                                              beauty is that FromDigits
                                                              doesn't care about digits 
                                                              greater than the base and 
                                                              just carries them over. *)
For[i=0,(r=DatePlus@i--~FromDigits~100)        ,];         (* Store the number in r. *)
For[i=0,(r=DatePlus@i--~FromDigits~100)>0      ,];         (* Make sure it's positive. *)
For[i=0,(r=DatePlus@i--~FromDigits~100)>0&&!n|r,];         (* And keep going while n does 
                                                              not divide r. *)
For[i=0,(r=DatePlus@i--~FromDigits~100)>0&&!n|r,];r~Max~-1 (* Clamp result to -1. *)

Note that I've used | instead of in the explanation, because the Unicode one messes with monospacing.

  • \$\begingroup\$ +1.Do you have a link pointing out that you should count unicode chars as 3 bytes? \$\endgroup\$ – Dr. belisarius Jul 30 '14 at 18:21
  • 2
    \$\begingroup\$ @belisarius The OP stated that this code golf is counted by bytes and not characters (this is also the default as stated in the tag wiki). \$\endgroup\$ – Martin Ender Jul 30 '14 at 18:24
  • \$\begingroup\$ I never got to read thru the end of the wiki :) Thanks! \$\endgroup\$ – Dr. belisarius Jul 30 '14 at 18:29

Python 2 - 150

import datetime as d,re
def f(n):
 while t:
    if c%n<1:return c

Thanks @chill0r for suggestion to remove days=, and Jason S for tip that the try block can be reduced to one line.

  • \$\begingroup\$ Yes. That is a standard operating procedure ;). The tabs get converted to spaces after pasting. \$\endgroup\$ – Vectorized Jul 30 '14 at 15:06
  • \$\begingroup\$ You can remove the days= in t-=d.timedelta(days=1). This works fine too (at least in python3) \$\endgroup\$ – chill0r Jul 30 '14 at 15:20
  • \$\begingroup\$ @bitpwner ah I see, never mind then. \$\endgroup\$ – Martin Ender Jul 30 '14 at 15:27
  • 1
    \$\begingroup\$ You can save more: (1) use int(t.strftime("%Y%m%d")) and drop re, (2) use a one-line try because only t-=d.timedelta(1) needs to be in it. \$\endgroup\$ – Jason S Jul 31 '14 at 4:33
  • 1
    \$\begingroup\$ @bitpwner strftime on older dates works in python3, checked and I do get an error in python2 \$\endgroup\$ – Jason S Jul 31 '14 at 8:17

C# 136

With the revised specs, a function that takes an unsigned int and returns an int.

int F(uint n){var d=System.DateTime.Now;int i;try{while((i=int.Parse(d.ToString("yyyMMdd")))%n>0)d=d.AddDays(-1);}catch{i=-1;}return i;}

152 characters with variable input/output

Taking advantage of the loose input/output requirements, input is to be stored in the variable n (currently counting all characters except the integer literal), and output is provided with the variable s.

class P{static void Main(){var n=4;var d=System.DateTime.Now;string s;try{while(int.Parse(s=d.ToString("yyyMMdd"))%n>0)d=d.AddDays(-1);}catch{s="-1";}}}

204 characters with STDIN/STDOUT:

using System;class P{static void Main(){int n=int.Parse(Console.ReadLine());var d=DateTime.Now;string s;try{while(int.Parse(s=d.ToString("yyyMMdd"))%n>0)d=d.AddDays(-1);}catch{s="-1";}Console.Write(s);}}
  • 1
    \$\begingroup\$ Really, a downvote? Does this not solve the problem correctly? Please explain. If anyone thinks I duplicated the other C# answer, I actually wrote this about an hour before the other one, and even looked into using C# 6.0 for the declaration expressions. Got a bit sidetracked, which resulted in posting the answer late. Even then, that's a rather flimsy reason for a downvote. \$\endgroup\$ – Bob Jul 30 '14 at 17:25

T-SQL (2012) - 148

Assumes there is a free variable @n with the n value.

declare @ date=getdate()while convert(char,@,112)%@n>0 and'00010101'<@ set @=dateadd(d,-1,@)print iif(convert(char,@,112)%@n=0,convert(char,@),'-1')

Golflua 90 86


An ungolfed Lua version would be,

n = io.read()
d = "%Y%m%d"
i = os.date(d)+0   -- implicitly casts os.date(d) to int
j = 0
while i>0 do
   if i % n == 0 then
   j = j+1
   i = os.date(d,os.time()-j*86400)+0
  • 2
    \$\begingroup\$ Tested here n = 20140699 outputs 20140699 \$\endgroup\$ – William Barbosa Jul 30 '14 at 14:50
  • \$\begingroup\$ @WilliamBarbosa: Fixed; 20140699 returns -1. \$\endgroup\$ – Kyle Kanos Jul 30 '14 at 17:36



Assumes the divisor is stored in n. The result will be stored in a variable called ans.

Commented version:

-1                                     % Store -1 in ans in case we don't find anything
s=str2num(datestr(1:now,'YYYYmmDD'))   % Make a list of date numbers
d=s(~mod(s,n)),                        % Select only those who are dividable and prepend -1
d(end)                                 % Store last found value in ans, if anything is found

Will generate an error if no result is found, but the answer is still available in the variable despite that.

Error could be avoided at the cost of 2 extra chars:

  • \$\begingroup\$ @MartinBüttner Hmm, solved that problem but now the solution is only tied for minimum chars. Can you see any improvements? \$\endgroup\$ – Dennis Jaheruddin Jul 31 '14 at 11:54
  • 1
    \$\begingroup\$ No, not off the top of my head. But my motivation to help you beat me is a bit limited. ;) \$\endgroup\$ – Martin Ender Jul 31 '14 at 12:11

PHP (92=85+7)

Expects input to be stored in $n.


I just remembered why I do not like PHP anymore=)

EDIT: Now the -1 of the specifications is implemented too.

  • \$\begingroup\$ No, just checked it, $d will be one too low when echo-ing. What do you mean by 'you've forge'? (Sorry, no english native=) \$\endgroup\$ – flawr Jul 30 '14 at 16:05
  • \$\begingroup\$ Oh, I didn't see that spec, of course this has to be added, thanks! \$\endgroup\$ – flawr Jul 31 '14 at 12:31

JavaScript (ES6) 115

Expects number in variable n, result stored in variable r. Each day is checked, starting with current date and decrementing - there must be a better way.
Moreover, using standard javascript date functions, all dates are gregorian down to year 1 (with leap years accordingly wrong before gregorian reform).

for(z=new Date,t=n+1;t>n&&t%n;)

C# - 144 (Or 124 in LINQPad) + 1 for each digit in n

This expects the input to be in the variable n. By the end of the execution the desired value will be in the variable r. This considers 00010101 as the first date, though, because the date 00000101 does not exist. Suggestions for improvement are always welcome.

class P{static void Main(){int n=7,r;var d=System.DateTime.Now;try{for(;(r=int.Parse(d.ToString("yyyMMdd")))%n>0;d=d.AddDays(-1));}catch{r=-1;}}}

LINQPad version:

int n=7,r;var d=System.DateTime.Now;try{for(;(r=int.Parse(d.ToString("yyyMMdd")))%n>0;d=d.AddDays(-1));}catch{r=-1;}r.Dump();

Groovy - 301 300 chars

Very simple (and slow), with no tricks to hide the fact that it uses Joda Time.


@Grab(group='joda-time', module='joda-time', version='2.3')
import org.joda.time.*
import org.joda.time.format.*
f={DateTimeFormat.forPattern("yyyyMMdd").print(new LocalDate().minusDays(it)) as int}
n=args[0] as int;b=0;x=-1;c=0
println x

Example run (on 7/30/2014):

$ groovy D.groovy  7
$ groovy D.groovy  16
$ groovy D.groovy  90000


@Grab(group='joda-time', module='joda-time', version='2.3')

import org.joda.time.*
import org.joda.time.format.*

f = { DateTimeFormat.forPattern("yyyyMMdd").print(new LocalDate().minusDays(it)) as int }

n = args[0] as int
b = 0 
x = -1
c = 0

while (!b) {
    if(f(c++)%n==0) { x=f(--c); b=1}

println x

R, 146 139


Good luck with a date that doesn't work. microbenchmark reports it takes about half a second to go back 15 days. As of July 31, 2014, this will take something like 20 million seconds (~23 days) to spit out -1, at least according to the back of the envelope.

edit: some shortcuts in the comments

  • \$\begingroup\$ !d is shorter than d==F and !z%%n than z%%n==0. Also, making as.numeric(gsub("-","",...) into a function should reduce the character count as well. Still, nice job! \$\endgroup\$ – plannapus Jul 31 '14 at 11:26
  • \$\begingroup\$ Oh and as.real is often a good, shorter alternative to as.numeric. \$\endgroup\$ – plannapus Jul 31 '14 at 11:32
  • \$\begingroup\$ Unfortunately as.real is defunct as of R 3.0.0. But we still have as.double which is one character shorter. \$\endgroup\$ – shadowtalker Jul 31 '14 at 12:25
  • \$\begingroup\$ Oh I didn't know that as I'm still using R 2.14 \$\endgroup\$ – plannapus Jul 31 '14 at 12:26
  • 1
    \$\begingroup\$ I'm not working on a computer i have administration rights on, so it's not really up to me. But I already have paste0 in my .Rprofile naturally :) \$\endgroup\$ – plannapus Jul 31 '14 at 12:33

Matlab 104

function d=f(v);for d=fix(now):-1:1 d=str2num(datestr(d,'YYYYmmDD'));if~mod(d,v)return;end;end;d=-1;end

Ungolfed :

function d = f(v)
   for d=fix(now):-1:1
       d = str2num(datestr(d,'YYYYmmDD'));
       if ~mod(d,v)
   d = -1;

EDIT: I managed to optimise it a bit, but @DennisJaheruddin has the real solution here

  • \$\begingroup\$ This can still be golfed quite a bit, I will update it. \$\endgroup\$ – Dennis Jaheruddin Jul 31 '14 at 10:28
  • \$\begingroup\$ @DennisJaheruddin I have rejected your edit based on this meta post. Please suggest your improvements in a comment, so the OP can review them before modifying his answer. \$\endgroup\$ – Martin Ender Jul 31 '14 at 10:40
  • \$\begingroup\$ Note that you can save chars in various ways: Use a script rather than a function, let things get assigned to ans, do the loop from low to high and let each result overwrite the previous one so you don't need to break the loop. -- Of course vectorization can also help, see my answer. \$\endgroup\$ – Dennis Jaheruddin Jul 31 '14 at 12:11
  • \$\begingroup\$ Here is a shorter loop based version of 67 chars: -1,for s=str2num(datestr(1:now,'YYYYmmDD'))',if~mod(s,n),+s,end,end \$\endgroup\$ – Dennis Jaheruddin Jul 31 '14 at 12:47
  • \$\begingroup\$ @MartinBüttner Thanks for the comment. There was an error as you said. Now it should be okay. \$\endgroup\$ – Scott Jul 31 '14 at 12:53

Python 3 - 151 148 bytes, generators

from datetime import*
f=lambda n:next((y for y in(int((t-timedelta(o)).strftime("%Y%m%d"))for o in range(t.toordinal()))if y%n<1),-1)

Thanks @nyuszika7h for import* suggestion


Ruby 103

return s if s%n<1
d-=1)while d.year>0


Expects the divisor value to be present in variable n.


The return value of the f function

Online example: http://ideone.com/LoYxG4


Java : 373 chars

This is a port of the Groovy answer, and uses Joda Time.


import org.joda.time.*;
import org.joda.time.format.*;
public class D {
static int f(int i){return Integer.parseInt(DateTimeFormat.forPattern("yyyyMMdd").print(new LocalDate().minusDays(i)));}
public static void main(String[] args){
int n=Integer.parseInt(args[0]);int b=0,c=0,x=-1;

Sample runs (with joda-time-2.4.jar on classpath:

$ java D 7
$ java D 4
$ java D 16
$ java D 90000


import org.joda.time.*;
import org.joda.time.format.*;

public class D {
    static int f(int i) {
        return Integer.parseInt(DateTimeFormat.forPattern("yyyyMMdd").print(new LocalDate().minusDays(i)));

    public static void main(String[] args) {
        int n = Integer.parseInt(args[0]);
        int b = 0,c = 0,x = -1;

        while(b!=1) {
            if(f(c++)%n==0) { x=f(--c);b=1; }
            if(f(0)-c<=101) { b=1; }

  • 3
    \$\begingroup\$ There's also java.time.* in the latest version of Java. \$\endgroup\$ – ntoskrnl Jul 31 '14 at 10:26

Bash+coreutils (8.21), 67 bytes

seq -f-%gday $[9**9]|date -f- +[pq]sp[_1pq]sq%Y%m%ddA1=qd$1%%0=p|dc
  • seq generates integers from 1 to 99, one per line, and formats it as -<x>day
  • pipe this to date -f which interprets each line and outputs the date formatted into a dc expression such as [pq] sp [_1pq] sq 20140728 d A1 =q d 7% 0=p (spaces added for readability)
    • [pq] define a macro to print the top of stack, then quit
    • sp save macro in register p
    • [pq] define a macro to push -1, print the top of stack, then quit
    • sq save macro in register q
    • 20140728 embedded date integer
    • d duplicate top of stack
    • A1 push 101 (00000101)
    • =q pop top 2 stack values: compare date and 101, and call macro q if equal
    • 7 push divider
    • % pop divider and dividee, the divide and push the remainder
    • 0 push 0
    • =p pop top 2 stack values: compare remainder and 0, and call macro p if equal
    • d duplicate top of stack
    • macro p is called: prints date integer and quits dc entirely
  • dc expressions are piped to dc for evaluation. Once dc prints the right value and quits, the rest of the pipeline is torn down


$ ./lastdivdate.sh 4
$ ./lastdivdate.sh 7
$ ./lastdivdate.sh 123456
$ ./lastdivdate.sh 77777
$ ./lastdivdate.sh 7777777

Since this program generates integers from 1 to 99, it will be valid up to just over 1 million years into the future. I hope this limitation is acceptable ;-)

Thanks @WumpusQ.Wumbley for shortening the return of -1.

  • \$\begingroup\$ @MartinBüttner Curses! Now it does, with a 19 byte penalty :) \$\endgroup\$ – Digital Trauma Jul 31 '14 at 0:51
  • \$\begingroup\$ Shorter ways to convert empty output to -1: add |grep .||echo -1 to the end of the pipeline, or use zsh where you can nest expansions like echo ${$(cmd):-1} (this will cost you a backslash elsewhere...) \$\endgroup\$ – user15244 Jul 31 '14 at 13:01
  • \$\begingroup\$ @WumpusQ.Wumbley Why didn't I think of that? Thanks! \$\endgroup\$ – Digital Trauma Jul 31 '14 at 16:52
  • 1
    \$\begingroup\$ By the way, this seems to be sensitive to the coreutils version. Mine (8.15) refuses to go back before 1901 with the "days ago" specification. \$\endgroup\$ – user15244 Jul 31 '14 at 17:02
  • 1
    \$\begingroup\$ Actually it seems to be a sizeof time_t issue, since the boundary where it breaks is 2**31 seconds before 1/1/1970. My older installation is also pathetically 32-bit \$\endgroup\$ – user15244 Jul 31 '14 at 17:25

PYTHON: 134 bytes

Not going to be able to beat the current leader, and it's not that much better than the best Python answer, but I decided to post my best Python solution.

from datetime import*
def y(a,n):
 if int(s)%n==0:yield s
 except:yield -1
 yield x


from datetime import *
def y(a, n):
    if s%n==0:
        yield s
        x=y(a-timedelta(1), n)
        yield -1
    yield x
  • \$\begingroup\$ It's actually 138 bytes. You can save 4 bytes by using from datetime import* instead of import datetime as d, timedelta(1) instead of d.timedelta(1) and yield instead of return. \$\endgroup\$ – nyuszika7h Aug 1 '14 at 13:31
  • \$\begingroup\$ I'm using a random online byte counter, is there a better option? \$\endgroup\$ – RageCage Aug 1 '14 at 13:34
  • \$\begingroup\$ mothereff.in/byte-counter \$\endgroup\$ – nyuszika7h Aug 1 '14 at 13:36
  • \$\begingroup\$ What makes that one different from this one? bytecount.bluebus112.com \$\endgroup\$ – RageCage Aug 1 '14 at 13:40
  • \$\begingroup\$ That one doesn't count newlines, plus it counts characters, not bytes. For ASCII text, the two are the same, so the latter doesn't make a difference here. In code-golf, you usually count characters unless the OP says otherwise. (Also, the one I linked was the first result in Google for "byte count" here.) \$\endgroup\$ – nyuszika7h Aug 1 '14 at 13:41

JavaScript (ES5) - 94

It expects the input in variable x, and places the output in o.

for(i=Date.now();i>-7e13&&(o=(new Date(i)).toISOString().replace(/-|T.*/g,''))%x;i-=864e5)o=-1

k4 (84) (73)

f:{f d@*|&~.q.mod[(f:{$[^x;-1;.($x)@&~"."=$x]})'d:{"d"$x+!1+"i"$y-x}[-730457;.z.D];x]}

This is just an initial cut with the first algorithm that came to mind; I'm sure better is possible in both performance and length.

This version hardcodes the "today" part (that's the .z.D); change it to a date literal (yyyy.mm.dd) or an integer in the q date system (days since January 1, 2000) to run the test cases. (q won't parse date literals earlier than the early eighteenth century, so for dates before that, you'll need to work out the value and use the appropriate integer directly. January 1, "A.D. 0", from the spec, turns out to be -730457, which is used in the function code. July 28, A.D. 5, from the last test case, turns out to be -728450.)

The given test cases:

  {f d@*|&~.q.mod[(f:{$[^x;-1;.($x)@&~"."=$x]})'d:{"d"$x+!1+"i"$y-x}[-730457;2014.07.30];x]}4
  {f d@*|&~.q.mod[(f:{$[^x;-1;.($x)@&~"."=$x]})'d:{"d"$x+!1+"i"$y-x}[-730457;2014.07.30];x]}7
  {f d@*|&~.q.mod[(f:{$[^x;-1;.($x)@&~"."=$x]})'d:{"d"$x+!1+"i"$y-x}[-730457;2014.07.28];x]}4
  {f d@*|&~.q.mod[(f:{$[^x;-1;.($x)@&~"."=$x]})'d:{"d"$x+!1+"i"$y-x}[-730457;2014.07.28];x]}7
  {f d@*|&~.q.mod[(f:{$[^x;-1;.($x)@&~"."=$x]})'d:{"d"$x+!1+"i"$y-x}[-730457;-728450];x]}90000


g:.,/$`\:`$$:;f:{$[Z=r:{(z>x)&.q.mod[g z]y}[Z:-730458;y]{x-1}/x;-1;g"d"$r]}

This is a different approach which uses one of the convergence operators to decrement the date until either it finds a divisible one or it crosses the 1/1/0000 boundary. It also does the conversion from date to integer slightly differently.

The test cases, this time all at once:

  g:.,/$`\:`$$:;{$[Z=r:{(z>x)&.q.mod[g z]y}[Z:-730458;y]{x-1}/x;-1;g"d"$r]}'[2014.07.30 2014.07.30 2014.07.28 2014.07.28,"d"$-728450;4 7 4 7 90000]
20140728 20140729 20140728 20140722 -1

VBA 343 bytes (module)

Sub divD(i As Long)
a = Now()
b = Format(a, "yyyymmdd")
    Do While b / i <> Int(b / i)
    a = DateAdd("d", -1, a)
    b = Format(a, "yyyymmdd")
        If b = "01000101" Then
            MsgBox -1
            Exit Sub
        End If
MsgBox b
End Sub
  • \$\begingroup\$ This can be heavily condensed down to Sub d(i):a=Now:b=a:Do Until b/i=Int(b/i):a=DateAdd("d",-1,a):b=Format(a,"yyyymmdd"):If b="01000101"Then:b=-1:Exit Sub:Loop:Debug.?b:End Sub for 139 Bytes \$\endgroup\$ – Taylor Scott Jun 5 '17 at 18:21

PowerShell - 76

This depends on the number being stored in the variable $n.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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