diff --git a/config.json b/config.json index f3c1e1b..058b1d0 100644 --- a/config.json +++ b/config.json @@ -97,14 +97,6 @@ "difficulty": 2, "status": "deprecated" }, - { - "slug": "clock", - "name": "Clock", - "uuid": "b1ebc201-5d23-4953-88d7-58c82def95b3", - "practices": [], - "prerequisites": [], - "difficulty": 2 - }, { "slug": "collatz-conjecture", "name": "Collatz Conjecture", @@ -331,6 +323,14 @@ "prerequisites": [], "difficulty": 3 }, + { + "slug": "clock", + "name": "Clock", + "uuid": "b1ebc201-5d23-4953-88d7-58c82def95b3", + "practices": [], + "prerequisites": [], + "difficulty": 3 + }, { "slug": "crypto-square", "name": "Crypto Square", diff --git a/exercises/practice/clock/.meta/Example.roc b/exercises/practice/clock/.meta/Example.roc index f0b48ed..f4d9bf1 100644 --- a/exercises/practice/clock/.meta/Example.roc +++ b/exercises/practice/clock/.meta/Example.roc @@ -6,7 +6,9 @@ minutesPerDay = 24 * 60 create : { hours ? I64, minutes ? I64 }* -> Clock create = \{ hours ? 0, minutes ? 0 } -> - totalMinutes = ((hours * 60 + minutes) % minutesPerDay + minutesPerDay) % minutesPerDay + hours24 = (hours % 24 + minutes // 60) % 24 + minutes60 = minutes % 60 + totalMinutes = ((hours24 * 60 + minutes60) % minutesPerDay + minutesPerDay) % minutesPerDay hh = totalMinutes // 60 |> Num.toU8 mm = totalMinutes % 60 |> Num.toU8 { hour: hh, minute: mm } @@ -18,10 +20,10 @@ toStr = \{ hour, minute } -> add : Clock, { hours ? I64, minutes ? I64 }* -> Clock add = \{ hour, minute }, { hours ? 0, minutes ? 0 } -> - totalHours = Num.toI64 hour + hours - totalMinutes = Num.toI64 minute + minutes + totalHours = Num.toI64 hour + (hours % 24 + minutes // 60) + totalMinutes = Num.toI64 minute + minutes % 60 create { hours: totalHours, minutes: totalMinutes } subtract : Clock, { hours ? I64, minutes ? I64 }* -> Clock subtract = \clock, { hours ? 0, minutes ? 0 } -> - clock |> add { hours: -hours, minutes: -minutes } + clock |> add { hours: -(hours % 24 + minutes // 60), minutes: -(minutes % 60) } diff --git a/exercises/practice/clock/.meta/additional_tests.json b/exercises/practice/clock/.meta/additional_tests.json new file mode 100644 index 0000000..198806d --- /dev/null +++ b/exercises/practice/clock/.meta/additional_tests.json @@ -0,0 +1,62 @@ +{ + "cases": [ + { + "description": "Can create a clock with max I64 values", + "property": "create", + "input": { + "hour": 9223372036854775807, + "minute": 9223372036854775807 + }, + "expected": "01:07" + }, + { + "description": "Can create a clock with min I64 values", + "property": "create", + "input": { + "hour": -9223372036854775808, + "minute": -9223372036854775808 + }, + "expected": "21:52" + }, + { + "description": "Can add max I64 values to a clock", + "property": "add", + "input": { + "hour": 23, + "minute": 59, + "value": 9223372036854775807 + }, + "expected": "18:06" + }, + { + "description": "Can add min I64 values to a clock", + "property": "add", + "input": { + "hour": 23, + "minute": 59, + "value": -9223372036854775808 + }, + "expected": "05:51" + }, + { + "description": "Can subtract max I64 values from a clock", + "property": "subtract", + "input": { + "hour": 23, + "minute": 59, + "value": 9223372036854775807 + }, + "expected": "05:52" + }, + { + "description": "Can subtract min I64 values from a clock", + "property": "subtract", + "input": { + "hour": 23, + "minute": 59, + "value": -9223372036854775808 + }, + "expected": "18:07" + } + ] +} diff --git a/exercises/practice/clock/.meta/template.j2 b/exercises/practice/clock/.meta/template.j2 index af54a29..c0d66b4 100644 --- a/exercises/practice/clock/.meta/template.j2 +++ b/exercises/practice/clock/.meta/template.j2 @@ -4,13 +4,9 @@ import {{ exercise | to_pascal }} exposing [create, add, subtract, toStr] -{% for supercase in cases %} -## -## {{ supercase["description"] }} -## - -{% for case in supercase["cases"] -%} +{% macro test_case(case) %} # {{ case["description"] }} + {%- if case["property"] == "create" %} expect clock = create {{ plugins.to_hours_minutes_record(case["input"]) }} @@ -33,6 +29,22 @@ expect # this test case is not implemented yet. Perhaps you can give it a try? {%- endif %} +{% endmacro %} + +{% for supercase in cases %} +## +## {{ supercase["description"] }} +## + +{% for case in supercase["cases"] -%} +{{ test_case(case) }} {% endfor %} {% endfor %} +## +## Extreme I64 values should not crash with overflow errors +## + +{% for case in additional_cases -%} +{{ test_case(case) }} +{% endfor %} diff --git a/exercises/practice/clock/clock-test.roc b/exercises/practice/clock/clock-test.roc index 6cf7e20..71d91a1 100644 --- a/exercises/practice/clock/clock-test.roc +++ b/exercises/practice/clock/clock-test.roc @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/clock/canonical-data.json -# File last updated on 2024-09-11 +# File last updated on 2024-10-13 app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.15.0/SlwdbJ-3GR7uBWQo6zlmYWNYOxnvo8r6YABXD-45UOw.tar.br", } @@ -374,3 +374,49 @@ expect clock2 = create {} clock1 == clock2 +## +## Extreme I64 values should not crash with overflow errors +## + +# Can create a clock with max I64 values +expect + clock = create { hours: 9223372036854775807, minutes: 9223372036854775807 } + result = clock |> toStr + expected = "01:07" + result == expected + +# Can create a clock with min I64 values +expect + clock = create { hours: -9223372036854775808, minutes: -9223372036854775808 } + result = clock |> toStr + expected = "21:52" + result == expected + +# Can add max I64 values to a clock +expect + clock = create { hours: 23, minutes: 59 } + result = clock |> add { minutes: 9223372036854775807 } |> toStr + expected = "18:06" + result == expected + +# Can add min I64 values to a clock +expect + clock = create { hours: 23, minutes: 59 } + result = clock |> add { minutes: -9223372036854775808 } |> toStr + expected = "05:51" + result == expected + +# Can subtract max I64 values from a clock +expect + clock = create { hours: 23, minutes: 59 } + result = clock |> subtract { minutes: 9223372036854775807 } |> toStr + expected = "05:52" + result == expected + +# Can subtract min I64 values from a clock +expect + clock = create { hours: 23, minutes: 59 } + result = clock |> subtract { minutes: -9223372036854775808 } |> toStr + expected = "18:07" + result == expected +