2017_22
This commit is contained in:
parent
1fd2a6b7ff
commit
9aa821376c
132
2017/22.cpp
Normal file
132
2017/22.cpp
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <iosfwd>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
#include <doctest.h>
|
||||||
|
|
||||||
|
#include <aocpp/Grid.hpp>
|
||||||
|
#include <aocpp/Startup.hpp>
|
||||||
|
#include <aocpp/Coord.hpp>
|
||||||
|
|
||||||
|
auto Part1(aocpp::Grid const &input) -> std::int64_t
|
||||||
|
{
|
||||||
|
std::unordered_set<aocpp::Coord> infected;
|
||||||
|
|
||||||
|
// Initialize set of infected locations
|
||||||
|
input.each([&infected](auto const pos, auto const cell)
|
||||||
|
{
|
||||||
|
if (cell == '#')
|
||||||
|
{
|
||||||
|
infected.insert(pos);
|
||||||
|
} });
|
||||||
|
|
||||||
|
// Start in the middle
|
||||||
|
aocpp::Coord pos;
|
||||||
|
pos.x = input.Cols() / 2;
|
||||||
|
pos.y = input.Rows() / 2;
|
||||||
|
|
||||||
|
// Start going "up"
|
||||||
|
aocpp::Coord vel{.x = 0, .y = -1};
|
||||||
|
|
||||||
|
// Count the number of iterations that cause an infection
|
||||||
|
std::uint64_t infections = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 10'000; ++i)
|
||||||
|
{
|
||||||
|
auto const it = infected.find(pos);
|
||||||
|
if (it == end(infected))
|
||||||
|
{
|
||||||
|
// was clean
|
||||||
|
vel = CCW(vel); // turn "left"
|
||||||
|
infected.insert(pos); // infect
|
||||||
|
infections++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// was infected
|
||||||
|
vel = CW(vel); // turn "right"
|
||||||
|
infected.erase(it); // clean
|
||||||
|
}
|
||||||
|
pos += vel; // advance
|
||||||
|
}
|
||||||
|
|
||||||
|
return infections;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Part2(aocpp::Grid const &input) -> std::int64_t
|
||||||
|
{
|
||||||
|
std::unordered_map<aocpp::Coord, char> cells;
|
||||||
|
|
||||||
|
// Initialize set of infected locations
|
||||||
|
input.each([&cells](auto const pos, auto const cell)
|
||||||
|
{
|
||||||
|
if (cell == '#')
|
||||||
|
{
|
||||||
|
cells.try_emplace(pos, '#');
|
||||||
|
} });
|
||||||
|
|
||||||
|
// Start in the middle
|
||||||
|
aocpp::Coord pos;
|
||||||
|
pos.x = input.Cols() / 2;
|
||||||
|
pos.y = input.Rows() / 2;
|
||||||
|
|
||||||
|
// Start going "up"
|
||||||
|
aocpp::Coord vel{.x = 0, .y = -1};
|
||||||
|
|
||||||
|
// Count the number of iterations that cause an infection
|
||||||
|
std::uint64_t infections = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 10'000'000; ++i)
|
||||||
|
{
|
||||||
|
auto const [it, added] = cells.try_emplace(pos, 'W'); // clean becomes weakened
|
||||||
|
if (added)
|
||||||
|
{
|
||||||
|
// already inserted 'W'
|
||||||
|
vel = CCW(vel); // turn "left"
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (it->second)
|
||||||
|
{
|
||||||
|
case 'W':
|
||||||
|
// no turn
|
||||||
|
it->second = '#';
|
||||||
|
infections++;
|
||||||
|
break;
|
||||||
|
case '#':
|
||||||
|
vel = CW(vel); // turn "right"
|
||||||
|
it->second = 'F';
|
||||||
|
break;
|
||||||
|
case 'F':
|
||||||
|
vel = Turn180(vel);
|
||||||
|
cells.erase(it); // clean
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw std::logic_error{"unexpected cell in steps"};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pos += vel; // advance
|
||||||
|
}
|
||||||
|
|
||||||
|
return infections;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_SUITE("2017-22 examples")
|
||||||
|
{
|
||||||
|
TEST_CASE("part 1")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
TEST_CASE("part 2")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Main(std::istream &in, std::ostream &out) -> void
|
||||||
|
{
|
||||||
|
auto const input = aocpp::Grid::Parse(in);
|
||||||
|
out << "Part 1: " << Part1(input) << std::endl;
|
||||||
|
out << "Part 2: " << Part2(input) << std::endl;
|
||||||
|
}
|
|
@ -33,3 +33,6 @@ target_link_libraries(2017_18 aocpp)
|
||||||
|
|
||||||
add_executable(2017_19 19.cpp)
|
add_executable(2017_19 19.cpp)
|
||||||
target_link_libraries(2017_19 aocpp)
|
target_link_libraries(2017_19 aocpp)
|
||||||
|
|
||||||
|
add_executable(2017_22 22.cpp)
|
||||||
|
target_link_libraries(2017_22 aocpp)
|
||||||
|
|
|
@ -80,6 +80,7 @@ auto operator*=(Coord &, std::int64_t) -> Coord &;
|
||||||
template<>
|
template<>
|
||||||
struct std::hash<aocpp::Coord>
|
struct std::hash<aocpp::Coord>
|
||||||
{
|
{
|
||||||
|
using is_transparent = void;
|
||||||
auto operator()(aocpp::Coord const& c) const noexcept -> std::size_t {
|
auto operator()(aocpp::Coord const& c) const noexcept -> std::size_t {
|
||||||
std::hash<std::int64_t> h;
|
std::hash<std::int64_t> h;
|
||||||
return h(c.x) ^ h(c.y);
|
return h(c.x) ^ h(c.y);
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
#ifndef AOCPP_GRID_HPP_
|
#ifndef AOCPP_GRID_HPP_
|
||||||
#define AOCPP_GRID_HPP_
|
#define AOCPP_GRID_HPP_
|
||||||
|
|
||||||
|
#include <concepts>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
|
||||||
#include <utility>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <aocpp/Coord.hpp>
|
#include <aocpp/Coord.hpp>
|
||||||
|
|
||||||
|
@ -62,8 +63,14 @@ struct Grid {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F>
|
/**
|
||||||
auto each(F f = F{}) const {
|
* @brief Apply the callback function across all elements of the grid.
|
||||||
|
*
|
||||||
|
* @tparam F Type of callback
|
||||||
|
* @param f Callback function
|
||||||
|
*/
|
||||||
|
template <std::invocable<Coord, char> F>
|
||||||
|
auto each(F f = F{}) const -> void {
|
||||||
auto const h = rows.size();
|
auto const h = rows.size();
|
||||||
for (std::size_t y = 0; y < h; y++) {
|
for (std::size_t y = 0; y < h; y++) {
|
||||||
auto const& row = rows[y];
|
auto const& row = rows[y];
|
||||||
|
|
Loading…
Reference in New Issue
Block a user