8
\$\begingroup\$

Background

You're an attractive code golfer and quite a few people are asking you out.

You don't have time to think about which days exactly you're available, so you decide to create a function the accepts a date and returns the days of that week.

You then take those days of the week, insert it into your calendar program to see if anyone else has asked you out already.

Rules

  • Accepts a date in YYYY-MM-DD format
  • Returns an array/list of dates of that week. (Sunday is the first day)
    • The dates can be displayed as the milliseconds between January 1, 1970 and that date, in a "common" date format1, or date objects.
  • The order of the dates must be ascending.
    • (Although you're smart enough to include support for a descending list, the program is able to work quickest with an ascending list and who has a few milliseconds to spare?)
  • Must work with on any day since 1993. (Yes, you're 24 years old at the time of writing!)
  • Every Javascript answer gets a high five!

Specs

Sample Input: whichDates(2017-08-29)

Output: (the equivalent of)

console.log([
  Date.parse('2017-08-27'),
  Date.parse('2017-08-28'),
  Date.parse('2017-08-29'),
  Date.parse('2017-08-30'),
  Date.parse('2017-08-31'),
  Date.parse('2017-09-01'),
  Date.parse('2017-09-02'),
]);

1 A format that is fairly well known. Such as YYYY-MM-DD.

2 This is ! Shortest code per language wins, but the shortest code overall gets the emerald checkmark!

\$\endgroup\$
  • 2
    \$\begingroup\$ Also, I suggest you to allow other formats, other than YYYY-MM-DD (I don't see a good reason why it should be strict). \$\endgroup\$ – Mr. Xcoder Sep 1 '17 at 21:32
  • 5
    \$\begingroup\$ The first sentence is the weirdest and less plausible introduction I've seen in a challenge. Well done :-) \$\endgroup\$ – Luis Mendo Sep 1 '17 at 23:29
  • 2
    \$\begingroup\$ @LuisMendo Thanks! But you never know who exactly is secretly admiring your sick programming skills.... \$\endgroup\$ – Chris Happy Sep 1 '17 at 23:31
  • 1
    \$\begingroup\$ Why Every Javascript answer gets a high five! ? \$\endgroup\$ – sergiol Sep 2 '17 at 0:23
  • 1
    \$\begingroup\$ Date.parse(2017-08-27) ?? should this be Date.parse('2017-08-27')? \$\endgroup\$ – tsh Sep 2 '17 at 9:26

10 Answers 10

1
\$\begingroup\$

Japt, 15 bytes

ÐU
7Æf1X+Uf -Ue

Test it


Explanation

Implicit input of string U.

ÐU

Convert U to a date object and reassign to U.

Create an array of integers from 0 to 6, passing each through a function where X is the current element.

f1

Set the date of U.

X+Uf

Add the current date of U to X.

-Ue

Subtract the current day of the week of U.

Implicitly output the resulting array.

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

Perl 6, 47 bytes

{my$d=Date.new($_);map($d+*-$d.day-of-week,^7)}

Try it online!

The code is almost self-explanatory. First we make up a Date object $d from the string, which happens to be in the nice ISOwhatever format. We can perform arithmetic with the dates (adding an integer = adding that many days, the same with subtracting). So $d-$d.day-of-week is the last this (oh my god, week has always started with Monday for me :D) week's Sunday. (.day-of-week is 1 for Monday to 7 for Sunday.) We then map over 0 to 6 (^7) and add that to the Sunday, getting all the days in the week. The number we're mapping over appears in the place of the star *. This list is then returned.

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

JavaScript (ES6), 73 63 62 Bytes

I thought I'd also have a go at it in JavaScript.

Edit: Using the milliseconds approach, as allowed by the prompt, I reduced it down to 62 bytes.

s=>[..."0123456"].map(i=>(x=new Date(s))-(x.getDay()-i)*864e5)

You could perform a .map(x=>new Date(x)) on the returned array if you wanted to convert it.


Maintaining the date approach (72 Bytes)

s=>[..."0123456"].map(i=>new Date((x=new Date(s))-(x.getDay()-i)*864e5))

There was a bug in my initial submission, it is fixed. Thanks to an observation by milk, I was able to remove the bug and still lower the byte count.

\$\endgroup\$
  • \$\begingroup\$ High Five!! \$\endgroup\$ – Chris Happy Sep 2 '17 at 0:29
  • 2
    \$\begingroup\$ Welcome to the site! \$\endgroup\$ – Luis Mendo Sep 2 '17 at 0:29
  • \$\begingroup\$ It's shorter to just write out the numbers in the array. 60 bytes: s=>[..."0123456"].map(i=>(x=new Date(s))-(x.getDay()-i)*8e7) \$\endgroup\$ – milk Sep 2 '17 at 0:37
  • 1
    \$\begingroup\$ Welcome to PPCG, and nicely tied :) Tip 1: Ditch the keys and use the index instead of the element when mapping over the array. Tip 2: For an array this small, it's shorter to generate it the way I did. \$\endgroup\$ – Shaggy Sep 2 '17 at 0:41
3
\$\begingroup\$

MATL, 22 21 bytes

7:j8XOs21Y2=f-GYO+1XO

Output is in dd-mm-yyyy format.

Try it at MATL Online!

Explanation

7:     % Push [1 2 3 4 5 6 7]
j      % Input as a string
8XO    % Convert date to string with format 8, which is 'Mon', 'Tue' etc
s      % Sum
21Y2   % Push predefined literal [298 302 288 305 289 296 310]. The first number
       % is the sum of ASCII codes of 'Mon', the second is that of 'Tue', etc.
=      % Is equal?, element-wise
f      % Index of nonzero value. For example, if input is a Friday this gives 5
-      % Subtract, element-wise. For a Friday this gives [-4 -3 -2 -1 0 1 2]
G      % Push input again
YO     % Convert to date number: number of days from January 0, 0000
+      % Add, element-wise
1XO    % Convert to date format 1, which is 'dd-mm-yyyy'. Implicitly display
\$\endgroup\$
3
\$\begingroup\$

JavaScript (ES6), 76 bytes

I think I've finally found the environment least conducive to efficient golfing: from behind my bar, while serving pints with my other hand!

s=>[...""+8e6].map((_,x)=>d.setDate(d.getDate()-d.getDay()+x),d=new Date(s))

Try it online (Snippet to follow)


Explanation

s=>

Anonymous function taking the string (of format yyyy-(m)m-(d)d) as an argument via parameter s.

[...""+8e6]

Create an array of 7 elements by converting 8000000 in scientific notation to a string and destructuring it, which is shorter than [...Array(7)].

.map((_,x)=>          )

Map over the array, passing each element through a function where _ is the current element, which won't be used, and x is the current index, 0-based.

,d=new Date(s)

Convert s to a Date object and assign it to variable d

d.setDate(     )

Set the date of d.

d.getDate()

Get the current date of d.

-d.getDay()

Subtract the current weekday number, 0-indexed, to get Sunday.

+x

Add x.

\$\endgroup\$
  • 2
    \$\begingroup\$ while serving pints with my other hand! - Nice multitasking skills :-) \$\endgroup\$ – Mr. Xcoder Sep 1 '17 at 21:42
  • \$\begingroup\$ Almost forgot... High Five! \$\endgroup\$ – Chris Happy Sep 1 '17 at 22:47
  • 2
    \$\begingroup\$ @ChrisHappy if you're learning JS, don't look to code golf for tips :P \$\endgroup\$ – caird coinheringaahing Sep 1 '17 at 22:48
  • 1
    \$\begingroup\$ @ChrisHappy: It could well be Sunday until I have time enough to write one up; stuck behind the bar 'til then. \$\endgroup\$ – Shaggy Sep 2 '17 at 0:29
  • 1
    \$\begingroup\$ @ChrisHappy: Found a minute, explanation added. You should have a look at the JS tips under the tips tag if you're looking for more trickd for golfing in JS. \$\endgroup\$ – Shaggy Sep 2 '17 at 10:46
2
\$\begingroup\$

Bash + common utilities, 53

jot -w@ 7 `date -f- +%s-%w*86400|bc` - 86400|date -f-

Try it online.

This assumes that the output of GNU date is a "common" date format, e.g. Fri Sep 1 00:00:00 UTC 2017.

Explanation

           date -f- +%s-%w*86400                       # read date from STDIN, output expression "seconds-since-epoch - (index of day in week * 60 * 60 * 24)
                                |bc                    # arithmetically evaluate generated expression - result is date of required sunday in seconds-since-epoch
jot -w@ 7 `                        ` - 86400           # output seconds-since-epoch for all 7 required days of the week, prefixed with "@"
                                            |date -f-  # convert all seconds-since-epoch dates back to regular dates
\$\endgroup\$
2
\$\begingroup\$

Python 3, 133 124 126 112 bytes

-9 bytes thanks to Mr. Xcoder
+2 bytes because the week starts with Sunday
-14 bytes thanks to notjagan

from datetime import*
a=date(*map(int,input().split('-')))
for i in range(7):print(a-timedelta(a.weekday()-i+1))

That didn't go as well as I had hoped.

\$\endgroup\$
  • \$\begingroup\$ 127 bytes \$\endgroup\$ – Mr. Xcoder Sep 1 '17 at 22:42
  • 1
    \$\begingroup\$ 124 bytes \$\endgroup\$ – Mr. Xcoder Sep 1 '17 at 22:43
  • 1
    \$\begingroup\$ 110 bytes. \$\endgroup\$ – notjagan Sep 1 '17 at 23:54
  • \$\begingroup\$ This works in Python2 also if we do raw_input() instead of input() above. (+4 bytes). range still works in Python2 for this small thing as well. Without raw_input you get errors. \$\endgroup\$ – Thomas Ward Sep 2 '17 at 15:45
1
\$\begingroup\$

Mathematica 20 bytes?

Mathematica expresses the list of days as a single date object. If such date object is acceptable output, the following 20-byte pure function will work:

#~DateObject~"Week"&

Example

#~DateObject~"Week"&["2017-08-29"]

week object

\$\endgroup\$
  • 1
    \$\begingroup\$ I don't see a problem with it! :) \$\endgroup\$ – Chris Happy Sep 23 '17 at 17:43
1
\$\begingroup\$

Java 8 (161 154 123 122 102 + 19 36 bytes)

Try it online!

import static java.time.LocalDate.*;

e->{for(int i=0;i<7;System.out.println(parse(e).plusDays(i++-parse(e).getDayOfWeek().getValue()%7)));}
\$\endgroup\$
  • \$\begingroup\$ Don't forget to include imports in your solution and byte count. \$\endgroup\$ – Jakob Sep 1 '17 at 23:49
  • \$\begingroup\$ Also you can save bytes by removing l and replacing references with LocalDate.parse(e). \$\endgroup\$ – Jakob Sep 2 '17 at 0:04
  • \$\begingroup\$ @Jakob Good shout, thank you \$\endgroup\$ – Roberto Graham Sep 2 '17 at 11:03
  • \$\begingroup\$ And now you can increment i in the loop body to save 1 byte. Oh, and the java.util.function.* import isn't used by the lambda, so you don't have to count it as part of the solution. \$\endgroup\$ – Jakob Sep 2 '17 at 16:05
1
\$\begingroup\$

Python 2, 115 Bytes or 111 Bytes, depending on input format.

Basically, this is almost the same code in the answer for Python3 written by Sobsz, but made to work in Python 2.


If input is in the form YYYY-MM-DD:

(This assumes the input is not wrapped in single-quotes to denote a string as input)

Key difference is that we need raw_input instead of input, unless we explicitly specify the date in 'YYYY-MM-DD' within the apostrophes to identify it as a string literal. Without the string literal input, we get a Syntax Error, hence the use of raw_input to accept dates in YYYY-MM-DD directly without putting it in string literals.

This of course assumes that the input is put in like so: 2017-08-29.

from datetime import*
a=date(*map(int,raw_input().split('-')))
for i in range(7):print a-timedelta(a.weekday()-i+1)

+4 from Sobsz's answer, then -1 because we don't need parentheses for the print statement and save a byte from the closing parenthesis not being there; total of +3 bytes difference.

Try it Online!


If input is in the form 'YYYY-MM-DD':

(Note that we must have the date provided inside quotes in order for this answer to work)

We get to save 4 bytes because we don't need the raw_ and this is effectively the same answer as Sobsz provides, minus a byte because we don't need the parentheses around the print command.

Thanks to Mr. Xcoder for pointing this one out, though this is technically an exact duplicate then, minus one byte, of Sobsz's answer.

from datetime import*
a=date(*map(int,input().split('-')))
for i in range(7):print a-timedelta(a.weekday()-i+1)
\$\endgroup\$
  • 1
    \$\begingroup\$ Welcome to PPCG! You can replace raw_input() with input and surround the input with quotes to save 4 bytes. Of course, that turns your solution into a duplicate though :P \$\endgroup\$ – Mr. Xcoder Sep 2 '17 at 16:09
  • \$\begingroup\$ @Mr.Xcoder True, which is why I skipped that. Though, if we put the input in quotes first, we actually save a byte from Sobsz, and I did make a note of that. \$\endgroup\$ – Thomas Ward Sep 2 '17 at 16:14

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.