From a99887954590dddced0c6110f360e11040c7a641 Mon Sep 17 00:00:00 2001 From: meatball <69751659+meatball133@users.noreply.github.com> Date: Fri, 6 Dec 2024 16:28:19 +0100 Subject: [PATCH 1/2] Fixes to concept tree --- misc/concept_tree.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/concept_tree.md b/misc/concept_tree.md index b89d34b2..ff207ae8 100644 --- a/misc/concept_tree.md +++ b/misc/concept_tree.md @@ -1,7 +1,7 @@ # Concept Tree This is a concept tree for the Crystal Syllabus. -It is a work in progress, it was last updated on 2024-01-13. +It is a work in progress, it was last updated on 2024-12-06. Each concept with an exercise around it has been implemented, the rest is still to be implemented. @@ -16,7 +16,7 @@ graph TD b(bools) end - subgraph J [Number Types] + subgraph J [Navigation Computer] ac(Number Types) end @@ -48,7 +48,7 @@ graph TD h(conditionals) end - subgraph I [Interest is intresting] + subgraph I [Interest is interesting] i(return) j(while) end From cd3dfe2100291ceeaf5660d90ac8a82cca2848c9 Mon Sep 17 00:00:00 2001 From: meatball Date: Sat, 3 Jan 2026 21:01:35 +0100 Subject: [PATCH 2/2] Add Swift Scheduling exercise with instructions, examples, and tests --- config.json | 8 ++ .../swift-scheduling/.docs/instructions.md | 50 +++++++++ .../swift-scheduling/.docs/introduction.md | 6 ++ .../swift-scheduling/.meta/config.json | 19 ++++ .../swift-scheduling/.meta/src/example.cr | 70 ++++++++++++ .../swift-scheduling/.meta/test_template.ecr | 12 +++ .../swift-scheduling/.meta/tests.toml | 58 ++++++++++ .../spec/swift_scheduling_spec.cr | 100 ++++++++++++++++++ .../swift-scheduling/src/swift_scheduling.cr | 5 + 9 files changed, 328 insertions(+) create mode 100644 exercises/practice/swift-scheduling/.docs/instructions.md create mode 100644 exercises/practice/swift-scheduling/.docs/introduction.md create mode 100644 exercises/practice/swift-scheduling/.meta/config.json create mode 100644 exercises/practice/swift-scheduling/.meta/src/example.cr create mode 100644 exercises/practice/swift-scheduling/.meta/test_template.ecr create mode 100644 exercises/practice/swift-scheduling/.meta/tests.toml create mode 100644 exercises/practice/swift-scheduling/spec/swift_scheduling_spec.cr create mode 100644 exercises/practice/swift-scheduling/src/swift_scheduling.cr diff --git a/config.json b/config.json index 4a708598..3d013963 100644 --- a/config.json +++ b/config.json @@ -1082,6 +1082,14 @@ "prerequisites": [], "difficulty": 4 }, + { + "slug": "swift-scheduling", + "name": "Swift Scheduling", + "uuid": "7f8b5494-1424-488a-a650-e5ceca8ed6f2", + "practices": [], + "prerequisites": [], + "difficulty": 4 + }, { "slug": "grade-school", "name": "Grade School", diff --git a/exercises/practice/swift-scheduling/.docs/instructions.md b/exercises/practice/swift-scheduling/.docs/instructions.md new file mode 100644 index 00000000..6423a106 --- /dev/null +++ b/exercises/practice/swift-scheduling/.docs/instructions.md @@ -0,0 +1,50 @@ +# Instructions + +Your task is to convert delivery date descriptions to _actual_ delivery dates, based on when the meeting started. + +There are two types of delivery date descriptions: + +1. Fixed: a predefined set of words. +2. Variable: words that have a variable component, but follow a predefined set of patterns. + +## Fixed delivery date descriptions + +There are three fixed delivery date descriptions: + +- `"NOW"` +- `"ASAP"` (As Soon As Possible) +- `"EOW"` (End Of Week) + +The following table shows how to translate them: + +| Description | Meeting start | Delivery date | +| ----------- | ----------------------------- | ----------------------------------- | +| `"NOW"` | - | Two hours after the meeting started | +| `"ASAP"` | Before 13:00 | Today at 17:00 | +| `"ASAP"` | After or at 13:00 | Tomorrow at 13:00 | +| `"EOW"` | Monday, Tuesday, or Wednesday | Friday at 17:00 | +| `"EOW"` | Thursday or Friday | Sunday at 20:00 | + +## Variable delivery date descriptions + +There are two variable delivery date description patterns: + +- `"M"` (N-th month) +- `"Q"` (N-th quarter) + +| Description | Meeting start | Delivery date | +| ----------- | ------------------------- | --------------------------------------------------------- | +| `"M"` | Before N-th month | At 8:00 on the _first_ workday of this year's N-th month | +| `"M"` | After or in N-th month | At 8:00 on the _first_ workday of next year's N-th month | +| `"Q"` | Before or in N-th quarter | At 8:00 on the _last_ workday of this year's N-th quarter | +| `"Q"` | After N-th quarter | At 8:00 on the _last_ workday of next year's N-th quarter | + +~~~~exercism/note +A workday is a Monday, Tuesday, Wednesday, Thursday, or Friday. + +A year has four quarters, each with three months: +1. January/February/March +2. April/May/June +3. July/August/September +4. October/November/December. +~~~~ diff --git a/exercises/practice/swift-scheduling/.docs/introduction.md b/exercises/practice/swift-scheduling/.docs/introduction.md new file mode 100644 index 00000000..2322f813 --- /dev/null +++ b/exercises/practice/swift-scheduling/.docs/introduction.md @@ -0,0 +1,6 @@ +# Introduction + +This week, it is your turn to take notes in the department's planning meeting. +In this meeting, your boss will set delivery dates for all open work items. +Annoyingly, instead of specifying the _actual_ delivery dates, your boss will only _describe them_ in an abbreviated format. +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. diff --git a/exercises/practice/swift-scheduling/.meta/config.json b/exercises/practice/swift-scheduling/.meta/config.json new file mode 100644 index 00000000..81c918a0 --- /dev/null +++ b/exercises/practice/swift-scheduling/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "meatball133" + ], + "files": { + "solution": [ + "src/swift_scheduling.cr" + ], + "test": [ + "spec/swift_scheduling_spec.cr" + ], + "example": [ + ".meta/src/example.cr" + ] + }, + "blurb": "Convert delivery date descriptions to actual delivery dates.", + "source": "Erik Schierboom", + "source_url": "https://github.com/exercism/problem-specifications/pull/2536" +} diff --git a/exercises/practice/swift-scheduling/.meta/src/example.cr b/exercises/practice/swift-scheduling/.meta/src/example.cr new file mode 100644 index 00000000..289a9635 --- /dev/null +++ b/exercises/practice/swift-scheduling/.meta/src/example.cr @@ -0,0 +1,70 @@ +module SwiftScheduling + private def self.first_workday_of_month(year : Int32, month : Int32) : Time + first = Time.utc(year, month, 1, 8, 0, 0) + + case first.day_of_week + when Time::DayOfWeek::Saturday + first + 2.days + when Time::DayOfWeek::Sunday + first + 1.day + else + first + end + end + + private def self.last_workday_of_month(year : Int32, month : Int32) : Time + next_month = month == 12 ? 1 : month + 1 + next_year = month == 12 ? year + 1 : year + + last = Time.utc(next_year, next_month, 1, 8, 0, 0) - 1.day + + case last.day_of_week + when Time::DayOfWeek::Saturday + last - 1.day + when Time::DayOfWeek::Sunday + last - 2.days + else + last + end + end + + def self.delivery_date(meeting_start : Time, description : String) : Time + result = meeting_start + case description + when "NOW" + result = meeting_start + 2.hours + when "ASAP" + if meeting_start.hour < 13 + result = Time.utc(meeting_start.year, meeting_start.month, meeting_start.day, 17, 0, 0) + else + tomorrow = meeting_start + 1.day + result = Time.utc(tomorrow.year, tomorrow.month, tomorrow.day, 13, 0, 0) + end + when "EOW" + case meeting_start.day_of_week.to_i + when 1..3 # Monday to Wednesday + friday = meeting_start + (5 - meeting_start.day_of_week.to_i).days + result = Time.utc(friday.year, friday.month, friday.day, 17, 0, 0) + when 4, 5 # Thursday or Friday + sunday = meeting_start + (7 - meeting_start.day_of_week.to_i).days + result = Time.utc(sunday.year, sunday.month, sunday.day, 20, 0, 0) + end + else + # | `"M"` | Before N-th month | At 8:00 on the _first_ workday of this year's N-th month | + # | `"M"` | After or in N-th month | At 8:00 on the _first_ workday of next year's N-th month | + # | `"Q"` | Before or in N-th quarter | At 8:00 on the _last_ workday of this year's N-th quarter | + # | `"Q"` | After N-th quarter | At 8:00 on the _last_ workday of next year's N-th quarter | + if description.includes?("M") + month = description[0..-2].to_i + year = meeting_start.month < month ? meeting_start.year : meeting_start.year + 1 + result = first_workday_of_month(year, month) + elsif description.includes?("Q") + quarter = description[1..-1].to_i + start_quarter = ((meeting_start.month - 1) // 3) + 1 + year = start_quarter <= quarter ? meeting_start.year : meeting_start.year + 1 + result = last_workday_of_month(year, quarter * 3) + end + end + result + end +end diff --git a/exercises/practice/swift-scheduling/.meta/test_template.ecr b/exercises/practice/swift-scheduling/.meta/test_template.ecr new file mode 100644 index 00000000..94b99c78 --- /dev/null +++ b/exercises/practice/swift-scheduling/.meta/test_template.ecr @@ -0,0 +1,12 @@ +require "spec" +require "../src/*" + +describe "<%-= to_capitalized(@json["exercise"].to_s) %>" do +<%- @json["cases"].as_a.each do |cases| %> + <%= status()%> "<%-= cases["description"] %>" do + start = Time.parse_utc("<%= cases["input"]["meetingStart"] %>", "%Y-%m-%dT%H:%M:%S") + expected = Time.parse_utc("<%-= cases["expected"] %>", "%Y-%m-%dT%H:%M:%S") + <%-= to_capitalized(@json["exercise"].to_s) %>.<%= cases["property"].to_s.underscore %>(start, <%= cases["input"]["description"].to_s.inspect %>).should eq(expected) + end +<% end %> +end \ No newline at end of file diff --git a/exercises/practice/swift-scheduling/.meta/tests.toml b/exercises/practice/swift-scheduling/.meta/tests.toml new file mode 100644 index 00000000..7cc3e415 --- /dev/null +++ b/exercises/practice/swift-scheduling/.meta/tests.toml @@ -0,0 +1,58 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[1d0e6e72-f370-408c-bc64-5dafa9c6da73] +description = "NOW translates to two hours later" + +[93325e7b-677d-4d96-b017-2582af879dc2] +description = "ASAP before one in the afternoon translates to today at five in the afternoon" + +[cb4252a3-c4c1-41f6-8b8c-e7269733cef8] +description = "ASAP at one in the afternoon translates to tomorrow at one in the afternoon" + +[6fddc1ea-2fe9-4c60-81f7-9220d2f45537] +description = "ASAP after one in the afternoon translates to tomorrow at one in the afternoon" + +[25f46bf9-6d2a-4e95-8edd-f62dd6bc8a6e] +description = "EOW on Monday translates to Friday at five in the afternoon" + +[0b375df5-d198-489e-acee-fd538a768616] +description = "EOW on Tuesday translates to Friday at five in the afternoon" + +[4afbb881-0b5c-46be-94e1-992cdc2a8ca4] +description = "EOW on Wednesday translates to Friday at five in the afternoon" + +[e1341c2b-5e1b-4702-a95c-a01e8e96e510] +description = "EOW on Thursday translates to Sunday at eight in the evening" + +[bbffccf7-97f7-4244-888d-bdd64348fa2e] +description = "EOW on Friday translates to Sunday at eight in the evening" + +[d651fcf4-290e-407c-8107-36b9076f39b2] +description = "EOW translates to leap day" + +[439bf09f-3a0e-44e7-bad5-b7b6d0c4505a] +description = "2M before the second month of this year translates to the first workday of the second month of this year" + +[86d82e83-c481-4fb4-9264-625de7521340] +description = "11M in the eleventh month translates to the first workday of the eleventh month of next year" + +[0d0b8f6a-1915-46f5-a630-1ff06af9da08] +description = "4M in the ninth month translates to the first workday of the fourth month of next year" + +[06d401e3-8461-438f-afae-8d26aa0289e0] +description = "Q1 in the first quarter translates to the last workday of the first quarter of this year" + +[eebd5f32-b16d-4ecd-91a0-584b0364b7ed] +description = "Q4 in the second quarter translates to the last workday of the fourth quarter of this year" + +[c920886c-44ad-4d34-a156-dc4176186581] +description = "Q3 in the fourth quarter translates to the last workday of the third quarter of next year" diff --git a/exercises/practice/swift-scheduling/spec/swift_scheduling_spec.cr b/exercises/practice/swift-scheduling/spec/swift_scheduling_spec.cr new file mode 100644 index 00000000..0f76dc06 --- /dev/null +++ b/exercises/practice/swift-scheduling/spec/swift_scheduling_spec.cr @@ -0,0 +1,100 @@ +require "spec" +require "../src/*" + +describe "SwiftScheduling" do + it "NOW translates to two hours later" do + start = Time.parse_utc("2012-02-13T09:00:00", "%Y-%m-%dT%H:%M:%S") + expected = Time.parse_utc("2012-02-13T11:00:00", "%Y-%m-%dT%H:%M:%S") + SwiftScheduling.delivery_date(start, "NOW").should eq(expected) + end + + pending "ASAP before one in the afternoon translates to today at five in the afternoon" do + start = Time.parse_utc("1999-06-03T09:45:00", "%Y-%m-%dT%H:%M:%S") + expected = Time.parse_utc("1999-06-03T17:00:00", "%Y-%m-%dT%H:%M:%S") + SwiftScheduling.delivery_date(start, "ASAP").should eq(expected) + end + + pending "ASAP at one in the afternoon translates to tomorrow at one in the afternoon" do + start = Time.parse_utc("2008-12-21T13:00:00", "%Y-%m-%dT%H:%M:%S") + expected = Time.parse_utc("2008-12-22T13:00:00", "%Y-%m-%dT%H:%M:%S") + SwiftScheduling.delivery_date(start, "ASAP").should eq(expected) + end + + pending "ASAP after one in the afternoon translates to tomorrow at one in the afternoon" do + start = Time.parse_utc("2008-12-21T14:50:00", "%Y-%m-%dT%H:%M:%S") + expected = Time.parse_utc("2008-12-22T13:00:00", "%Y-%m-%dT%H:%M:%S") + SwiftScheduling.delivery_date(start, "ASAP").should eq(expected) + end + + pending "EOW on Monday translates to Friday at five in the afternoon" do + start = Time.parse_utc("2025-02-03T16:00:00", "%Y-%m-%dT%H:%M:%S") + expected = Time.parse_utc("2025-02-07T17:00:00", "%Y-%m-%dT%H:%M:%S") + SwiftScheduling.delivery_date(start, "EOW").should eq(expected) + end + + pending "EOW on Tuesday translates to Friday at five in the afternoon" do + start = Time.parse_utc("1997-04-29T10:50:00", "%Y-%m-%dT%H:%M:%S") + expected = Time.parse_utc("1997-05-02T17:00:00", "%Y-%m-%dT%H:%M:%S") + SwiftScheduling.delivery_date(start, "EOW").should eq(expected) + end + + pending "EOW on Wednesday translates to Friday at five in the afternoon" do + start = Time.parse_utc("2005-09-14T11:00:00", "%Y-%m-%dT%H:%M:%S") + expected = Time.parse_utc("2005-09-16T17:00:00", "%Y-%m-%dT%H:%M:%S") + SwiftScheduling.delivery_date(start, "EOW").should eq(expected) + end + + pending "EOW on Thursday translates to Sunday at eight in the evening" do + start = Time.parse_utc("2011-05-19T08:30:00", "%Y-%m-%dT%H:%M:%S") + expected = Time.parse_utc("2011-05-22T20:00:00", "%Y-%m-%dT%H:%M:%S") + SwiftScheduling.delivery_date(start, "EOW").should eq(expected) + end + + pending "EOW on Friday translates to Sunday at eight in the evening" do + start = Time.parse_utc("2022-08-05T14:00:00", "%Y-%m-%dT%H:%M:%S") + expected = Time.parse_utc("2022-08-07T20:00:00", "%Y-%m-%dT%H:%M:%S") + SwiftScheduling.delivery_date(start, "EOW").should eq(expected) + end + + pending "EOW translates to leap day" do + start = Time.parse_utc("2008-02-25T10:30:00", "%Y-%m-%dT%H:%M:%S") + expected = Time.parse_utc("2008-02-29T17:00:00", "%Y-%m-%dT%H:%M:%S") + SwiftScheduling.delivery_date(start, "EOW").should eq(expected) + end + + pending "2M before the second month of this year translates to the first workday of the second month of this year" do + start = Time.parse_utc("2007-01-02T14:15:00", "%Y-%m-%dT%H:%M:%S") + expected = Time.parse_utc("2007-02-01T08:00:00", "%Y-%m-%dT%H:%M:%S") + SwiftScheduling.delivery_date(start, "2M").should eq(expected) + end + + pending "11M in the eleventh month translates to the first workday of the eleventh month of next year" do + start = Time.parse_utc("2013-11-21T15:30:00", "%Y-%m-%dT%H:%M:%S") + expected = Time.parse_utc("2014-11-03T08:00:00", "%Y-%m-%dT%H:%M:%S") + SwiftScheduling.delivery_date(start, "11M").should eq(expected) + end + + pending "4M in the ninth month translates to the first workday of the fourth month of next year" do + start = Time.parse_utc("2019-11-18T15:15:00", "%Y-%m-%dT%H:%M:%S") + expected = Time.parse_utc("2020-04-01T08:00:00", "%Y-%m-%dT%H:%M:%S") + SwiftScheduling.delivery_date(start, "4M").should eq(expected) + end + + pending "Q1 in the first quarter translates to the last workday of the first quarter of this year" do + start = Time.parse_utc("2003-01-01T10:45:00", "%Y-%m-%dT%H:%M:%S") + expected = Time.parse_utc("2003-03-31T08:00:00", "%Y-%m-%dT%H:%M:%S") + SwiftScheduling.delivery_date(start, "Q1").should eq(expected) + end + + pending "Q4 in the second quarter translates to the last workday of the fourth quarter of this year" do + start = Time.parse_utc("2001-04-09T09:00:00", "%Y-%m-%dT%H:%M:%S") + expected = Time.parse_utc("2001-12-31T08:00:00", "%Y-%m-%dT%H:%M:%S") + SwiftScheduling.delivery_date(start, "Q4").should eq(expected) + end + + pending "Q3 in the fourth quarter translates to the last workday of the third quarter of next year" do + start = Time.parse_utc("2022-10-06T11:00:00", "%Y-%m-%dT%H:%M:%S") + expected = Time.parse_utc("2023-09-29T08:00:00", "%Y-%m-%dT%H:%M:%S") + SwiftScheduling.delivery_date(start, "Q3").should eq(expected) + end +end diff --git a/exercises/practice/swift-scheduling/src/swift_scheduling.cr b/exercises/practice/swift-scheduling/src/swift_scheduling.cr new file mode 100644 index 00000000..8cd85f5f --- /dev/null +++ b/exercises/practice/swift-scheduling/src/swift_scheduling.cr @@ -0,0 +1,5 @@ +module SwiftScheduling + def self.delivery_date(meeting_start : Time, description : String) : Time + # Write your code for the 'Swift Scheduling' exercise in this file. + end +end