#include #include #include #include #include #include #include #include #include #include struct Diagram { std::vector data; size_t width; size_t height; using GridView = std::mdspan>; auto grid() { return GridView(data.data(), height, width); } }; auto printMap(Diagram &diagram) { auto grid = diagram.grid(); for (auto row = 0UZ; row != grid.extent(0); row++) { for (auto col = 0UZ; col != grid.extent(1); col++) { std::print("{}", grid[row, col]); } std::println(); } // std::println("Map: {}", diagram.data); std::println("Width: {}", diagram.width); std::println("Height: {}", diagram.height); } auto parseMap(const std::string &filename) -> std::expected { std::ifstream inputF{filename}; if (!inputF) { return std::unexpected{"Some file open error.\n"}; } Diagram diagram{}; std::string puzzleLine{}; while (std::getline(inputF, puzzleLine)) { // std::println("{:3}: {}", diagram.height, puzzleLine); diagram.data.push_back(0); diagram.data.append_range(puzzleLine | std::views::transform([](char c) -> int { return c == '.' ? 0 : 1; })); diagram.data.push_back(0); diagram.height++; // ugly diagram.width = puzzleLine.length() + 2; } // also ugly, bound it with 0s diagram.data.append_range(std::vector(diagram.width, 0)); diagram.data.insert_range(diagram.data.begin(), std::vector(diagram.width, 0)); diagram.height += 2; // printMap(diagram); // auto ms2 = std::mdspan(diagram.data.data(), diagram.width, diagram.height); return std::move(diagram); } auto countMovablePaper(Diagram &diagram) -> long { long nMovablePaper{}; auto grid = diagram.grid(); for (auto row = 1UZ; row != grid.extent(0) - 1; row++) { for (auto col = 1UZ; col != grid.extent(1) - 1; col++) { if (grid[row, col] == 1) { // std::print("checking [{},{}]:", row, col); // shitty kernel int upLeft = grid[row - 1, col - 1]; int up = grid[row - 1, col]; int upRight = grid[row - 1, col + 1]; int left = grid[row, col - 1]; int right = grid[row, col + 1]; int downLeft = grid[row + 1, col - 1]; int down = grid[row + 1, col]; int downRight = grid[row + 1, col + 1]; // caveman shit if ((upLeft + up + upRight + left + right + downLeft + down + downRight) < 4) { // std::println("Found"); nMovablePaper++; } } // std::println(); } } return nMovablePaper; } auto moveMoveablePaper(Diagram &diagram) -> long { long totalPaperRemoved{}; auto grid = diagram.grid(); constexpr std::array, 8> offsets = { {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}}; while (true) { long currentPaperRemoved = 0; for (auto row = 1UZ; row != grid.extent(0) - 1; row++) { for (auto col = 1UZ; col != grid.extent(1) - 1; col++) { if (grid[row, col] != 1) { continue; } // std::print("checking [{},{}]:", row, col); // shitty kernal int neighbors{0}; for (auto [dr, dc] : offsets) { // mdspan allows [x, y] indexing natively neighbors += grid[row + dr, col + dc]; } if (neighbors < 4) { grid[row, col] = 0; // std::println("Found"); currentPaperRemoved++; } } // std::println(); } if (currentPaperRemoved == 0) { std::println("Didn't remove any more paper this iteration! Stopping."); break; } totalPaperRemoved += currentPaperRemoved; // printMap(diagram); } return totalPaperRemoved; } auto main() -> int { auto testCase = parseMap("test_input"); if (testCase) { // auto testResult = countMovablePaper(*testCase); // std::println("P1 Testcase result: {}", testResult); auto testResultP2 = moveMoveablePaper(*testCase); std::println("P2 Testcase result: {}", testResultP2); } else { std::print("{}\n", testCase.error()); } auto realPuzzle = parseMap("puzzle_input"); if (realPuzzle) { // auto realResult = countMovablePaper(*realPuzzle); // std::println("P1 Real result: {}", realResult); auto realResultP2 = moveMoveablePaper(*realPuzzle); std::println("P2 Real result: {}", realResultP2); } else { std::print("{}\n", realPuzzle.error()); } return 0; }