Skip to content

Commit ba433a8

Browse files
authored
Merge branch 'main' into add-intergalactic-transmission
2 parents 0b429ca + 312ab2c commit ba433a8

File tree

14 files changed

+822
-0
lines changed

14 files changed

+822
-0
lines changed

config.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,18 @@
854854
],
855855
"difficulty": 4
856856
},
857+
{
858+
"slug": "swift-scheduling",
859+
"name": "Swift Scheduling",
860+
"uuid": "7f5388dc-ce0e-40d4-98d1-7a00aeae018d",
861+
"practices": [],
862+
"prerequisites": [
863+
"if-else-statements",
864+
"datetime",
865+
"strings"
866+
],
867+
"difficulty": 4
868+
},
857869
{
858870
"slug": "triangle",
859871
"name": "Triangle",
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Instructions
2+
3+
Your task is to convert delivery date descriptions to _actual_ delivery dates, based on when the meeting started.
4+
5+
There are two types of delivery date descriptions:
6+
7+
1. Fixed: a predefined set of words.
8+
2. Variable: words that have a variable component, but follow a predefined set of patterns.
9+
10+
## Fixed delivery date descriptions
11+
12+
There are three fixed delivery date descriptions:
13+
14+
- `"NOW"`
15+
- `"ASAP"` (As Soon As Possible)
16+
- `"EOW"` (End Of Week)
17+
18+
The following table shows how to translate them:
19+
20+
| Description | Meeting start | Delivery date |
21+
| ----------- | ----------------------------- | ----------------------------------- |
22+
| `"NOW"` | - | Two hours after the meeting started |
23+
| `"ASAP"` | Before 13:00 | Today at 17:00 |
24+
| `"ASAP"` | After or at 13:00 | Tomorrow at 13:00 |
25+
| `"EOW"` | Monday, Tuesday, or Wednesday | Friday at 17:00 |
26+
| `"EOW"` | Thursday or Friday | Sunday at 20:00 |
27+
28+
## Variable delivery date descriptions
29+
30+
There are two variable delivery date description patterns:
31+
32+
- `"<N>M"` (N-th month)
33+
- `"Q<N>"` (N-th quarter)
34+
35+
| Description | Meeting start | Delivery date |
36+
| ----------- | ------------------------- | --------------------------------------------------------- |
37+
| `"<N>M"` | Before N-th month | At 8:00 on the _first_ workday of this year's N-th month |
38+
| `"<N>M"` | After or in N-th month | At 8:00 on the _first_ workday of next year's N-th month |
39+
| `"Q<N>"` | Before or in N-th quarter | At 8:00 on the _last_ workday of this year's N-th quarter |
40+
| `"Q<N>"` | After N-th quarter | At 8:00 on the _last_ workday of next year's N-th quarter |
41+
42+
~~~~exercism/note
43+
A workday is a Monday, Tuesday, Wednesday, Thursday, or Friday.
44+
45+
A year has four quarters, each with three months:
46+
1. January/February/March
47+
2. April/May/June
48+
3. July/August/September
49+
4. October/November/December.
50+
~~~~
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Introduction
2+
3+
This week, it is your turn to take notes in the department's planning meeting.
4+
In this meeting, your boss will set delivery dates for all open work items.
5+
Annoyingly, instead of specifying the _actual_ delivery dates, your boss will only _describe them_ in an abbreviated format.
6+
As many of your colleagues won't be familiar with this corporate lingo, you'll need to convert these delivery date descriptions to actual delivery dates.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"authors": [
3+
"zamora-carlos"
4+
],
5+
"files": {
6+
"solution": [
7+
"src/main/java/SwiftScheduling.java"
8+
],
9+
"test": [
10+
"src/test/java/SwiftSchedulingTest.java"
11+
],
12+
"example": [
13+
".meta/src/reference/java/SwiftScheduling.java"
14+
]
15+
},
16+
"blurb": "Convert delivery date descriptions to actual delivery dates.",
17+
"source": "Erik Schierboom",
18+
"source_url": "https://github.com/exercism/problem-specifications/pull/2536"
19+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import java.time.DayOfWeek;
2+
import java.time.LocalDateTime;
3+
4+
import static java.time.DayOfWeek.*;
5+
6+
public class SwiftScheduling {
7+
public static LocalDateTime convertToDeliveryDate(LocalDateTime meetingStart, String description) {
8+
if ("NOW".equals(description)) {
9+
return meetingStart.plusHours(2);
10+
}
11+
12+
if ("ASAP".equals(description)) {
13+
LocalDateTime sameDayAt1pm = toStartOfDay(meetingStart).withHour(13);
14+
15+
if (meetingStart.isBefore(sameDayAt1pm)) {
16+
return toStartOfDay(meetingStart).withHour(17);
17+
} else {
18+
return toStartOfDay(meetingStart).plusDays(1).withHour(13);
19+
}
20+
}
21+
22+
if ("EOW".equals(description)) {
23+
DayOfWeek day = meetingStart.getDayOfWeek();
24+
LocalDateTime deliveryDate = toStartOfDay(meetingStart);
25+
26+
if (day == MONDAY || day == TUESDAY || day == WEDNESDAY) {
27+
deliveryDate = deliveryDate.withHour(17);
28+
while (deliveryDate.getDayOfWeek() != FRIDAY) {
29+
deliveryDate = deliveryDate.plusDays(1);
30+
}
31+
} else if (day == THURSDAY || day == FRIDAY) {
32+
deliveryDate = deliveryDate.withHour(20);
33+
while (deliveryDate.getDayOfWeek() != SUNDAY) {
34+
deliveryDate = deliveryDate.plusDays(1);
35+
}
36+
} else {
37+
throw new IllegalArgumentException("Invalid day of week");
38+
}
39+
40+
return deliveryDate;
41+
}
42+
43+
if (description.matches("\\d+M")) {
44+
int month = Integer.parseInt(description.substring(0, description.length() - 1));
45+
LocalDateTime targetMonth = toStartOfDay(meetingStart)
46+
.withMonth(month)
47+
.withDayOfMonth(1);
48+
49+
if (!meetingStart.isBefore(targetMonth)) {
50+
targetMonth = targetMonth.plusYears(1);
51+
}
52+
53+
LocalDateTime deliveryDate = targetMonth.withHour(8);
54+
while (isWeekend(deliveryDate)) {
55+
deliveryDate = deliveryDate.plusDays(1);
56+
}
57+
58+
return deliveryDate;
59+
}
60+
61+
if (description.matches("Q\\d")) {
62+
int quarter = Integer.parseInt(description.substring(1));
63+
LocalDateTime lastDayOfQuarter = getLastDayOfQuarter(meetingStart, quarter);
64+
65+
if (!meetingStart.isBefore(lastDayOfQuarter.plusDays(1))) {
66+
lastDayOfQuarter = lastDayOfQuarter.plusYears(1);
67+
}
68+
69+
LocalDateTime deliveryDate = lastDayOfQuarter.withHour(8);
70+
while (isWeekend(deliveryDate)) {
71+
deliveryDate = deliveryDate.minusDays(1);
72+
}
73+
74+
return deliveryDate;
75+
}
76+
77+
throw new IllegalArgumentException("Invalid description");
78+
}
79+
80+
private static LocalDateTime toStartOfDay(LocalDateTime dateTime) {
81+
return dateTime.toLocalDate().atStartOfDay();
82+
}
83+
84+
private static LocalDateTime getLastDayOfQuarter(LocalDateTime dateTime, int quarter) {
85+
int lastMonthOfQuarter = quarter * 3;
86+
return toStartOfDay(dateTime)
87+
.withMonth(lastMonthOfQuarter)
88+
.withDayOfMonth(1)
89+
.plusMonths(1)
90+
.minusDays(1);
91+
}
92+
93+
private static boolean isWeekend(LocalDateTime date) {
94+
DayOfWeek dayOfWeek = date.getDayOfWeek();
95+
return dayOfWeek == SATURDAY || dayOfWeek == SUNDAY;
96+
}
97+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
11+
12+
[1d0e6e72-f370-408c-bc64-5dafa9c6da73]
13+
description = "NOW translates to two hours later"
14+
15+
[93325e7b-677d-4d96-b017-2582af879dc2]
16+
description = "ASAP before one in the afternoon translates to today at five in the afternoon"
17+
18+
[cb4252a3-c4c1-41f6-8b8c-e7269733cef8]
19+
description = "ASAP at one in the afternoon translates to tomorrow at one in the afternoon"
20+
21+
[6fddc1ea-2fe9-4c60-81f7-9220d2f45537]
22+
description = "ASAP after one in the afternoon translates to tomorrow at one in the afternoon"
23+
24+
[25f46bf9-6d2a-4e95-8edd-f62dd6bc8a6e]
25+
description = "EOW on Monday translates to Friday at five in the afternoon"
26+
27+
[0b375df5-d198-489e-acee-fd538a768616]
28+
description = "EOW on Tuesday translates to Friday at five in the afternoon"
29+
30+
[4afbb881-0b5c-46be-94e1-992cdc2a8ca4]
31+
description = "EOW on Wednesday translates to Friday at five in the afternoon"
32+
33+
[e1341c2b-5e1b-4702-a95c-a01e8e96e510]
34+
description = "EOW on Thursday translates to Sunday at eight in the evening"
35+
36+
[bbffccf7-97f7-4244-888d-bdd64348fa2e]
37+
description = "EOW on Friday translates to Sunday at eight in the evening"
38+
39+
[d651fcf4-290e-407c-8107-36b9076f39b2]
40+
description = "EOW translates to leap day"
41+
42+
[439bf09f-3a0e-44e7-bad5-b7b6d0c4505a]
43+
description = "2M before the second month of this year translates to the first workday of the second month of this year"
44+
45+
[86d82e83-c481-4fb4-9264-625de7521340]
46+
description = "11M in the eleventh month translates to the first workday of the eleventh month of next year"
47+
48+
[0d0b8f6a-1915-46f5-a630-1ff06af9da08]
49+
description = "4M in the ninth month translates to the first workday of the fourth month of next year"
50+
51+
[06d401e3-8461-438f-afae-8d26aa0289e0]
52+
description = "Q1 in the first quarter translates to the last workday of the first quarter of this year"
53+
54+
[eebd5f32-b16d-4ecd-91a0-584b0364b7ed]
55+
description = "Q4 in the second quarter translates to the last workday of the fourth quarter of this year"
56+
57+
[c920886c-44ad-4d34-a156-dc4176186581]
58+
description = "Q3 in the fourth quarter translates to the last workday of the third quarter of next year"
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
plugins {
2+
id "java"
3+
}
4+
5+
repositories {
6+
mavenCentral()
7+
}
8+
9+
dependencies {
10+
testImplementation platform("org.junit:junit-bom:5.10.0")
11+
testImplementation "org.junit.jupiter:junit-jupiter"
12+
testImplementation "org.assertj:assertj-core:3.25.1"
13+
14+
testRuntimeOnly "org.junit.platform:junit-platform-launcher"
15+
}
16+
17+
test {
18+
useJUnitPlatform()
19+
20+
testLogging {
21+
exceptionFormat = "full"
22+
showStandardStreams = true
23+
events = ["passed", "failed", "skipped"]
24+
}
25+
}
Binary file not shown.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
distributionBase=GRADLE_USER_HOME
2+
distributionPath=wrapper/dists
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
4+
validateDistributionUrl=true
5+
zipStoreBase=GRADLE_USER_HOME
6+
zipStorePath=wrapper/dists

0 commit comments

Comments
 (0)