From c8de9d2d3b3df987b33b9c4e721790eb40edcec2 Mon Sep 17 00:00:00 2001
From: Felix Agner <felix.agner@control.lth.se>
Date: Sun, 15 Dec 2024 10:10:41 +0100
Subject: [PATCH] added weekend stuff

---
 day 13/day_13_felix.cpp  |  81 +++++++++++++++++++++++
 day 14/day_14_felix.cpp  | 122 +++++++++++++++++++++++++++++++++++
 day 15/day_15_felix.cpp  |  93 +++++++++++++++++++++++++++
 day 15/day_15_felix2.cpp | 135 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 431 insertions(+)
 create mode 100644 day 13/day_13_felix.cpp
 create mode 100644 day 14/day_14_felix.cpp
 create mode 100644 day 15/day_15_felix.cpp
 create mode 100644 day 15/day_15_felix2.cpp

diff --git a/day 13/day_13_felix.cpp b/day 13/day_13_felix.cpp
new file mode 100644
index 0000000..4fbf659
--- /dev/null
+++ b/day 13/day_13_felix.cpp	
@@ -0,0 +1,81 @@
+#include <bits/stdc++.h>
+using namespace std;
+const bool DEBUG = false;
+
+#define coord pair <ll, ll>
+#define ll long long
+
+#define matrix vector <vector <double>>
+
+bool is_invertible(matrix m) {
+    return m[0][0] * m[1][1] - m[0][1] * m[1][0] != 0;
+}
+
+matrix invert(matrix m) {
+    double det = m[0][0] * m[1][1] - m[0][1] * m[1][0];
+    return {{{m[1][1]/det, -m[0][1]/det}, {-m[1][0]/det, m[0][0]/det}}};
+}
+
+coord read_coord(string s, int skip_first) {
+    char c;
+    ll x, y;
+    stringstream ss;
+    ss << s;
+    for (int i = 0; i < skip_first; i++) ss >> c;
+    ss >> x;
+    for (int i = 0; i < 3; i++) ss >> c;
+    ss >> y;
+    return coord(x, y);
+}
+
+bool is_integer(double f) {
+    return ceil(f) == f || floor(f) == f || round(f) == f || abs(f - round(f)) < 0.001;
+}
+
+ll minimum_tokens(coord a, coord b, coord prize, int max_steps) {
+    matrix m = {{(double)a.first, (double)b.first}, {(double)a.second, (double)b.second}};
+    if (!is_invertible(m)){
+        cout << "Not invertible" << endl;
+        return 0;
+    }
+    matrix inv = invert(m);
+    double na = inv[0][0] * prize.first + inv[0][1] * prize.second;
+    double nb = inv[1][0] * prize.first + inv[1][1] * prize.second;
+    DEBUG && cout << "Na " << na << " Nb " << nb << endl;
+    DEBUG && cout << na - round(na) << " " << nb - round(nb) << endl;
+    // Check if they are integers
+    if (!is_integer(na) || !is_integer(nb)) {
+        DEBUG && cout << "Not integers" << endl;
+        return 0;
+    }
+    bool too_large = max_steps != -1 && (na > max_steps || nb > max_steps);
+    if (na < 0 || nb < 0 || too_large) {
+        DEBUG && cout << "Out of bounds" << endl;
+        return 0;
+    }
+
+    return 3 * round(na) + round(nb);
+}
+
+int main () {
+    string bA, bB, prize;
+    ll part1 = 0;
+    ll part2 = 0;
+    while (getline(cin, bA) && getline(cin, bB) && getline(cin, prize)) {
+        coord a, b, p;
+        DEBUG && cout << "Read " << bA << " " << bB << " " << prize << endl;
+        a = read_coord(bA, 10);
+        b = read_coord(bB, 10);
+        p = read_coord(prize, 8);
+
+        // part1 += minimum_tokens(a, b, p, 100);
+        part2 += minimum_tokens(a, b, {p.first + 10000000000000, p.second + 10000000000000}, -1);
+
+        getline(cin, bA); // just clear line
+        // break;
+    }
+ 
+    cout << "Part 1: " << part1 << endl;
+    cout << "Part 2: " << part2 << endl;
+    return 0;
+}
\ No newline at end of file
diff --git a/day 14/day_14_felix.cpp b/day 14/day_14_felix.cpp
new file mode 100644
index 0000000..0859ccf
--- /dev/null
+++ b/day 14/day_14_felix.cpp	
@@ -0,0 +1,122 @@
+#include <bits/stdc++.h>
+using namespace std;
+const bool DEBUG = false;
+
+int SZX = DEBUG ? 11 : 101;
+int SZY = DEBUG ? 7 : 103;
+string INPUT_FILE = DEBUG ? "test_input.txt" : "input.txt";
+
+#define coord pair <int, int>
+#define ll long long
+
+pair<coord,coord> parse_line(string &line) {
+    DEBUG && cout << "Parsing line: " << line << endl;
+    int p1, p2, v1, v2;
+    stringstream ss(line);
+    char c;
+    for (int i = 0; i < 2; i++) ss >> c;
+    ss >> p1 >> c >> p2;
+    for (int i = 0; i < 2; i++) ss >> c;
+    ss >> v1 >> c >> v2;
+    DEBUG && cout << "Parsed line: " << p1 << " " << p2 << " " << v1 << " " << v2 << endl;
+    return make_pair(make_pair(p1, p2), make_pair(v1, v2));
+}
+
+coord move(coord &p0, coord &v, int steps) {
+    coord pend = {p0.first + steps * v.first, p0.second + steps * v.second};
+    pend = {pend.first % SZX, pend.second % SZY};
+    pend.first = pend.first < 0 ? pend.first + SZX : pend.first;
+    pend.second = pend.second < 0 ? pend.second + SZY : pend.second;
+    return pend;
+}
+
+int get_quadrant(coord &pend) {
+    int dx = pend.first - floor(SZX / 2);
+    int dy = pend.second - floor(SZY / 2);
+
+    DEBUG && cout << "x: " << pend.first << " y: " << pend.second << endl;
+    DEBUG && cout << "dx: " << dx << " dy: " << dy << endl;
+    if (dx > 0 && dy > 0) return 0;
+    if (dx < 0 && dy > 0) return 1;
+    if (dx < 0 && dy < 0) return 2;
+    if (dx > 0 && dy < 0) return 3;
+    return -1;
+}
+
+void print_grid(vector<coord> &positions) {
+    vector<string> grid(SZY, string(SZX, ' '));
+    for (coord &p : positions) {
+        grid[p.second][p.first] = '#';
+    }
+    for (string &row : grid) {
+        cout << row << endl;
+    }
+}
+
+int main () {
+    string line;
+    array<ll, 4> quadcount = {0, 0, 0, 0};
+    vector<coord> positions;
+    vector<coord> new_positions;
+    vector<coord> velocities;
+
+    // read input file
+
+    // Open the text file named "input.txt"
+    ifstream f(INPUT_FILE);
+
+    // Check if the file is successfully opened
+    if (!f.is_open()) {
+        cerr << "Error opening the file!";
+        return 1;
+    }
+
+    while (getline(f, line)) {
+        pair<coord, coord> pv = parse_line(line);
+        positions.push_back(pv.first);
+        new_positions.push_back(pv.first);
+        velocities.push_back(pv.second);
+    }
+    for (int step = 62; step < 100000; step+=101) {
+        // bool christmas_tree = true;
+        for (int i = 0; i < positions.size(); i++) {
+            new_positions[i] = move(positions[i], velocities[i], step);
+            // if (new_positions[i].first + new_positions[i].second < SZX / 3) {
+            //     christmas_tree = false;
+            //     break;
+            // }
+        }   
+        // if (!christmas_tree) continue;
+        cout << "Seconds: " << step << endl;
+        print_grid(new_positions);
+        //this_thread::sleep_for(chrono::milliseconds(500));
+        getchar();
+    }
+    
+
+    for (int i = 0; i < positions.size(); i++) {
+        coord pend = move(positions[i], velocities[i], 100);
+        int quad = get_quadrant(pend);
+        quadcount[quad]++;
+    }
+    ll part1 = quadcount[0] * quadcount[1] * quadcount[2] * quadcount[3];
+    cout << "Part 1: " << part1 << endl;
+
+    return 0;
+}
+
+// 25
+// 62
+// 128
+// 163
+// 231
+// 540
+// 567
+// 643
+// 668
+// 746
+// 769
+// 849
+// 870
+// 952
+// 971
\ No newline at end of file
diff --git a/day 15/day_15_felix.cpp b/day 15/day_15_felix.cpp
new file mode 100644
index 0000000..5054dad
--- /dev/null
+++ b/day 15/day_15_felix.cpp	
@@ -0,0 +1,93 @@
+#include <bits/stdc++.h>
+using namespace std;
+const bool DEBUG = false;
+
+#define coord pair <int, int>
+#define ll long long
+
+vector<string> warehouse;
+const map <char, coord> DIRMAP = {
+    {'^', {0, -1}},
+    {'v', {0, 1}},
+    {'<', {-1, 0}},
+    {'>', {1, 0}}
+};
+
+void print_warehouse() {
+    for (string line : warehouse) cout << line << endl;
+}
+
+string read_input() {
+    string line = "none";
+    string instructions;
+    while (getline(cin, line) && line != "") {
+        warehouse.push_back(line);
+    }
+    while (getline(cin, line)) instructions += line;
+    return instructions;
+}
+
+coord find_robot() {
+    for (int row = 0; row < warehouse.size(); row++) {
+        for (int col = 0; col < warehouse[row].size(); col++) {
+            if (warehouse[row][col] == '@') return {col, row};
+        }
+    }
+    return {-1, -1};
+}
+
+bool is_immovable(coord pos, coord dir) {
+    if (warehouse[pos.second][pos.first] == '#') return true;
+    if (warehouse[pos.second][pos.first] == 'O') {
+        coord next_pos = {pos.first + dir.first, pos.second + dir.second};
+        return is_immovable(next_pos, dir);
+    };
+    return false;
+}
+
+coord move(coord pos, coord dir) {
+    coord next_pos = {pos.first + dir.first, pos.second + dir.second};
+    // if (DEBUG) cout << "Moving from " << pos.first << ", " << pos.second << " to " << next_pos.first << ", " << next_pos.second << endl;
+    // if (DEBUG) cout << "Is immovable? " << is_immovable(next_pos, dir) << endl;
+    if (is_immovable(next_pos, dir)) return pos;
+    if (warehouse[pos.second][pos.first] == '.') return pos;
+    move(next_pos, dir);
+    if (DEBUG) cout << warehouse[next_pos.second][next_pos.first] << " " << warehouse[pos.second][pos.first] << endl;
+    warehouse[next_pos.second][next_pos.first] = warehouse[pos.second][pos.first];
+    warehouse[pos.second][pos.first] = '.';
+    return next_pos;
+}
+
+ll count_boxes() {
+    ll count = 0;
+    for (int row = 0; row < warehouse.size(); row++) {
+        for (int col = 0; col < warehouse[row].size(); col++) {
+            if (warehouse[row][col] == 'O') count+=100*row + col;
+        }
+    }
+    return count;
+}
+
+int main () {
+    string instructions = read_input();
+    if (DEBUG) cout << "Warehouse: " << endl;
+    if (DEBUG) print_warehouse();
+    if (DEBUG) cout << "Instructions: " << endl << instructions << endl;
+
+    coord robot = find_robot();
+    if (DEBUG) cout << "Robot at: " << robot.first << ", " << robot.second << endl;
+
+    stringstream moves(instructions);
+    char arrow;
+    while (moves >> arrow) {
+        coord dir = DIRMAP.at(arrow);
+        robot = move(robot, dir);
+        if (DEBUG) cout << "Move " << arrow << endl;
+        if (DEBUG) print_warehouse();
+        if (DEBUG) cout << endl;
+    }
+
+    cout << "Part 1: " << count_boxes() << endl;
+
+    return 0;
+}
\ No newline at end of file
diff --git a/day 15/day_15_felix2.cpp b/day 15/day_15_felix2.cpp
new file mode 100644
index 0000000..b83ae7d
--- /dev/null
+++ b/day 15/day_15_felix2.cpp	
@@ -0,0 +1,135 @@
+#include <bits/stdc++.h>
+using namespace std;
+const bool DEBUG = false;
+
+#define coord pair <int, int>
+#define ll long long
+
+vector<string> warehouse;
+const map <char, coord> DIRMAP = {
+    {'^', {0, -1}},
+    {'v', {0, 1}},
+    {'<', {-1, 0}},
+    {'>', {1, 0}}
+};
+
+const map <char, string> CHARMAP = {
+    {'#', "##"},
+    {'.', ".."},
+    {'@', "@."},
+    {'O', "[]"}
+};
+
+void print_warehouse() {
+    for (string line : warehouse) cout << line << endl;
+}
+
+string read_input() {
+    string line = "none";
+    string instructions;
+    while (getline(cin, line) && line != "") {
+        stringstream ss(line);
+        string row;
+        char c;
+        while (ss >> c) row += CHARMAP.at(c);
+        warehouse.push_back(row);
+    }
+    while (getline(cin, line)) instructions += line;
+    return instructions;
+}
+
+coord find_robot() {
+    for (int row = 0; row < warehouse.size(); row++) {
+        for (int col = 0; col < warehouse[row].size(); col++) {
+            if (warehouse[row][col] == '@') return {col, row};
+        }
+    }
+    return {-1, -1};
+}
+
+bool is_immovable(coord pos, coord dir) {
+    coord next_pos = {pos.first + dir.first, pos.second + dir.second};
+    if (warehouse[pos.second][pos.first] == '#') return true;
+
+    if (warehouse[pos.second][pos.first] == '[' && dir.second != 0) {
+        coord next_right = {next_pos.first + 1, next_pos.second};
+        return is_immovable(next_pos, dir) || is_immovable(next_right, dir);
+    } else if (warehouse[pos.second][pos.first] == ']' && dir.second != 0) {
+        coord next_left = {next_pos.first - 1, next_pos.second};
+        return is_immovable(next_pos, dir) || is_immovable(next_left, dir);
+    } else if (warehouse[pos.second][pos.first] == '[' || warehouse[pos.second][pos.first] == ']') {
+        return is_immovable(next_pos, dir);
+    }
+
+    return false;
+}
+
+coord move(coord pos, coord dir) {
+    coord next_pos = {pos.first + dir.first, pos.second + dir.second};
+
+    if (is_immovable(next_pos, dir)) return pos; // cannot move
+    if (warehouse[pos.second][pos.first] == '.') return pos; // nothing to move
+
+    if (warehouse[pos.second][pos.first] == '[' && dir.second != 0) {
+        coord next_right = {next_pos.first + 1, next_pos.second};
+        move(next_pos, dir);
+        move(next_right, dir);
+        warehouse[next_pos.second][next_pos.first] = '[';
+        warehouse[next_right.second][next_right.first] = ']';
+        warehouse[pos.second][pos.first] = '.';
+        warehouse[pos.second][pos.first + 1] = '.';
+
+    } else if (warehouse[pos.second][pos.first] == ']' && dir.second != 0) {
+        coord next_left = {next_pos.first - 1, next_pos.second};
+        move(next_pos, dir);
+        move(next_left, dir);
+        warehouse[next_pos.second][next_pos.first] = ']';
+        warehouse[next_left.second][next_left.first] = '[';
+        warehouse[pos.second][pos.first] = '.';
+        warehouse[pos.second][pos.first - 1] = '.';
+    } else {
+        move(next_pos, dir);   
+        warehouse[next_pos.second][next_pos.first] = warehouse[pos.second][pos.first];
+        warehouse[pos.second][pos.first] = '.'; 
+    }
+    
+    
+    
+    return next_pos;
+}
+
+ll count_boxes() {
+    ll count = 0;
+    for (int row = 0; row < warehouse.size(); row++) {
+        for (int col = 0; col < warehouse[row].size(); col++) {
+            if (warehouse[row][col] == '[') count+=100*row + col;
+        }
+    }
+    return count;
+}
+
+int main () {
+    string instructions = read_input();
+    if (DEBUG) cout << "Warehouse: " << endl;
+    if (DEBUG) print_warehouse();
+    if (DEBUG) cout << "Instructions: " << endl << instructions << endl;
+
+    coord robot = find_robot();
+    if (DEBUG) cout << "Robot at: " << robot.first << ", " << robot.second << endl;
+
+    stringstream moves(instructions);
+    char arrow;
+    int n_moves = 0;
+    while (moves >> arrow) {
+        n_moves++;
+        coord dir = DIRMAP.at(arrow);
+        robot = move(robot, dir);
+        if (DEBUG) cout << "Move #" << n_moves << " " << arrow << endl;
+        if (DEBUG) print_warehouse();
+        if (DEBUG) cout << endl;
+    }
+
+    cout << "Part 2: " << count_boxes() << endl;
+
+    return 0;
+}
\ No newline at end of file
-- 
GitLab