Unable to load image

AoC Day 14 : Sands of time

I won't paste my code yet since my parser just does the needful, and I somehow manage to get overlapping grains of sand, though that doesn't matter in the end.

I'm also seeing a lot of pythonistas having high runtime (1-10s+ and more) and I'm here with the bruteforce grain-by-grain taking 150ms for part 2 (including drawing the final graph lmao). Matlab chads can't stop winning :gigachad2:

EDIT : part 2 webm

16
Jump in the discussion.

No email address required.

Harcoded the area and misread the instruction so my parttwo stops if the sand is one tile below the source. So naturally i just moved the source up by one.


#include <iostream>
#include <array>
#include <cassert>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>

constexpr int HEIGHT = 1000;
constexpr int WIDTH = 1000;

struct Coordinate {
    int x;
    int y;

    auto operator<=>(const Coordinate& r) const = default;

    Coordinate(int x, int y) {
        this->x = x;
        this->y = y;
    }
    
    Coordinate left() {
        return { x - 1, y };
    }

    Coordinate right() {
        return { x + 1, y };
    }
};

template<size_t W, size_t H>
class Map {
private:
    Coordinate sand_source{0,0};
    void draw_horizontal(Coordinate& a, Coordinate& b) {
        int start = a.x;
        int end = b.x;
        if (start > end) std::swap(start, end);
        
        std::array<char, W>& row = map[a.y];
        std::fill(row.begin() + start, row.begin() + end + 1, '#');
    }
    void draw_vertical(Coordinate& a, Coordinate& b) {
        int start = a.y;
        int end = b.y;
        if (start > end) std::swap(start, end);

        for (; start <= end; ++start) {
            map[start][a.x] = '#';
        }
    }
    bool place_sand(Coordinate& p) {
        map[p.y][p.x] = 'o';
        return true;
    }
public:
    std::array <std::array<char, W>, H> map;

    Map() {
        map = {};
        for (std::array<char, W>& row : map) {
            std::fill(row.begin(), row.end(), '.');
        }
    }
    bool is_room(const Coordinate p) const {
        return (p.x >= 0 && p.y >= 0 && p.x < W && p.y < H) && map[p.y][p.x] == '.';
    }

    void draw_line(Coordinate a, Coordinate b) {
        assert(a.x == b.x ||a.y == b.y && "Can't draw diagonals");
        if (a.x == b.x) draw_vertical(a, b);
        else draw_horizontal(a, b);
    }

    void add_sand_source(Coordinate sand_source) {
        this->sand_source = sand_source;
        map[sand_source.y][sand_source.x] = '+';
    }

    bool drop_sand() {
        if (map[sand_source.y - 1][sand_source.x] != '.') return false;

        Coordinate location = { sand_source.x, sand_source.y - 1 };

        while (location.y >= 0) {
            if (is_room(location)) location.y -= 1;
            else if (is_room(location.left())) location.x -= 1;
            else if (is_room(location.right())) location.x += 1;
            else {
                location.y += 1;
                return place_sand(location);
            }
        }

        return false;
    }
};

template<size_t W, size_t H>
std::ostream& operator<<(std::ostream& os, const Map<W, H>& map) {
    for (auto it = map.map.rbegin(); it < map.map.rend(); ++it) {
        for (char c : *it) os << c;
        os << '\n';
    }
    return os;
}

int run(bool partTwo = false) {
    auto area = new Map<WIDTH, HEIGHT>();

    std::fstream file("input.txt");
    std::string buf;
    int min{ 0 };

    while (std::getline(file, buf)) {
        int x{ 0 };
        int y{ 0 };
        
        std::string d_buf = "";
        
        std::vector<Coordinate> coord;

        for (char c : buf) {
            if (c == ',') {
                x = std::stoi(d_buf);
                d_buf = "";
            }
            else if (c == '-') {
                y = std::stoi(d_buf);
                min = std::max(y, min);
                d_buf = "";
                coord.push_back({ x, HEIGHT - y - 2});
            }
            else if (std::isdigit(c)) {
                d_buf += c;
            }
        }
        y = std::stoi(d_buf);
        min = std::max(y, min);
        d_buf = "";
        coord.push_back({ x, HEIGHT - y - 2 });

        for (size_t i{ 1 }; i < coord.size(); ++i) {
            area->draw_line(coord[i - 1], coord[i]);
        }
    }
    if (partTwo) area->draw_line({ 0,HEIGHT - min - 4 }, { WIDTH - 1, HEIGHT - min - 4 });
    area->add_sand_source({ 500, HEIGHT - 1 });

    int total{ 0 };
    while (area->drop_sand()) {
        total++;
    }

    return total;
}

int main() {
    std::cout << "Part One: " << run() << '\n';
    std::cout << "Part Two: " << run(true);
}
Jump in the discussion.

No email address required.

look im gunna have 2 ask u 2 keep ur giant dumps in the potty not in my replys 😷😷😷

Jump in the discussion.

No email address required.

Link copied to clipboard
Action successful!
Error, please refresh the page and try again.