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_Day22/main.cpp

251 lines
9.2 KiB

#define OLC_PGE_APPLICATION
#include "pixelGameEngine.h"
#include "olcutils.h"
using namespace olc;
enum Direction{
RIGHT,
DOWN,
LEFT,
UP
};
struct Instruction{
int number=-1;
Direction turn;
};
int main()
{
std::vector<std::vector<char>>map;
std::vector<Instruction>instructions;
std::vector<vi2d>visitedLocs;
std::ifstream file("input");
while (file.good()){
std::string line;
std::getline(file,line);
if (line.length()>0){
if (line[0]=='.'||line[0]==' '||line[0]=='#'){
std::vector<char>mapRow;
for (int i=0;i<line.length();i++){
mapRow.push_back(line[i]);
}
map.push_back(mapRow);
} else {
//Parse the instruction set.
bool isNumber=true;
int marker=0;
while(marker<line.length()){
if (isNumber){
std::string acc="";
while (line[marker]>='0'&&line[marker]<='9'){
acc+=line[marker++];
}
instructions.push_back({std::atoi(acc.c_str())});
isNumber=false;
} else {
switch(line[marker++]){
case 'R':{
instructions.push_back({-1,Direction::RIGHT});
}break;
case 'L':{
instructions.push_back({-1,Direction::LEFT});
}break;
}
isNumber=true;
}
}
}
}
}
for (int y=0;y<map.size();y++){
for (int x=0;x<map[y].size();x++){
std::cout<<map[y][x];
}
std::cout<<std::endl;
}
std::cout<<"============="<<std::endl;
for (int i=0;i<instructions.size();i++){
if (instructions[i].number==-1){
if (instructions[i].turn==Direction::RIGHT){
std::cout<<'R';
} else {
std::cout<<'L';
}
} else {
std::cout<<instructions[i].number;
}
}
std::cout<<std::endl;
vi2d pos={0,0};
for (int i=0;i<map[0].size();i++){
if (map[0][i]!=' '){
pos={i,0};
}
}
int instructionMarker=0;
Direction facingDir=Direction::RIGHT;
while (instructionMarker<instructions.size()){
Instruction&instruction=instructions[instructionMarker];
if (instruction.number!=-1){
std::cout<<"Moving "<<instruction.number<<" steps"<<std::endl;
int steps=instruction.number;
while (steps>0){
switch (facingDir){
case Direction::RIGHT:{
char tile=' ';
vi2d targetPos={pos.x+1,pos.y};
if (pos.x+1>=map[pos.y].size()){
for (int i=0;i<map[pos.y].size();i++){
if (map[pos.y][i]=='.'){
targetPos.x=i;
break;
} else
if (map[pos.y][i]=='#'){
//It's a dead end so we can't move. Go next.
goto next;
}
}
}
tile=map[targetPos.y][targetPos.x];
switch (tile){
case '.':{
pos=targetPos;
visitedLocs.push_back(pos);
}break;
case '#':{
goto next;
}break;
case ' ':{
//Impossible when going right.
}break;
}
}break;
case Direction::LEFT:{
char tile=' ';
vi2d targetPos={pos.x-1,pos.y};
if (pos.x-1<0||map[pos.y][pos.x-1]==' '){
if (map[pos.y][map[pos.y].size()-1]=='.'){
targetPos.x=map[pos.y].size()-1;
} else
if (map[pos.y][map[pos.y].size()-1]=='#'){
//It's a dead end so we can't move. Go next.
goto next;
}
}
tile=map[targetPos.y][targetPos.x];
switch (tile){
case '.':{
pos=targetPos;
visitedLocs.push_back(pos);
}break;
case '#':{
goto next;
}break;
case ' ':{
//Impossible when going right.
}break;
}
}break;
case Direction::UP:{
char tile=' ';
vi2d targetPos={pos.x,pos.y-1};
if (pos.y-1<0||map[pos.y-1][pos.x]==' '){
for (int y=map.size()-1;y>0;y--){
if (map[y].size()>pos.x){
if (map[y][pos.x]=='.'){
targetPos.y=y;
break;
}else
if (map[y][pos.x]=='#'){
goto next;
}
}
}
}
tile=map[targetPos.y][targetPos.x];
switch (tile){
case '.':{
pos=targetPos;
visitedLocs.push_back(pos);
}break;
case '#':{
goto next;
}break;
case ' ':{
//Impossible when going right.
}break;
}
}break;
case Direction::DOWN:{
char tile=' ';
vi2d targetPos={pos.x,pos.y+1};
if (pos.y+1>=map.size()||map[pos.y+1].size()<=pos.x||map[pos.y+1][pos.x]==' '){
for (int y=0;y<map.size();y++){
if (map[y].size()>pos.x){
if (map[y][pos.x]=='.'){
std::cout<<"Found a spot. ("<<y<<")"<<std::endl;
targetPos.y=y;
break;
}else
if (map[y][pos.x]=='#'){
std::cout<<"Found a dead end. ("<<y<<")"<<std::endl;
goto next;
}
}
}
}
tile=map[targetPos.y][targetPos.x];
switch (tile){
case '.':{
pos=targetPos;
visitedLocs.push_back(pos);
}break;
case '#':{
goto next;
}break;
case ' ':{
}break;
}
}break;
}
steps--;
}
} else {
if (instruction.turn==Direction::RIGHT){
facingDir=(Direction)((facingDir+1)%4);
} else {
int dir = facingDir-1;
if (dir<0){
dir=3;
}
facingDir=(Direction)dir;
}
std::cout<<"Turned "<<(instruction.turn==Direction::RIGHT?"RIGHT":"LEFT")<<" to face "<<facingDir<<std::endl;
}
next:
instructionMarker++;
}
std::cout<<"Final position: "<<pos<<" Dir:"<<facingDir<<std::endl;
std::cout<<"Sum: "<<1000*(pos.y+1)+4*(pos.x+1)+facingDir<<std::endl;
for (int y=0;y<map.size();y++){
for (int x=0;x<map[y].size();x++){
for (int i=0;i<visitedLocs.size();i++){
if (visitedLocs[i].x==x&&visitedLocs[i].y==y){
std::cout<<'+';
goto nextit;
}
}
std::cout<<map[y][x];
nextit:;
}
std::cout<<std::endl;
}
return 0;
}