diff --git a/2024/answer_tests/day14/example1.txt b/2024/answer_tests/day14/example1.txt new file mode 100644 index 0000000..1edbdf3 --- /dev/null +++ b/2024/answer_tests/day14/example1.txt @@ -0,0 +1,2 @@ +Day 14: +12 diff --git a/2024/input/day14/example1.txt b/2024/input/day14/example1.txt new file mode 100644 index 0000000..2455da4 --- /dev/null +++ b/2024/input/day14/example1.txt @@ -0,0 +1,12 @@ +p=0,4 v=3,-3 +p=6,3 v=-1,-3 +p=10,3 v=-1,2 +p=2,0 v=2,-1 +p=0,0 v=1,3 +p=3,0 v=-2,-2 +p=7,6 v=-1,-3 +p=3,0 v=-1,-2 +p=9,3 v=2,3 +p=7,3 v=-1,2 +p=2,4 v=2,-3 +p=9,5 v=-3,-3 diff --git a/2024/src/day14.cpp b/2024/src/day14.cpp new file mode 100644 index 0000000..794c003 --- /dev/null +++ b/2024/src/day14.cpp @@ -0,0 +1,30 @@ +/****************************************************************************** + * File: day14.cpp + * + * Author: Eric T. Johnson (yut23) + * Created: 2024-12-14 + *****************************************************************************/ + +#include "day14.hpp" +#include "lib.hpp" +#include // for ifstream +#include // for cout + +int main(int argc, char **argv) { + std::ifstream infile = aoc::parse_args(argc, argv); + const bool is_example = + std::string{argv[1]}.find("example") != std::string::npos; + aoc::Pos bounds = is_example ? aoc::Pos{11, 7} : aoc::Pos{101, 103}; + + auto robots = aoc::day14::read_input(infile); + + for (int time = 0; time < 100; ++time) { + for (auto &robot : robots) { + robot.update(bounds); + } + } + + std::cout << aoc::day14::safety_factor(robots, bounds) << "\n"; + + return 0; +} diff --git a/2024/src/day14.hpp b/2024/src/day14.hpp new file mode 100644 index 0000000..4c003f4 --- /dev/null +++ b/2024/src/day14.hpp @@ -0,0 +1,82 @@ +/****************************************************************************** + * File: day14.hpp + * + * Author: Eric T. Johnson (yut23) + * Created: 2024-12-14 + *****************************************************************************/ + +#ifndef DAY14_HPP_5W9MWUPG +#define DAY14_HPP_5W9MWUPG + +#include "lib.hpp" // for Pos, Delta, expect_input +#include // for array +#include // for istream +#include // for string, getline +#include // for move +#include // for vector + +namespace aoc::day14 { + +struct Robot { + Pos pos{0, 0}; + Delta vel{0, 0}; + + void update(const Pos &bounds); +}; + +std::istream &operator>>(std::istream &is, Robot &robot) { + is >> std::noskipws; + is >> aoc::expect_input("p=") >> robot.pos.x >> aoc::expect_input(',') >> + robot.pos.y >> aoc::expect_input(" v=") >> robot.vel.dx >> + aoc::expect_input(',') >> robot.vel.dy; + is >> std::ws; + return is; +} + +auto read_input(std::istream &is) { + Robot robot; + std::vector robots; + while (is >> robot) { + robots.push_back(std::move(robot)); + } + return robots; +} + +void Robot::update(const Pos &bounds) { + pos += vel; + if (pos.x < 0) { + pos.x += bounds.x; + } else if (pos.x >= bounds.x) { + pos.x -= bounds.x; + } + if (pos.y < 0) { + pos.y += bounds.y; + } else if (pos.y >= bounds.y) { + pos.y -= bounds.y; + } +} + +int safety_factor(const std::vector &robots, const Pos &bounds) { + std::array quadrants{}; + for (const auto &robot : robots) { + int quad_idx = 0; + if (robot.pos.x == bounds.x / 2 || robot.pos.y == bounds.y / 2) { + // robot is exactly in the middle, so it doesn't count for any + // quadrant + continue; + } + if (robot.pos.x > bounds.x / 2) { + quad_idx |= 1; + } + if (robot.pos.y > bounds.y / 2) { + quad_idx |= 2; + } + ++quadrants[quad_idx]; + } + + return quadrants[0] * quadrants[1] * quadrants[2] * quadrants[3]; +} + +} // namespace aoc::day14 + +#endif /* end of include guard: DAY14_HPP_5W9MWUPG */