You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
AoC2022_Day12/main.cpp

148 lines
4.6 KiB

#include <vector>
#include <fstream>
#include <iostream>
#include <cmath>
struct vi2d{
int x,y;
friend std::ostream&operator<<(std::ostream&out,vi2d&rhs){
out<<"("<<rhs.x<<","<<rhs.y<<")";
return out;
}
};
struct node{
private:
char elevation='a';
public:
bool visited=false;
std::vector<node*>connections;
int myDist=INFINITY;
vi2d pos;
node*parent=nullptr;
node(char elevation){
this->elevation=elevation;
};
char getElevation(){
return elevation=='S'?'a':elevation=='E'?'z'+1:elevation;
}
};
vi2d playerPos={0,0};
vi2d endingPos={0,0};
std::vector<std::vector<node>>grid;
std::vector<node*>possibleStartingLocs;
node*startNode;
node *endNode;
int main()
{
std::ifstream file("input");
while (file.good()){
std::string line;
std::getline(file,line);
std::vector<node>row;
if (line.length()>0){
for (int x=0;x<line.length();x++){
row.push_back(node(line[x]));
if (line[x]=='S'){
playerPos={x,(int)grid.size()};
}
if (line[x]=='E'){
endingPos={x,(int)grid.size()};
}
}
grid.push_back(row);
}
}
std::cout<<"================"<<std::endl;
for (int y=0;y<grid.size();y++){
for (int x=0;x<grid[y].size();x++){
std::cout<<grid[y][x].getElevation();
grid[y][x].pos={x,y};
if (grid[y][x].getElevation()=='a'){
possibleStartingLocs.push_back(&grid[y][x]);
}
if (x>0&&grid[y][x-1].getElevation()-1<=grid[y][x].getElevation()){
grid[y][x].connections.push_back(&grid[y][x-1]);
}
if (x<grid[y].size()-1&&grid[y][x+1].getElevation()-1<=grid[y][x].getElevation()){
grid[y][x].connections.push_back(&grid[y][x+1]);
}
if (y>0&&grid[y-1][x].getElevation()-1<=grid[y][x].getElevation()){
grid[y][x].connections.push_back(&grid[y-1][x]);
}
if (y<grid.size()-1&&grid[y+1][x].getElevation()-1<=grid[y][x].getElevation()){
grid[y][x].connections.push_back(&grid[y+1][x]);
}
if (x==playerPos.x&&y==playerPos.y){
startNode=&grid[y][x];
//std::cout<<"Starting node set."<<std::endl;
}
if (x==endingPos.x&&y==endingPos.y){
endNode = &grid[y][x];
//std::cout << "Ending node set." << std::endl;
}
}
std::cout<<std::endl;
}
int bestPath=INFINITY;
node*testNode;
for (int l=0;l<possibleStartingLocs.size();l++){
testNode=possibleStartingLocs[l];
//std::cout<<"Checking location: "<<testNode->pos<<std::endl;
for (int y=0;y<grid.size();y++){
for (int x=0;x<grid[y].size();x++){
node&n=grid[y][x];
n.visited=false;
n.myDist=INFINITY;
n.parent=nullptr;
}
}
std::vector<node*>searchNodes;
searchNodes.push_back(testNode);
testNode->myDist=0.0f;
while (searchNodes.size()>0){
node*currentNode=searchNodes.front();
if (currentNode->visited){
searchNodes.erase(searchNodes.begin());
continue;
}
currentNode->visited=true;
for (int i=0;i<currentNode->connections.size();i++){
node*neighbor=currentNode->connections[i];
if (!neighbor->visited){
searchNodes.push_back(neighbor);
}
float lowerGoal=currentNode->myDist+pow(neighbor->pos.x-currentNode->pos.x,2)+pow(neighbor->pos.y-currentNode->pos.y,2);
if (lowerGoal<neighbor->myDist){
neighbor->parent=currentNode;
neighbor->myDist=lowerGoal;
}
}
}
node *searchNode = endNode;
bool completed=false;
int jumps=0;
while (searchNode!=testNode){
if (searchNode->parent!=nullptr){
//std::cout<<"Node goes from "<<searchNode->pos<<" to "<<searchNode->parent->pos<<std::endl;
jumps++;
searchNode=searchNode->parent;
}else{
break;
}
}
if (searchNode==testNode){
if (jumps<bestPath){
std::cout<<"New Shortest path is "<<jumps<<" hops"<<std::endl;
bestPath=jumps;
}
}
}
return 0;
}