16
\$\begingroup\$

NOTE: Since I'm Dutch myself, all dates are in the Dutch dd-MM-yyyy format in the challenge description and test cases.

Challenge:

Inputs:
Start date \$s\$; End date \$e\$; Digit \$n\$

Outputs:
All dates within the range \$[s,e]\$ (including on both sides), which contain \$n\$ amount of unique digits in their date.

Example:

Inputs: Start date: 12-11-1991; End date: 02-02-1992; Digit: 4

Outputs:
With leading 0s for days/months:

[20-11-1991, 23-11-1991, 24-11-1991, 25-11-1991, 26-11-1991, 27-11-1991, 28-11-1991, 30-11-1991, 01-12-1991, 02-12-1991, 09-12-1991, 10-12-1991, 13-12-1991, 14-12-1991, 15-12-1991, 16-12-1991, 17-12-1991, 18-12-1991, 20-12-1991, 23-12-1991, 24-12-1991, 25-12-1991, 26-12-1991, 27-12-1991, 28-12-1991, 31-12-1991, 01-01-1992, 02-01-1992, 09-01-1992, 10-01-1992, 11-01-1992, 12-01-1992, 19-01-1992, 20-01-1992, 21-01-1992, 22-01-1992, 29-01-1992, 01-02-1992, 02-02-1992]

Without leading 0s for days/months:

[20-11-1991, 23-11-1991, 24-11-1991, 25-11-1991, 26-11-1991, 27-11-1991, 28-11-1991, 30-11-1991, 3-12-1991, 4-12-1991, 5-12-1991, 6-12-1991, 7-12-1991, 8-12-1991, 10-12-1991, 13-12-1991, 14-12-1991, 15-12-1991, 16-12-1991, 17-12-1991, 18-12-1991, 20-12-1991, 23-12-1991, 24-12-1991, 25-12-1991, 26-12-1991, 27-12-1991, 28-12-1991, 31-12-1991, 3-1-1992, 4-1-1992, 5-1-1992, 6-1-1992, 7-1-1992, 8-1-1992, 10-1-1992, 13-1-1992, 14-1-1992, 15-1-1992, 16-1-1992, 17-1-1992, 18-1-1992, 20-1-1992, 23-1-1992, 24-1-1992, 25-1-1992, 26-1-1992, 27-1-1992, 28-1-1992, 31-1-1992]

Challenge rules:

  • The input and output dates may be in any reasonable (date-)format. Can be as a string in any dMy format (including optional separators), list of three integers, your language's native Date-object, etc. Output may be a list/array/stream, printed to STDOUT, a single delimited String, etc.
  • You are allowed to include or exclude leading 0s for days/months in your outputs. Please specify which of the two you use in your answer, since it will cause different results. I.e. 1-1-1991 has 2 unique digits, but 01-01-1991 as 3 unique digits.
  • You don't have to deal with leap years and differences of Gregorian vs Julian calendars. You can assume the date-ranges given in the test cases will never go over February 28th/March 1st for years divisible by 4.
  • The input-digit \$n\$ is guaranteed to be in the range \$[1,8]\$, so dealing with \$n=0\$ is unspecified (returning an empty list would be most reasonable, but giving an error or incorrect result is fine as well; you won't have to deal with that input).

General rules:

  • This is , so shortest answer in bytes wins.
    Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
  • Standard rules apply for your answer with default I/O rules, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
  • Default Loopholes are forbidden.
  • If possible, please add a link with a test for your code (i.e. TIO).
  • Also, adding an explanation for your answer is highly recommended.

Test cases:

Inputs: [12-11-1991, 02-02-1992], 4
Outputs with leading 0s:    [20-11-1991, 23-11-1991, 24-11-1991, 25-11-1991, 26-11-1991, 27-11-1991, 28-11-1991, 30-11-1991, 01-12-1991, 02-12-1991, 09-12-1991, 10-12-1991, 13-12-1991, 14-12-1991, 15-12-1991, 16-12-1991, 17-12-1991, 18-12-1991, 20-12-1991, 23-12-1991, 24-12-1991, 25-12-1991, 26-12-1991, 27-12-1991, 28-12-1991, 31-12-1991, 01-01-1992, 02-01-1992, 09-01-1992, 10-01-1992, 11-01-1992, 12-01-1992, 19-01-1992, 20-01-1992, 21-01-1992, 22-01-1992, 29-01-1992, 01-02-1992, 02-02-1992]
Outputs without leading 0s: [20-11-1991, 23-11-1991, 24-11-1991, 25-11-1991, 26-11-1991, 27-11-1991, 28-11-1991, 30-11-1991, 3-12-1991, 4-12-1991, 5-12-1991, 6-12-1991, 7-12-1991, 8-12-1991, 10-12-1991, 13-12-1991, 14-12-1991, 15-12-1991, 16-12-1991, 17-12-1991, 18-12-1991, 20-12-1991, 23-12-1991, 24-12-1991, 25-12-1991, 26-12-1991, 27-12-1991, 28-12-1991, 31-12-1991, 3-1-1992, 4-1-1992, 5-1-1992, 6-1-1992, 7-1-1992, 8-1-1992, 10-1-1992, 13-1-1992, 14-1-1992, 15-1-1992, 16-1-1992, 17-1-1992, 18-1-1992, 20-1-1992, 23-1-1992, 24-1-1992, 25-1-1992, 26-1-1992, 27-1-1992, 28-1-1992, 31-1-1992]

Inputs: [19-09-2019, 30-09-2019], 5
Outputs (same with and without leading 0s): [23-09-2019, 24-09-2019, 25-09-2019, 26-09-2019, 27-09-2019, 28-09-2019, 30-09-2019]

Inputs: [19-09-2019, 30-09-2019], 8
Output (same with and without leading 0s): []

Inputs: [20-06-1749, 30-06-1749], 8
Outputs with leading 0s:    [23-06-1749, 25-06-1749, 28-06-1749]
Outputs without leading 0s: []

Inputs: [10-12-1969, 12-01-1970], 6
Outputs (same with and without leading 0s): [30-12-1969]

Inputs: [10-12-1969, 12-01-1970], 5
Outputs with leading 0s:    [10-12-1969, 13-12-1969, 14-12-1969, 15-12-1969, 17-12-1969, 18-12-1969, 20-12-1969, 23-12-1969, 24-12-1969, 25-12-1969, 27-12-1969, 28-12-1969, 31-12-1969, 02-01-1970, 03-01-1970, 04-01-1970, 05-01-1970, 06-01-1970, 08-01-1970, 12-01-1970]
Outputs without leading 0s: [10-12-1969, 13-12-1969, 14-12-1969, 15-12-1969, 17-12-1969, 18-12-1969, 20-12-1969, 23-12-1969, 24-12-1969, 25-12-1969, 27-12-1969, 28-12-1969, 31-12-1969, 2-1-1970, 3-1-1970, 4-1-1970, 5-1-1970, 6-1-1970, 8-1-1970, 12-1-1970]

Inputs: [11-11-1111, 11-11-1111], 1
Output (same with and without leading 0s): [11-11-1111]
\$\endgroup\$
1
  • \$\begingroup\$ I know it is specifically not the format demanded here, but I just comment here to "spread the word": there is an internationnal standard that programmers should try to use for dates (in logs, filenames, etc) : en.wikipedia.org/wiki/ISO_8601. (uses a 'T' to desambiguate (without the T the date+time could be something else entirely) and specifies the separators to use, and when one can not use separators [ie proposes different variant (from short to long] of the same standard]: the main one being: YYYY-MM-DDThh:mm:ss.mmm +hh:mm, the +hh:mm being your locale's time offset from UTC .) \$\endgroup\$ Oct 10, 2019 at 9:58

10 Answers 10

5
\$\begingroup\$

R, 81 bytes

function(s,e,n,x=seq(s,e,1))x[lengths(sapply(strsplit(paste(x),""),unique))==n+1]

Try it online!

Uses R’s native date format and has leading zeros on day and month.

\$\endgroup\$
3
\$\begingroup\$

Red, 93 bytes

func[a b n][until[if n = length? exclude d: rejoin[a/4"-"a/3"-"a/2]"-"[print d]b < a: a + 1]]

Try it online!

Without leading 0s for days/months.

Too bad that Red converts internally 09-10-2019 to 9-Oct-2019 - that's why I need to extract the day/month/year individually.

\$\endgroup\$
2
  • \$\begingroup\$ I'm not familiar with Red but it seems like there's a lot of whitespace that could be cut out of this. Pardon me if I'm wrong, though. \$\endgroup\$
    – moltarze
    Oct 10, 2019 at 9:51
  • \$\begingroup\$ @connectyourcharger No problem! Seemingly there are several unnecessary whitespaces, but they are needed to separate the tokens. Words (identifiers) in Red can include -=+*<>?!~&, that's why a whitespace (or (...)[...]"...") are needed. \$\endgroup\$ Oct 10, 2019 at 10:35
2
\$\begingroup\$

Japt, 23 bytes

Takes the date inputs as Unix timestamps, outputs an array of strings with formatting and leading 0s dependent on your locale. Would be 1 byte shorter in Japt v2 but there seems to be a bug when converting Date objects to strings.

òV864e5@ÐX s7Ãf_¬â ʶWÄ

Try it

òV864e5@ÐX s7Ãf_¬â ʶWÄ     :Implicit input of integers U=s,V=e & W=n
òV                          :Range [U,V]
  864e5                     :  With step 86,400,000 (24*60*60*1000)
       @                    :Map each X
        ÐX                  :  Convert to Date object
           s7               :  Convert to locale date string
             Ã              :End map
              f             :Filter
               _            :By passing each through the following function
                ¬           :  Split
                 â          :  Deduplicate
                   Ê        :  Length
                    ¶       :  Is equal to
                     WÄ     :  W+1, to account for the inclusion of the delimiting "/" or "-"
\$\endgroup\$
2
\$\begingroup\$

Python 3.8 (pre-release), 84 bytes

-6 bytes thanks to Gloweye

lambda s,e,n:[d for i in range((e-s).days+1)if-len(set(d:=str(s+type(e-s)(i))))==~n]

An unnamed function which returns a list of strings (counting/including leading zeros) that accepts three arguments:

  • s, the start - a datetime.date object;
  • e, the end - a datetime.date object; and
  • n, the number of days - an int object.

Try it online!

Note: As the function accepts datetime.date objects I have not counted the import code for that (and have worked around importing the datetime.timedelta object as it is indirectly accessible via subtraction of these input objects).

\$\endgroup\$
4
  • 1
    \$\begingroup\$ type(obj) is 3 bytes shorter than obj.__class__. \$\endgroup\$
    – Gloweye
    Oct 10, 2019 at 8:15
  • \$\begingroup\$ @Gloweye awesome thanks! \$\endgroup\$ Oct 10, 2019 at 9:07
  • \$\begingroup\$ @Gloweye saves 6 in the end (the dot goes and the brackets are already present) \$\endgroup\$ Oct 10, 2019 at 9:14
  • 1
    \$\begingroup\$ I hadn't analyzed to that depth yet, just saw the __class__ and made a quick comment. Always glad to help. \$\endgroup\$
    – Gloweye
    Oct 10, 2019 at 9:15
2
\$\begingroup\$

Ruby -rdate, 54 bytes

Takes 2 Date objects and a number as input, and returns a list of Date objects as output. Handles leap years and uses leading zeroes.

->a,b,n{(a..b).select{|d|d.to_s.chars.uniq.size==n+1}}

Try it online!

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

JavaScript (ES6), 91 bytes

Takes input as (n)(end)(start), where the dates are expected as Unix timestamps in milliseconds. Returns a space-separated list of dates in format yyyy-mm-dd.

Leading 0s are included.

n=>b=>g=a=>a>b?'':(new Set(d=new Date(a).toJSON().split`T`[0]).size+~n?'':d+' ')+g(a+864e5)

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ This snippet will probably fail if DST shifted happened (a+864e5 may not be tomorrow in that case). But thankfully, tio use UTC timezone which doesn't have DST. -- from someone who use the same logic in product website and realize something wrong until DST shifted... \$\endgroup\$
    – tsh
    Oct 10, 2019 at 9:37
1
\$\begingroup\$

PHP, 90 bytes

for([,$s,$e,$n]=$argv;$s<=$e;)$n-count(count_chars($d=date(Ymd,86400*$s++),1))||print$d._;

Try it online!

This is with leading 0s. Inputs are command arguments ($argv) and dates are Unix timestamps in days (basically standard seconds / 86400), I used this format as we don't need the time in this challenge and it allowed me to golf 1 more byte. Keeps adding a day to start until it reaches the end and prints any dates with $n unique digits in it, separated by _ in Ymd format.

Also have a 89 bytes alternative which prints dates to output in same format as input (Unix timestamps in days).

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

Java (JDK), 86 bytes

(s,e,n)->s.datesUntil(e.plusDays(1)).filter(d->(""+d).chars().distinct().count()==n+1)

Try it online!

I chose to use leading 0s.

Credits

  • -24 thanks to Kevin Cruijssen who didn't know he could golf away that much :p
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Maybe I shouldn't have made it inclusive on both ends, then you could have used Java 9's datesUntil for 103 bytes. ;) Nice answer. I don't see anything that could be golfed personally. \$\endgroup\$ Oct 10, 2019 at 11:54
  • 1
    \$\begingroup\$ @KevinCruijssen Well, actually, you gave an extremely nice way of golfing! Just add .plusDays(1) and remove the .forEach(System.out::println) and it's a very much golfed answer because as you wrote, dates can be returned as value objects and streams are allowed. ;-) I had no clue that datesUntil even existed! Thank you for that :-) \$\endgroup\$ Oct 10, 2019 at 12:34
  • \$\begingroup\$ Woops, forgot about my own rules allowing stream returns, haha XD I'm an idiot. But glad I could help you with my idiocy. ;p \$\endgroup\$ Oct 10, 2019 at 13:46
1
\$\begingroup\$

C# (Visual C# Interactive Compiler)

Without leading 0s, 104, 103 bytes

(s,e,n)=>new int[(e-s).Days+1].Select((x,i)=>s.AddDays(i)).Where(x=>$"{x:yyyMd}".Distinct().Count()>=n)

Try it online!

With leading 0s, 106 105 bytes

(s,e,n)=>new int[(e-s).Days+1].Select((x,i)=>s.AddDays(i)).Where(x=>$"{x:yyyMMdd}".Distinct().Count()>=n)

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ You can remove the space at x =>$" in both your versions for -1. :) \$\endgroup\$ Oct 15, 2019 at 12:29
  • \$\begingroup\$ @KevinCruijssen ah fuck thanks x) I'm sure someone can come up with a shorter solution too, I'm not satisfied with this one \$\endgroup\$
    – Innat3
    Oct 15, 2019 at 12:35
0
\$\begingroup\$

Kotlin, 119 bytes

fun f(a:LocalDate,b:LocalDate,c:Long)=a.datesUntil(b.plusDays(1)).filter{it.toString().chars().distinct().count()==c+1}

Without leading 0s, takes in two java.time.LocalDate and a Long, returns a Stream of LocalDates

\$\endgroup\$
1
  • \$\begingroup\$ Hi, welcome to CCGC! Could you perhaps add a Try it online link with test code to verify it works? Also, I don't know Kotlin, but is it possible to replace it.toString() with (it+"") to save a few bytes? I know this is possible in some other languages like Java or .NET C#. \$\endgroup\$ Oct 15, 2019 at 12:31

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.