Skip to content

Commit

Permalink
Add 2016 day 13 cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
vss2sn committed Jul 20, 2024
1 parent 3508d8c commit e8498da
Show file tree
Hide file tree
Showing 7 changed files with 283 additions and 2 deletions.
2 changes: 1 addition & 1 deletion 2016/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ This folder contains solutions to each of the problems in Advent of Code 2016 in
| <nobr> [Day 10: Balance Bots](https://adventofcode.com/2016/day/10) </nobr> | <nobr> [Part 1](/2016/cpp/day_10a.cpp) [Part 2](/2016/cpp/day_10b.cpp) </nobr> |[Link](/2016/input/day_10_input)|[Link](/2016/sample_input/day_10_sample_input)|[Link](/2016/puzzles/day_10_puzzle)|
| <nobr> [Day 11: Radioisotope Thermoelectric Generators](https://adventofcode.com/2016/day/11) </nobr> | <nobr> [Part 1](/2016/cpp/day_11a.cpp) [Part 2](/2016/cpp/day_11b.cpp) </nobr> |[Link](/2016/input/day_11_input)|[Link](/2016/sample_input/day_11_sample_input)|[Link](/2016/puzzles/day_11_puzzle)|
| <nobr> [Day 12: Leonardo's Monorail](https://adventofcode.com/2016/day/12) </nobr> | <nobr> [Part 1](/2016/cpp/day_12a.cpp) [Part 2](/2016/cpp/day_12b.cpp) </nobr> |[Link](/2016/input/day_12_input)|[Link](/2016/sample_input/day_12_sample_input)|[Link](/2016/puzzles/day_12_puzzle)|
| <nobr> [Day 13: ](https://adventofcode.com/2016/day/13) </nobr> | <nobr> [Part 1](/2016/cpp/day_13a.cpp) [Part 2](/2016/cpp/day_13b.cpp) </nobr> |[Link](/2016/input/day_13_input)|[Link](/2016/sample_input/day_13_sample_input)|[Link](/2016/puzzles/day_13_puzzle)|
| <nobr> [Day 13: A Maze of Twisty Little Cubicles](https://adventofcode.com/2016/day/13) </nobr> | <nobr> [Part 1](/2016/cpp/day_13a.cpp) [Part 2](/2016/cpp/day_13b.cpp) </nobr> |[Link](/2016/input/day_13_input)|[Link](/2016/sample_input/day_13_sample_input)|[Link](/2016/puzzles/day_13_puzzle)|
| <nobr> [Day 14: ](https://adventofcode.com/2016/day/14) </nobr> | <nobr> [Part 1](/2016/cpp/day_14a.cpp) [Part 2](/2016/cpp/day_14b.cpp) </nobr> |[Link](/2016/input/day_14_input)|[Link](/2016/sample_input/day_14_sample_input)|[Link](/2016/puzzles/day_14_puzzle)|
| <nobr> [Day 15: ](https://adventofcode.com/2016/day/15) </nobr> | <nobr> [Part 1](/2016/cpp/day_15a.cpp) [Part 2](/2016/cpp/day_15b.cpp) </nobr> |[Link](/2016/input/day_15_input)|[Link](/2016/sample_input/day_15_sample_input)|[Link](/2016/puzzles/day_15_puzzle)|
| <nobr> [Day 16: ](https://adventofcode.com/2016/day/16) </nobr> | <nobr> [Part 1](/2016/cpp/day_16a.cpp) [Part 2](/2016/cpp/day_16b.cpp) </nobr> |[Link](/2016/input/day_16_input)|[Link](/2016/sample_input/day_16_sample_input)|[Link](/2016/puzzles/day_16_puzzle)|
Expand Down
119 changes: 119 additions & 0 deletions 2016/cpp/day_13a.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#include <array>
#include <fstream>
#include <iostream>
#include <queue>
#include <string>
#include <unordered_set>

enum class Type {
WALL, SPACE
};

int sv_to_int (const std::string_view sv) {
bool negative = (sv[0] == '-') ? true : false;
int n = 0;
for (int i = negative ? 1 : 0; i < sv.size(); i++) {
n = n * 10 + (sv[i] - '0');
}
if (negative) {
n *= -1;
}
return n;
}

std::array<int, 31> get_bit_masks () {
std::array<int, 31> bit_masks;
int bit_mask = 1;
for (int i = 0; i < 31; i++) {
bit_masks[i] = bit_mask;
bit_mask <<= 1;
}
return bit_masks;
}

struct Point {
Point (const int x, const int y) : x(x), y(y) {}
int x;
int y;
};

struct PointAndMove {
PointAndMove(const int x = 0, const int y = 0, const int move = 0) : p(Point(x, y)), move(move) {}
Point p;
int move;
bool operator == (const PointAndMove& pm) const {
return p.x == pm.p.x && p.y == pm.p.y;
}
};

struct pm_hasher {
std::size_t operator () (const PointAndMove& pm) const {
return pm.p.x << 5 + pm.p.y;
}
};

int main(int argc, char* argv[]) {
std::string input = "../input/day_13_input";
if (argc > 1) {
input = argv[1];
}

std::ifstream file(input);
std::string line;
std::getline(file, line);
const int designers_fav_n = std::stoi(line);
const std::array<int, 31> bit_masks = get_bit_masks();
const auto get_type = [designers_fav_n, &bit_masks](const int y, const int x) {
const int n = x*x + 3*x + 2*x*y + y + y*y + designers_fav_n;
int count = 0;
for (const auto& bit_mask : bit_masks) {
// std::cout << bit_mask << '\n';
count += ((n & bit_mask) != 0) ? 1 : 0;
}
// std::cout << '(' << x << ',' << y << " | " << n << " | " << count << " | " << static_cast<int>((count % 2 == 0) ? Type::SPACE : Type::WALL) << '\n';
return (count % 2 == 0) ? Type::SPACE : Type::WALL;
};
const std::array<Point, 4> moves {
Point(0,1),
Point(1,0),
Point(0,-1),
Point(-1, 0)
};
const auto in_bounds = [](const Point& p) {
return p.x >= 0 && p.y >= 0;
};
std::unordered_set<PointAndMove, pm_hasher> seen;
std::queue<PointAndMove> q;
PointAndMove pm;
pm.p = Point(1,1);
pm.move = 0;
q.push(pm);
// for (int i = 0; i < 10; i++) {
// for (int j = 0; j < 10; j++) {
// std::cout << ((get_type(i, j) == Type::WALL) ? '#' : '.');
// }
// std::cout << '\n';
// }
while(!q.empty()) {
const auto current = q.front();
q.pop();
if (seen.find(current) != seen.end()) continue;
seen.insert(current);
if (current.p.x == 39 && current.p.y == 31) {
// std::cout << "Found" << '\n';
std::cout << current.move << '\n';
return 0;
}
for (const auto& move : moves) {
PointAndMove next;
next.p = Point(current.p.x + move.x, current.p.y + move.y);
next.move = current.move + 1;
if (!in_bounds(next.p)) continue;
if (get_type(next.p.x, next.p.y) == Type::WALL) continue;
if (seen.find(next) != seen.end()) continue;
q.push(next);
}
}
std::cout << "Not found " << '\n';
return 0;
}
118 changes: 118 additions & 0 deletions 2016/cpp/day_13b.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#include <array>
#include <fstream>
#include <iostream>
#include <queue>
#include <string>
#include <unordered_set>

enum class Type {
WALL, SPACE
};

int sv_to_int (const std::string_view sv) {
bool negative = (sv[0] == '-') ? true : false;
int n = 0;
for (int i = negative ? 1 : 0; i < sv.size(); i++) {
n = n * 10 + (sv[i] - '0');
}
if (negative) {
n *= -1;
}
return n;
}

std::array<int, 31> get_bit_masks () {
std::array<int, 31> bit_masks;
int bit_mask = 1;
for (int i = 0; i < 31; i++) {
bit_masks[i] = bit_mask;
bit_mask <<= 1;
}
return bit_masks;
}

struct Point {
Point (const int x, const int y) : x(x), y(y) {}
int x;
int y;
};

struct PointAndMove {
PointAndMove(const int x = 0, const int y = 0, const int move = 0) : p(Point(x, y)), move(move) {}
Point p;
int move;
bool operator == (const PointAndMove& pm) const {
return p.x == pm.p.x && p.y == pm.p.y;
}
};

struct pm_hasher {
std::size_t operator () (const PointAndMove& pm) const {
return pm.p.x << 5 + pm.p.y;
}
};

int main(int argc, char* argv[]) {
std::string input = "../input/day_13_input";
if (argc > 1) {
input = argv[1];
}

std::ifstream file(input);
std::string line;
std::getline(file, line);
const int designers_fav_n = std::stoi(line);
const std::array<int, 31> bit_masks = get_bit_masks();
const auto get_type = [designers_fav_n, &bit_masks](const int y, const int x) {
const int n = x*x + 3*x + 2*x*y + y + y*y + designers_fav_n;
int count = 0;
for (const auto& bit_mask : bit_masks) {
// std::cout << bit_mask << '\n';
count += ((n & bit_mask) != 0) ? 1 : 0;
}
// std::cout << '(' << x << ',' << y << " | " << n << " | " << count << " | " << static_cast<int>((count % 2 == 0) ? Type::SPACE : Type::WALL) << '\n';
return (count % 2 == 0) ? Type::SPACE : Type::WALL;
};
const std::array<Point, 4> moves {
Point(0,1),
Point(1,0),
Point(0,-1),
Point(-1, 0)
};
const auto in_bounds = [](const Point& p) {
return p.x >= 0 && p.y >= 0;
};
std::unordered_set<PointAndMove, pm_hasher> seen;
std::queue<PointAndMove> q;
PointAndMove pm;
pm.p = Point(1,1);
pm.move = 0;
q.push(pm);
// for (int i = 0; i < 10; i++) {
// for (int j = 0; j < 10; j++) {
// std::cout << ((get_type(i, j) == Type::WALL) ? '#' : '.');
// }
// std::cout << '\n';
// }
while(!q.empty()) {
const auto current = q.front();
q.pop();
if (seen.find(current) != seen.end()) continue;
if (current.move > 50) {
std::cout << seen.size() << '\n';
return 0;
}
seen.insert(current);
for (const auto& move : moves) {
PointAndMove next;
next.p = Point(current.p.x + move.x, current.p.y + move.y);
next.move = current.move + 1;
if (!in_bounds(next.p)) continue;
if (get_type(next.p.x, next.p.y) == Type::WALL) continue;
if (seen.find(next) != seen.end()) continue;
q.push(next);
}
}
std::cout << "Not found " << '\n';
return 0;
}
1 change: 1 addition & 0 deletions 2016/input/day_13_input
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1352
42 changes: 42 additions & 0 deletions 2016/puzzles/day_13_puzzle
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
--- Day 13: A Maze of Twisty Little Cubicles ---
You arrive at the first floor of this new building to discover a much less welcoming environment than the shiny atrium of the last one. Instead, you are in a maze of twisty little cubicles, all alike.

Every location in this area is addressed by a pair of non-negative integers (x,y). Each such coordinate is either a wall or an open space. You can't move diagonally. The cube maze starts at 0,0 and seems to extend infinitely toward positive x and y; negative values are invalid, as they represent a location outside the building. You are in a small waiting area at 1,1.

While it seems chaotic, a nearby morale-boosting poster explains, the layout is actually quite logical. You can determine whether a given x,y coordinate will be a wall or an open space using a simple system:

Find x*x + 3*x + 2*x*y + y + y*y.
Add the office designer's favorite number (your puzzle input).
Find the binary representation of that sum; count the number of bits that are 1.
If the number of bits that are 1 is even, it's an open space.
If the number of bits that are 1 is odd, it's a wall.
For example, if the office designer's favorite number were 10, drawing walls as # and open spaces as ., the corner of the building containing 0,0 would look like this:

0123456789
0 .#.####.##
1 ..#..#...#
2 #....##...
3 ###.#.###.
4 .##..#..#.
5 ..##....#.
6 #...##.###
Now, suppose you wanted to reach 7,4. The shortest route you could take is marked as O:

0123456789
0 .#.####.##
1 .O#..#...#
2 #OOO.##...
3 ###O#.###.
4 .##OO#OO#.
5 ..##OOO.#.
6 #...##.###
Thus, reaching 7,4 would take a minimum of 11 steps (starting from your current location, 1,1).

What is the fewest number of steps required for you to reach 31,39?

Your puzzle answer was 90.

--- Part Two ---
How many locations (distinct x,y coordinates, including your starting location) can you reach in at most 50 steps?

Your puzzle answer was 135.
1 change: 1 addition & 0 deletions 2016/sample_input/day_13_sample_input
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
10
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ This repository contains solutions to the Advent of Code puzzles.
|2019 |1-25 |1-7 | [Link](/2019/) |[Link](/2019/README.md) |
|2018 |1-25 | - | [Link](/2018/) |[Link](/2018/README.md) |
|2017 |1-25 | - | [Link](/2017/) |[Link](/2017/README.md) |
|2017 |1-12 | - | [Link](/2016/) |[Link](/2016/README.md) |
|2017 |1-13 | - | [Link](/2016/) |[Link](/2016/README.md) |

## To run ##

Expand Down

0 comments on commit e8498da

Please sign in to comment.