diff --git a/2021/README.md b/2021/README.md index bd87d34..773572d 100644 --- a/2021/README.md +++ b/2021/README.md @@ -20,7 +20,7 @@ | 14 | ✓ | ✓ | [Erlang] | | 15 | ✓ | ✓ | [D] | | 16 | ✓ | ✓ | [Haskell] | -| 17 | | | | +| 17 | ✓ | ✓ | [Dart] | | 18 | | | | | 19 | | | | | 20 | | | | @@ -52,3 +52,5 @@ [erlang]: https://www.erlang.org [d]: https://dlang.org [haskell]: https://www.haskell.org +[dart]: https://dart.dev +[elixir]: https://elixir-lang.org diff --git a/2021/day-17/Justfile b/2021/day-17/Justfile new file mode 100644 index 0000000..23f0e73 --- /dev/null +++ b/2021/day-17/Justfile @@ -0,0 +1,2 @@ +@part PART INPUT_FILE="inputs/puzzle.txt": + dart part_{{PART}}.dart {{INPUT_FILE}} diff --git a/2021/day-17/common.dart b/2021/day-17/common.dart new file mode 100644 index 0000000..e97b692 --- /dev/null +++ b/2021/day-17/common.dart @@ -0,0 +1,79 @@ +import "dart:io"; +import "dart:math"; + +List> parseFile(String path) { + final file = File(path); + + final content = file.readAsStringSync(); + + final coordinates = content + .trim().split(" ") + .skip(2).where((e) => e.isNotEmpty) + .map((elem) { + return elem + .split("=").last + .replaceFirst(",", "").split("..") + .map(int.parse) + .toList(); + }) + .toList(); + + return coordinates; +} + +List step(int x, int y, int xv, int yv) { + final dx = x + xv; + final dy = y + yv; + final dxv = xv + (xv > 0 ? -1 : (xv < 0 ? 1 : 0)); + final dyv = yv - 1; + return [dx, dy, dxv, dyv]; +} + +bool hasMissed(int x, int y, List> area) { + var missed = (x - area[0][1]) > 0; + return missed || (y - area[1][0]) < 0; +} + +bool isInTargetArea(int x, int y, List> area) { + return + x >= area[0][0] && + x <= area[0][1] && + y >= area[1][0] && + y <= area[1][1]; +} + +bool landsInTargetArea(int init_vx, int init_vy, List> area) { + var x = 0; + var y = 0; + var vx = init_vx; + var vy = init_vy; + + while (true) { + final result = step(x, y, vx, vy); + if (isInTargetArea(result[0], result[1], area)) return true; + if (hasMissed(result[0], result[1], area)) return false; + x = result[0]; + y = result[1]; + vx = result[2]; + vy = result[3]; + } +} + +int? findMaxHeight(int init_vx, int init_vy, List> area) { + var x = 0; + var y = 0; + var vx = init_vx; + var vy = init_vy; + var max_height = 0; + + while (true) { + final result = step(x, y, vx, vy); + max_height = max(result[1], max_height); + if (isInTargetArea(result[0], result[1], area)) return max_height; + if (hasMissed(result[0], result[1], area)) return null; + x = result[0]; + y = result[1]; + vx = result[2]; + vy = result[3]; + } +} diff --git a/2021/day-17/inputs/puzzle.txt b/2021/day-17/inputs/puzzle.txt new file mode 100644 index 0000000..ba5668c --- /dev/null +++ b/2021/day-17/inputs/puzzle.txt @@ -0,0 +1 @@ +target area: x=277..318, y=-92..-53 diff --git a/2021/day-17/inputs/sample1.txt b/2021/day-17/inputs/sample1.txt new file mode 100644 index 0000000..a07e02d --- /dev/null +++ b/2021/day-17/inputs/sample1.txt @@ -0,0 +1 @@ +target area: x=20..30, y=-10..-5 diff --git a/2021/day-17/part_one.dart b/2021/day-17/part_one.dart new file mode 100644 index 0000000..88cd4b0 --- /dev/null +++ b/2021/day-17/part_one.dart @@ -0,0 +1,23 @@ +import "dart:math"; +import "common.dart"; + +main(List args) { + final path = args.first; + + final target_area = parseFile(path); + + final max_xv = target_area[0][1]; + final max_yv = target_area[1][0].abs(); + var max_height = 0; + + Iterable.generate(max_xv, (v) => v + 1).forEach((x) { + Iterable.generate(max_yv, (v) => v + 1).forEach((y) { + final result = findMaxHeight(x, y, target_area); + if (result != null) { + max_height = max(result, max_height); + } + }); + }); + + print(max_height); +} diff --git a/2021/day-17/part_two.dart b/2021/day-17/part_two.dart new file mode 100644 index 0000000..180501e --- /dev/null +++ b/2021/day-17/part_two.dart @@ -0,0 +1,30 @@ +import "dart:math"; +import "common.dart"; + +main(List args) { + final path = args.first; + + final target_area = parseFile(path); + + final max_xv = target_area[0][1]; + final max_yv = target_area[1][0]; + var velocity_count = 0; + + var yv = max_yv; + + while (yv < max_yv.abs()) { + var xv = max_xv; + + while (xv > 0) { + if (landsInTargetArea(xv, yv, target_area)) { + velocity_count += 1; + } + + xv -= 1; + } + + yv += 1; + } + + print(velocity_count); +} diff --git a/README.md b/README.md index bc5058c..410017f 100644 --- a/README.md +++ b/README.md @@ -8,4 +8,4 @@ - [2018](2018/README.md) (0% completed) - [2019](2019/README.md) (0% completed) - [2020](2020/README.md) (20% completed) -- [2021](2021/README.md) (64% completed) +- [2021](2021/README.md) (68% completed)