|
|
|
#define OLC_PGE_APPLICATION
|
|
|
|
#include "pixelGameEngine.h"
|
|
|
|
#include "olcutils.h"
|
|
|
|
|
|
|
|
using namespace olc;
|
|
|
|
|
|
|
|
const vi2d INVALID={-9999999,-99999999};
|
|
|
|
|
|
|
|
enum Direction{
|
|
|
|
NORTH,
|
|
|
|
EAST,
|
|
|
|
SOUTH,
|
|
|
|
WEST
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Elf{
|
|
|
|
vi2d pos;
|
|
|
|
int orderMarker=0;
|
|
|
|
std::array<Direction,4>orderList={Direction::NORTH,Direction::SOUTH,Direction::WEST,Direction::EAST};
|
|
|
|
vi2d dest=INVALID;
|
|
|
|
};
|
|
|
|
|
|
|
|
vi2d upperLeft={0,0};
|
|
|
|
vi2d lowerRight={0,0};
|
|
|
|
|
|
|
|
std::map<vi2d,Elf>elves;
|
|
|
|
|
|
|
|
int iterations=1;
|
|
|
|
|
|
|
|
int main()
|
|
|
|
{
|
|
|
|
std::ifstream file("input");
|
|
|
|
int y=0;
|
|
|
|
while (file.good()){
|
|
|
|
std::string line;
|
|
|
|
std::getline(file,line);
|
|
|
|
if (line.length()>0){
|
|
|
|
std::cout<<line<<std::endl;
|
|
|
|
for (int i=0;i<line.length();i++){
|
|
|
|
if (line[i]=='#'){
|
|
|
|
elves[{i,y}]={{i,y}};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
lowerRight={(int)line.length()-1,y++};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
std::cout<<elves.size()<<" elves loaded."<<std::endl;
|
|
|
|
while (true){
|
|
|
|
std::map<vi2d,vi2d>plannedMoves;
|
|
|
|
for (std::map<vi2d,Elf>::iterator it=elves.begin();it!=elves.end();++it){
|
|
|
|
Elf&e=elves[it->first];
|
|
|
|
int neighbors=0;
|
|
|
|
for (int x=-1;x<=1;x++){
|
|
|
|
for (int y=-1;y<=1;y++){
|
|
|
|
if (x!=0||y!=0){
|
|
|
|
if (elves.find({x+it->first.x,y+it->first.y})!=elves.end()){
|
|
|
|
neighbors++;
|
|
|
|
goto neighborCheck;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
neighborCheck:
|
|
|
|
if (neighbors>0){
|
|
|
|
for (int j=0;j<e.orderList.size();j++){
|
|
|
|
Direction orderDir=e.orderList[j];
|
|
|
|
switch (orderDir){
|
|
|
|
case NORTH:{
|
|
|
|
if (elves.find({it->first.x,it->first.y-1})==elves.end()&&
|
|
|
|
elves.find({it->first.x-1,it->first.y-1})==elves.end()&&
|
|
|
|
elves.find({it->first.x+1,it->first.y-1})==elves.end()
|
|
|
|
){
|
|
|
|
vi2d dest={it->first.x,it->first.y-1};
|
|
|
|
if (plannedMoves.find(dest)!=plannedMoves.end()){
|
|
|
|
if (elves.find(plannedMoves[dest])==elves.end()){
|
|
|
|
std::cout<<"WARNING! Could not find Elf @"<<plannedMoves[dest]<<std::endl;
|
|
|
|
}
|
|
|
|
elves[plannedMoves[dest]].dest=INVALID;
|
|
|
|
//std::cout<<"Overlap found! Invalidated elves attempting to move to "<<plannedMoves[dest]<<std::endl;
|
|
|
|
} else {
|
|
|
|
plannedMoves[dest]=it->first;
|
|
|
|
e.dest=dest;
|
|
|
|
//std::cout<<"Elf @"<<it->first<<"Plans to move NORTH"<<std::endl;
|
|
|
|
}
|
|
|
|
goto orderComplete;
|
|
|
|
}
|
|
|
|
}break;
|
|
|
|
case SOUTH:{
|
|
|
|
if (elves.find({it->first.x,it->first.y+1})==elves.end()&&
|
|
|
|
elves.find({it->first.x-1,it->first.y+1})==elves.end()&&
|
|
|
|
elves.find({it->first.x+1,it->first.y+1})==elves.end()
|
|
|
|
){
|
|
|
|
vi2d dest={it->first.x,it->first.y+1};
|
|
|
|
if (plannedMoves.find(dest)!=plannedMoves.end()){
|
|
|
|
if (elves.find(plannedMoves[dest])==elves.end()){
|
|
|
|
std::cout<<"WARNING! Could not find Elf @"<<plannedMoves[dest]<<std::endl;
|
|
|
|
}
|
|
|
|
elves[plannedMoves[dest]].dest=INVALID;
|
|
|
|
//std::cout<<"Overlap found! Invalidated elves attempting to move to "<<plannedMoves[dest]<<std::endl;
|
|
|
|
} else {
|
|
|
|
plannedMoves[dest]=it->first;
|
|
|
|
e.dest=dest;
|
|
|
|
//std::cout<<"Elf @"<<it->first<<"Plans to move SOUTH"<<std::endl;
|
|
|
|
}
|
|
|
|
goto orderComplete;
|
|
|
|
}
|
|
|
|
}break;
|
|
|
|
case WEST:{
|
|
|
|
if (elves.find({it->first.x-1,it->first.y})==elves.end()&&
|
|
|
|
elves.find({it->first.x-1,it->first.y-1})==elves.end()&&
|
|
|
|
elves.find({it->first.x-1,it->first.y+1})==elves.end()
|
|
|
|
){
|
|
|
|
vi2d dest={it->first.x-1,it->first.y};
|
|
|
|
if (plannedMoves.find(dest)!=plannedMoves.end()){
|
|
|
|
if (elves.find(plannedMoves[dest])==elves.end()){
|
|
|
|
std::cout<<"WARNING! Could not find Elf @"<<plannedMoves[dest]<<std::endl;
|
|
|
|
}
|
|
|
|
elves[plannedMoves[dest]].dest=INVALID;
|
|
|
|
} else {
|
|
|
|
plannedMoves[dest]=it->first;
|
|
|
|
e.dest=dest;
|
|
|
|
}
|
|
|
|
//std::cout<<"Elf @"<<it->first<<"Plans to move WEST"<<std::endl;
|
|
|
|
goto orderComplete;
|
|
|
|
}
|
|
|
|
}break;
|
|
|
|
case EAST:{
|
|
|
|
if (elves.find({it->first.x+1,it->first.y})==elves.end()&&
|
|
|
|
elves.find({it->first.x+1,it->first.y-1})==elves.end()&&
|
|
|
|
elves.find({it->first.x+1,it->first.y+1})==elves.end()
|
|
|
|
){
|
|
|
|
vi2d dest={it->first.x+1,it->first.y};
|
|
|
|
if (plannedMoves.find(dest)!=plannedMoves.end()){
|
|
|
|
if (elves.find(plannedMoves[dest])==elves.end()){
|
|
|
|
std::cout<<"WARNING! Could not find Elf @"<<plannedMoves[dest]<<std::endl;
|
|
|
|
}
|
|
|
|
elves[plannedMoves[dest]].dest=INVALID;
|
|
|
|
//std::cout<<"Overlap found! Invalidated elves attempting to move to "<<plannedMoves[dest]<<std::endl;
|
|
|
|
} else {
|
|
|
|
plannedMoves[dest]=it->first;
|
|
|
|
e.dest=dest;
|
|
|
|
}
|
|
|
|
//std::cout<<"Elf @"<<it->first<<"Plans to move EAST"<<std::endl;
|
|
|
|
goto orderComplete;
|
|
|
|
}
|
|
|
|
}break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
orderComplete:;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
upperLeft={0,0};
|
|
|
|
lowerRight={0,0};
|
|
|
|
std::map<vi2d,Elf>newElves;
|
|
|
|
bool moved=false;
|
|
|
|
for (std::map<vi2d,Elf>::iterator it=elves.begin();it!=elves.end();++it){
|
|
|
|
Elf&e=elves[it->first];
|
|
|
|
if (e.dest!=INVALID){
|
|
|
|
e.pos=e.dest;
|
|
|
|
if (e.dest.x<upperLeft.x){
|
|
|
|
upperLeft.x=e.dest.x;
|
|
|
|
}
|
|
|
|
if (e.dest.y<upperLeft.y){
|
|
|
|
upperLeft.y=e.dest.y;
|
|
|
|
}
|
|
|
|
if (e.dest.x>lowerRight.x){
|
|
|
|
lowerRight.x=e.dest.x;
|
|
|
|
}
|
|
|
|
if (e.dest.y>lowerRight.y){
|
|
|
|
lowerRight.y=e.dest.y;
|
|
|
|
}
|
|
|
|
e.dest=INVALID;
|
|
|
|
Direction temp=e.orderList[0];
|
|
|
|
for (int j=0;j<e.orderList.size()-1;j++){
|
|
|
|
Direction&dir=e.orderList[j];
|
|
|
|
dir=e.orderList[j+1];
|
|
|
|
}
|
|
|
|
Direction&tempDir=e.orderList[e.orderList.size()-1];
|
|
|
|
tempDir=temp;
|
|
|
|
/*std::cout<<"Next orders: ";
|
|
|
|
for (int j=0;j<e.orderList.size();j++){
|
|
|
|
std::cout<<e.orderList[j];
|
|
|
|
}
|
|
|
|
std::cout<<std::endl;*/
|
|
|
|
moved=true;
|
|
|
|
} else {
|
|
|
|
if (e.pos.x<upperLeft.x){
|
|
|
|
upperLeft.x=e.pos.x;
|
|
|
|
}
|
|
|
|
if (e.pos.y<upperLeft.y){
|
|
|
|
upperLeft.y=e.pos.y;
|
|
|
|
}
|
|
|
|
if (e.pos.x>lowerRight.x){
|
|
|
|
lowerRight.x=e.pos.x;
|
|
|
|
}
|
|
|
|
if (e.pos.y>lowerRight.y){
|
|
|
|
lowerRight.y=e.pos.y;
|
|
|
|
}
|
|
|
|
Direction temp=e.orderList[0];
|
|
|
|
for (int j=0;j<e.orderList.size()-1;j++){
|
|
|
|
Direction&dir=e.orderList[j];
|
|
|
|
dir=e.orderList[j+1];
|
|
|
|
}
|
|
|
|
Direction&tempDir=e.orderList[e.orderList.size()-1];
|
|
|
|
tempDir=temp;
|
|
|
|
/*std::cout<<"Next orders: ";
|
|
|
|
for (int j=0;j<e.orderList.size();j++){
|
|
|
|
std::cout<<e.orderList[j];
|
|
|
|
}
|
|
|
|
std::cout<<std::endl;*/
|
|
|
|
}
|
|
|
|
newElves[e.pos]=e;
|
|
|
|
}
|
|
|
|
|
|
|
|
elves=newElves;
|
|
|
|
if (!moved){
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
iterations++;
|
|
|
|
}
|
|
|
|
for (int y=upperLeft.y;y<=lowerRight.y;y++){
|
|
|
|
for (int x=upperLeft.x;x<=lowerRight.x;x++){
|
|
|
|
if (elves.find({x,y})==elves.end()){
|
|
|
|
std::cout<<'.';
|
|
|
|
} else {
|
|
|
|
std::cout<<'#';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
std::cout<<std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sum=0;
|
|
|
|
for (int x=upperLeft.x;x<=lowerRight.x;x++){
|
|
|
|
for (int y=upperLeft.y;y<=lowerRight.y;y++){
|
|
|
|
if (elves.find({x,y})==elves.end()){
|
|
|
|
sum++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::cout<<"Iteration Count: "<<iterations<<std::endl;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|