Finally did Day 6 using C++.
Interestingly -O3 optimization made a better than ten times improvement on time.
Code:
Advent of code 2024 day 6Part1 - 4982Part2 - 1663Elapsed time 20.6543 seconds
Code:
#include <iostream>#include <chrono>#include <fstream>#include <utility>#include <string>#include <vector>#include <map>const char* filename = "data.txt";using xy = std::pair<int,int>;xy operator +=(xy l,xy r){return {l.first + r.first,l.second + r.second};}// part 2 uses masksenum move{up = 0b1,right = 0b10,down = 0b100,left = 0b1000};xy next(xy c,move m){ switch(m) { case up: return c += {-1,0}; case right: return c += {0,1}; case down: return c += {1,0}; case left: return c += {0,-1}; } return c;}move bump(move x){ switch(x) { case up: return right; case right: return down; case down: return left; case left: break; } return up;}// pos is possible states of each position in the map// low bits are used by part 2enum pos{none = 0,done = 0xf0,block,off};bool test(xy start, std::map<int, std::vector<pos>>& map){ move face = up; xy current = start; while(true) { // current direction is face xy newxy = next(current,face); if(map[newxy.first][newxy.second] == block) face = bump(face); else current = newxy; pos& x = map[current.first][current.second]; if(x != off) { if(x & face) return true; else x = static_cast<pos>(x | face); } else break; } return false;}void clear(std::map<int ,std::vector<pos>>& map){ int height = map.size(); int width = map[0].size(); // clear all but obstacles and edges for(int i = 1; i < height - 1; i++) for(int j = 1; j < width - 1; j++) { if(map[i][j] != block) map[i][j] = none; }}int part2(xy start, std::map<int, std::vector<pos>>& map){ int height = map.size(); int width = map[0].size(); int count = 0; for(int i = 1; i < height - 1; i++) { for(int j = 1; j < width - 1; j++) { if(map[i][j] != block && start != xy(i,j)) { clear(map); map[i][j] = block; if(test(start,map)) count++; map[i][j] = none; } } } return count;}int part1(xy current, std::map<int, std::vector<pos>>& map){ int count = 0; move face = up; do { // process current position if(map[current.first][current.second] != done) count++; map[current.first][current.second] = done; // current direction is face xy newxy = next(current,face); if(map[newxy.first][newxy.second] == block) face = bump(face); else current = newxy; }while(map[current.first][current.second] != off); return count;}int main(){ std::chrono::time_point<std::chrono::system_clock> start,stop; start = std::chrono::system_clock::now(); std::cout << "Advent of code 2024 day 6" << "\n"; std::ifstream file(filename); std::map<int, std::vector<pos>> map; xy first; if(file) { int x = 1; std::string s; std::getline(file,s); int width = s.length() + 2; std::vector<pos> line(width); for(int i = 0; i < width ; i++) line[i] = off; map.emplace(0,line); while(!file.eof()) { line[0] = off; for(int i = 1; i < width - 1; i++) { if (s[i - 1] == '#') line[i] = block; else line[i] = none; if(s[i - 1] == '^') first = {x,i}; } line[width - 1] = off; map.emplace(x,line); std::getline(file,s); x++; } for(int i = 0; i < width ; i++) line[i] = off; map.emplace(x,line); } std::cout << "Part1 - " << part1(first,map) << "\n"; std::cout << "Part2 - " << part2(first,map) << "\n"; stop = std::chrono::system_clock::now(); std::chrono::duration<double> elapsed = stop - start; std::cout << "Elapsed time " << elapsed.count() << " seconds" << "\n"; return 0;}
Statistics: Posted by RogerW — Fri Dec 13, 2024 3:41 pm