Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <fstream>
- #include <iostream>
- #include <string>
- #include <vector>
- #include <unordered_map>
- const int steps[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
- struct vector_hash {
- std::size_t operator()(std::vector<int> const& vec) const {
- std::size_t seed = vec.size();
- for(auto x : vec) {
- x = ((x >> 16) ^ x) * 0x45d9f3b;
- x = ((x >> 16) ^ x) * 0x45d9f3b;
- x = (x >> 16) ^ x;
- seed ^= x + 0x9e3779b9 + (seed << 6) + (seed >> 2);
- }
- return seed;
- }
- };
- bool search(std::vector<int>& v, int key){
- for(int i = 0; i < v.size(); i++){
- if(v[i] == key)
- return true;
- }
- return false;
- }
- bool stop_check(int x, int y, int nrows, int ncols){
- if(x >= nrows || x < 0 || y < 0 || y >= ncols)
- return true;
- return false;
- }
- void change_pos(int& x, int& y, int cur_dir, char op){
- if(op == '+'){
- x += steps[cur_dir][0];
- y += steps[cur_dir][1];
- } else if(op == '-'){
- x -= steps[cur_dir][0];
- y -= steps[cur_dir][1];
- }
- }
- bool place_obstacle(std::unordered_map<std::vector<int>, std::vector<int>, vector_hash>& visited, std::vector<std::string>& guard_map, int x, int y, int cur_dir)
- {
- std::unordered_map<std::vector<int>, std::vector<int>, vector_hash> lvisited;
- int nrows = guard_map.size();
- int ncols = guard_map[0].size();
- bool quit = false;
- while(!quit){
- while(!(quit = stop_check(x, y, nrows, ncols)) && guard_map[x][y] != '#' ){
- std::vector<int> t{x, y};
- if((visited.find(t) != visited.end() && search(visited[t], cur_dir)) || (lvisited.find(t) != lvisited.end() && search(lvisited[t], cur_dir))){
- return true;
- }
- lvisited[t].push_back(cur_dir);
- change_pos(x, y, cur_dir, '+');
- }
- change_pos(x, y, cur_dir, '-');
- cur_dir = (cur_dir + 1) % 4;
- }
- return false;
- }
- int main()
- {
- std::ifstream inp_file;
- std::vector<std::string> guard_map;
- int st_x, st_y;
- int cur_dir;
- inp_file.open("day6-in.txt");
- if(inp_file.is_open()){
- std::string line;
- bool f = false;
- while(std::getline(inp_file, line)){
- guard_map.push_back(line);
- for(int i = 0; !f && i < line.size(); i++){
- if(line[i] == '^'){
- st_x = guard_map.size() - 1;
- st_y = i;
- f = true;
- }
- }
- }
- }
- inp_file.close();
- int nrows, ncols;
- bool quit = false;
- int pos_visited = 1;
- int nobstacle_pos = 0;
- std::unordered_map<std::vector<int>, std::vector<int>, vector_hash> visited;
- nrows = guard_map.size();
- ncols = guard_map[0].size();
- int x,y;
- x = st_x;
- y = st_y;
- cur_dir = 0;
- while(!quit){
- while(guard_map[x][y] != '#'){
- std::vector<int> t{x, y};
- visited[t].push_back(cur_dir);
- if(guard_map[x][y] == '.'){
- pos_visited++;
- guard_map[x][y] = '#';
- if(place_obstacle(visited, guard_map, x - steps[cur_dir][0], y - steps[cur_dir][1], (cur_dir + 1) % 4)){
- nobstacle_pos++;
- }
- guard_map[x][y] = 'X';
- }
- change_pos(x, y, cur_dir, '+');
- if((quit = stop_check(x, y, nrows, ncols)))
- break;
- }
- change_pos(x, y, cur_dir, '-');
- cur_dir = (cur_dir + 1) % 4;
- }
- std::cout << pos_visited << std::endl;
- std::cout << nobstacle_pos << std::endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement