main
Benjamin Kraft 9 months ago
parent 86120c01a1
commit 1e991c1f77
  1. 222
      src/days/10/Day10.cpp
  2. 28
      src/days/10/Day10.h

@ -1,9 +1,225 @@
#include "Day10.h" #include "Day10.h"
Result Day10::Task1() { Result Day10::Task1() {
return Day::Task1(); Map map = parseMap();
Coord start = getStart();
vector<pair<Coord, vector<Tile>>> neighbours = {
{{start.x + 1, start.y}, {NORTH_WEST, SOUTH_WEST, HORIZONTAL}},
{{start.x - 1, start.y}, {NORTH_EAST, SOUTH_EAST, HORIZONTAL}},
{{start.x, start.y + 1}, {NORTH_WEST, NORTH_EAST, VERTICAL}},
{{start.x, start.y - 1}, {SOUTH_WEST, SOUTH_EAST, VERTICAL}},
};
Coord current {};
for (const auto &[coord, types] : neighbours)
for (const auto &type : types)
if (map.at(coord) == type)
current = coord;
Coord previous = start;
vector<Coord> loop = {start};
while (map.at(current) != START) {
loop.push_back(current);
Coord next = map.next(previous, current);
previous = current;
current = next;
}
size_t distance = loop.size() / 2;
return to_string(distance);
} }
Result Day10::Task2() { Result Day10::Task2() {
return Day::Task2(); Map map = parseMap();
}
Coord start = getStart();
vector<pair<Coord, vector<Tile>>> neighbours = {
{{start.x + 1, start.y}, {NORTH_WEST, SOUTH_WEST, HORIZONTAL}},
{{start.x - 1, start.y}, {NORTH_EAST, SOUTH_EAST, HORIZONTAL}},
{{start.x, start.y + 1}, {NORTH_WEST, NORTH_EAST, VERTICAL}},
{{start.x, start.y - 1}, {SOUTH_WEST, SOUTH_EAST, VERTICAL}},
};
Coord current {};
for (const auto &[coord, types] : neighbours)
for (const auto &type : types)
if (map.at(coord) == type)
current = coord;
Coord previous = start;
vector<Coord> loop = {start};
while (map.at(current) != START) {
loop.push_back(current);
Coord next = map.next(previous, current);
previous = current;
current = next;
}
vector<vector<bool>> mask(map.tiles.size(), vector<bool>(map.tiles[0].size(), false));
for (const Coord &coord : loop)
mask[coord.y][coord.x] = true;
map.replaceStart(loop);
uint64 area = 0;
bool inside = false;
bool edgeEntryFromTop = false;
for (size_t y = 0; y < map.tiles.size(); y++){
for (size_t x = 0; x < map.tiles[0].size(); x++){
if (mask[y][x]){
switch (map.at({x, y})) {
case VERTICAL:
inside = !inside;
break;
case NORTH_EAST:
edgeEntryFromTop = true;
break;
case SOUTH_EAST:
edgeEntryFromTop = false;
break;
case SOUTH_WEST:
if (edgeEntryFromTop)
inside = !inside;
break;
case NORTH_WEST:
if (!edgeEntryFromTop)
inside = !inside;
break;
case HORIZONTAL:
break;
default:
exit(1);
}
} else if (inside)
area++;
}
}
return to_string(area);
}
Day10::Map Day10::parseMap() const {
Map map;
for (const string &line : input){
vector<Tile> row;
for (const char &c : line)
row.push_back(charToTile.at(c));
map.tiles.push_back(row);
}
return map;
}
Day10::Coord Day10::getStart() const {
for (size_t y = 0; y < input.size(); y++)
for (size_t x = 0; x < input[y].size(); x++)
if (input[y][x] == 'S')
return {x, y};
cout << "No Start found!" << endl;
exit(1);
}
Day10::Tile Day10::Map::at(const Day10::Coord &c) const {
if (c.y < 0 || c.y >= tiles.size() ||
c.x < 0 || c.x >= tiles[0].size())
return GROUND;
return tiles[c.y][c.x];
}
Day10::Coord Day10::Map::next(const Day10::Coord &previous, const Day10::Coord &current) const {
auto [c1, c2] = neighbours(current);
if (previous == c1)
return c2;
if (previous == c2)
return c1;
exit(1);
}
void Day10::Map::replaceStart(const vector<Coord> &loop) {
Coord prev = loop.back();
Coord start = loop[0];
Coord next = loop[1];
auto east = Coord({start.x + 1, start.y});
auto west = Coord({start.x - 1, start.y});
auto south = Coord({start.x, start.y + 1});
auto north = Coord({start.x, start.y - 1});
Tile result;
for (size_t i = 2; i < 8; i++){
bool found = false;
Tile tile = Tile(i);
switch (tile) {
case SOUTH_EAST:
found = (prev == east && next == south) || (prev == south && next == east);
break;
case SOUTH_WEST:
found = (prev == west && next == south) || (prev == south && next == west);
break;
case NORTH_EAST:
found = (prev == east && next == north) || (prev == north && next == east);
break;
case NORTH_WEST:
found = (prev == west && next == north) || (prev == north && next == west);
break;
case HORIZONTAL:
found = (prev == east && next == west) || (prev == west && next == east);
break;
case VERTICAL:
found = (prev == south && next == north) || (prev == north && next == south);
break;
default:
exit(1);
}
if (found)
result = tile;
}
tiles[start.y][start.x] = result;
}
pair<Day10::Coord, Day10::Coord> Day10::Map::neighbours(const Day10::Coord &c) const {
Coord c1 {}, c2 {};
switch (at(c)) {
case SOUTH_EAST:
c1 = {c.x, c.y + 1};
c2 = {c.x + 1, c.y};
break;
case SOUTH_WEST:
c1 = {c.x, c.y + 1};
c2 = {c.x - 1, c.y};
break;
case NORTH_EAST:
c1 = {c.x, c.y - 1};
c2 = {c.x + 1, c.y};
break;
case NORTH_WEST:
c1 = {c.x, c.y - 1};
c2 = {c.x - 1, c.y};
break;
case HORIZONTAL:
c1 = {c.x - 1, c.y};
c2 = {c.x + 1, c.y};
break;
case VERTICAL:
c1 = {c.x, c.y - 1};
c2 = {c.x, c.y + 1};
break;
default:
exit(1);
}
return {c1, c2};
}
bool Day10::Coord::operator==(const Day10::Coord &other) const {
return x == other.x && y == other.y;
}

@ -3,6 +3,34 @@
#include "../../Day.h" #include "../../Day.h"
class Day10 : public Day { class Day10 : public Day {
enum Tile {START = 0, GROUND, SOUTH_EAST, SOUTH_WEST, NORTH_EAST, NORTH_WEST, HORIZONTAL, VERTICAL};
map<char, Tile> charToTile = {
{'S', START},
{'.', GROUND},
{'F', SOUTH_EAST},
{'7', SOUTH_WEST},
{'L', NORTH_EAST},
{'J', NORTH_WEST},
{'-', HORIZONTAL},
{'|', VERTICAL},
};
struct Coord {
size_t x;
size_t y;
bool operator ==(const Coord &other) const;
};
struct Map {
vector<vector<Tile>> tiles;
Tile at(const Coord &c) const;
Coord next(const Coord& previous, const Coord &current) const;
pair<Coord, Coord> neighbours(const Coord &c) const;
void replaceStart(const vector<Coord> &loop);
};
Map parseMap() const;
Coord getStart() const;
protected: protected:
Result Task1() override; Result Task1() override;

Loading…
Cancel
Save