Initial work done on part 2, but I'm not sure I'll keep the method I'm using. I might have to refactor it out into a function so that it can be called with any particular direction so that when I'm testing potential pathways I can change directions, too.
This commit is contained in:
parent
f9c90b42de
commit
86476f7ff0
134
2024/6/main.cpp
134
2024/6/main.cpp
@ -8,12 +8,6 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
struct Position {
|
|
||||||
// NOTE(dev): Could do enum empty/reached/blocked, but I'm not interested.
|
|
||||||
bool blocked = false;
|
|
||||||
bool reached = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Direction {
|
enum Direction {
|
||||||
UP = 0,
|
UP = 0,
|
||||||
RIGHT,
|
RIGHT,
|
||||||
@ -21,6 +15,36 @@ enum Direction {
|
|||||||
LEFT
|
LEFT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Position {
|
||||||
|
// NOTE(dev): Could do enum empty/reached/blocked, but I'm not interested.
|
||||||
|
bool blocked = false;
|
||||||
|
std::map<Direction, bool> reached;
|
||||||
|
|
||||||
|
bool Reached() const {
|
||||||
|
return reached.size();
|
||||||
|
}
|
||||||
|
char ReachedChar() const {
|
||||||
|
bool up_or_down = false;
|
||||||
|
bool left_or_right = false;
|
||||||
|
if(reached.contains(Direction::UP) || reached.contains(Direction::DOWN))
|
||||||
|
up_or_down = true;
|
||||||
|
if(reached.contains(Direction::LEFT) || reached.contains(Direction::RIGHT))
|
||||||
|
left_or_right = true;
|
||||||
|
|
||||||
|
if(up_or_down != left_or_right)
|
||||||
|
{
|
||||||
|
if(up_or_down)
|
||||||
|
return '|';
|
||||||
|
else
|
||||||
|
return '-';
|
||||||
|
}
|
||||||
|
else if(up_or_down)
|
||||||
|
return '+';
|
||||||
|
else
|
||||||
|
return ' ';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
struct Player {
|
struct Player {
|
||||||
std::pair<int, int> location;
|
std::pair<int, int> location;
|
||||||
Direction direction = Direction::UP;
|
Direction direction = Direction::UP;
|
||||||
@ -28,7 +52,7 @@ struct Player {
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
const std::string filename = "data.txt";
|
const std::string filename = "data_test.txt";
|
||||||
std::ifstream ifs(filename);
|
std::ifstream ifs(filename);
|
||||||
if(!ifs.is_open())
|
if(!ifs.is_open())
|
||||||
{
|
{
|
||||||
@ -75,8 +99,8 @@ int main()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
const auto &pos = level[{x, y}];
|
const auto &pos = level[{x, y}];
|
||||||
if(pos.reached)
|
if(pos.Reached())
|
||||||
std::cout << "X";
|
std::cout << pos.ReachedChar();
|
||||||
else if(pos.blocked)
|
else if(pos.blocked)
|
||||||
std::cout << "#";
|
std::cout << "#";
|
||||||
else
|
else
|
||||||
@ -85,6 +109,9 @@ int main()
|
|||||||
}
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << "PT2 Total: " << total_pt2 << std::endl;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Parse Input
|
// Parse Input
|
||||||
@ -101,7 +128,7 @@ int main()
|
|||||||
pos.blocked = true;
|
pos.blocked = true;
|
||||||
if(value == '^') // always up?
|
if(value == '^') // always up?
|
||||||
{
|
{
|
||||||
pos.reached = true;
|
pos.reached[Direction::UP] = true;
|
||||||
player.location = {x, y};
|
player.location = {x, y};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,8 +150,6 @@ int main()
|
|||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
// while(player.location.first >= 0 && player.location.first < max_x &&
|
|
||||||
// player.location.second >= 0 && player.location.second < max_y)
|
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
std::pair<int, int> next_location = player.location;
|
std::pair<int, int> next_location = player.location;
|
||||||
@ -150,13 +175,90 @@ int main()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(level[next_location].blocked)
|
if(level[next_location].blocked)
|
||||||
|
{
|
||||||
|
// NOTE(dev): Also check if the next potential position is the last space before a turn,
|
||||||
|
// as then the up/down or left/right flag wouldn't be set, but the
|
||||||
|
// left/right or up/down flag would be.
|
||||||
|
level[player.location].reached[player.direction] = true;
|
||||||
player.direction = static_cast<Direction>(((int(player.direction)) + 1) % 4);
|
player.direction = static_cast<Direction>(((int(player.direction)) + 1) % 4);
|
||||||
|
level[player.location].reached[player.direction] = true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
level[next_location].reached = true;
|
// TODO(dev): Need to handle the scenario where you've yet to explore a section but it
|
||||||
|
// would result in a loop.
|
||||||
|
// e.g.: Placing a stopping point at the O
|
||||||
|
//
|
||||||
|
// # #
|
||||||
|
// +->O #
|
||||||
|
// #| #
|
||||||
|
// S # #
|
||||||
|
// # #
|
||||||
|
// # #
|
||||||
|
//
|
||||||
|
// IDEA: Follow turns when exploring a direction like that. Snake your way until
|
||||||
|
// you fall off the map or you line up with a square you've been in before
|
||||||
|
std::map<Direction, bool> could_loop;
|
||||||
|
// Part 2: If you could loop in this next position, COUNT IT
|
||||||
|
if(player.direction == Direction::DOWN)
|
||||||
|
{
|
||||||
|
// search left of new position to see if you've been in this horizontal bit:
|
||||||
|
for(int x = next_location.first; x >= 0; --x)
|
||||||
|
{
|
||||||
|
std::pair<int,int> potential_position = { x, next_location.second };
|
||||||
|
if(level[potential_position].reached.contains(Direction::LEFT))
|
||||||
|
{
|
||||||
|
could_loop[Direction::LEFT] = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(player.direction == Direction::UP)
|
||||||
|
{
|
||||||
|
// search right of new position to see if you've been in this horizontal bit:
|
||||||
|
for(int x = next_location.first; x < max_x; ++x)
|
||||||
|
{
|
||||||
|
std::pair<int,int> potential_position = { x, next_location.second };
|
||||||
|
if(level[potential_position].reached.contains(Direction::RIGHT))
|
||||||
|
{
|
||||||
|
could_loop[Direction::RIGHT] = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(player.direction == Direction::LEFT)
|
||||||
|
{
|
||||||
|
// search left of new position to see if you've been in this horizontal bit:
|
||||||
|
for(int y = next_location.second; y >= 0; --y)
|
||||||
|
{
|
||||||
|
std::pair<int,int> potential_position = { next_location.first, y };
|
||||||
|
if(level[potential_position].reached.contains(Direction::UP))
|
||||||
|
{
|
||||||
|
could_loop[Direction::UP] = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// search left of new position to see if you've been in this horizontal bit:
|
||||||
|
for(int y = next_location.second; y < max_y; ++y)
|
||||||
|
{
|
||||||
|
std::pair<int,int> potential_position = { next_location.first, y };
|
||||||
|
if(level[potential_position].reached.contains(Direction::DOWN))
|
||||||
|
{
|
||||||
|
could_loop[Direction::DOWN] = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
total_pt2 += could_loop.size();
|
||||||
|
|
||||||
|
level[next_location].reached[player.direction] = true;
|
||||||
player.location = next_location;
|
player.location = next_location;
|
||||||
// DebugPrint();
|
|
||||||
// usleep(20000);
|
DebugPrint();
|
||||||
|
usleep(500000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +266,7 @@ int main()
|
|||||||
|
|
||||||
for(auto y = 0; y < max_y; ++y)
|
for(auto y = 0; y < max_y; ++y)
|
||||||
for(auto x = 0; x < max_x; ++x)
|
for(auto x = 0; x < max_x; ++x)
|
||||||
if(level[{x,y}].reached)
|
if(level[{x,y}].Reached())
|
||||||
++total;
|
++total;
|
||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
Loading…
Reference in New Issue
Block a user