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:
		
							
								
								
									
										134
									
								
								2024/6/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										134
									
								
								2024/6/main.cpp
									
									
									
									
									
								
							@@ -8,12 +8,6 @@
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#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 {
 | 
			
		||||
	UP = 0,
 | 
			
		||||
	RIGHT,
 | 
			
		||||
@@ -21,6 +15,36 @@ enum Direction {
 | 
			
		||||
	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 {
 | 
			
		||||
	std::pair<int, int> location;
 | 
			
		||||
	Direction direction = Direction::UP;
 | 
			
		||||
@@ -28,7 +52,7 @@ struct Player {
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
	const std::string filename = "data.txt";
 | 
			
		||||
	const std::string filename = "data_test.txt";
 | 
			
		||||
	std::ifstream ifs(filename);
 | 
			
		||||
	if(!ifs.is_open())
 | 
			
		||||
	{
 | 
			
		||||
@@ -75,8 +99,8 @@ int main()
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					const auto &pos = level[{x, y}];
 | 
			
		||||
					if(pos.reached)
 | 
			
		||||
						std::cout << "X";
 | 
			
		||||
					if(pos.Reached())
 | 
			
		||||
						std::cout << pos.ReachedChar();
 | 
			
		||||
					else if(pos.blocked)
 | 
			
		||||
						std::cout << "#";
 | 
			
		||||
					else
 | 
			
		||||
@@ -85,6 +109,9 @@ int main()
 | 
			
		||||
			}
 | 
			
		||||
			std::cout << std::endl;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		std::cout << std::endl;
 | 
			
		||||
		std::cout << "PT2 Total: " << total_pt2 << std::endl;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	// Parse Input
 | 
			
		||||
@@ -101,7 +128,7 @@ int main()
 | 
			
		||||
				pos.blocked = true;
 | 
			
		||||
			if(value == '^') // always up?
 | 
			
		||||
			{
 | 
			
		||||
				pos.reached = true;
 | 
			
		||||
				pos.reached[Direction::UP] = true;
 | 
			
		||||
				player.location = {x, y};
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@@ -123,8 +150,6 @@ int main()
 | 
			
		||||
 | 
			
		||||
	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)
 | 
			
		||||
	{
 | 
			
		||||
		std::pair<int, int> next_location = player.location;
 | 
			
		||||
@@ -150,13 +175,90 @@ int main()
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		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);
 | 
			
		||||
			level[player.location].reached[player.direction] = true;
 | 
			
		||||
		}
 | 
			
		||||
		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;
 | 
			
		||||
			// DebugPrint();
 | 
			
		||||
			// usleep(20000);
 | 
			
		||||
 | 
			
		||||
			DebugPrint();
 | 
			
		||||
			usleep(500000);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -164,7 +266,7 @@ int main()
 | 
			
		||||
 | 
			
		||||
	for(auto y = 0; y < max_y; ++y)
 | 
			
		||||
		for(auto x = 0; x < max_x; ++x)
 | 
			
		||||
			if(level[{x,y}].reached)
 | 
			
		||||
			if(level[{x,y}].Reached())
 | 
			
		||||
				++total;
 | 
			
		||||
 | 
			
		||||
	std::cout << std::endl;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user