FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

冬休みプログラミングレッスン2024: Advent of Code (Day06)

adventofcode.com

久しぶりにC++を使ってプログラミングしている。なんかソフトウェアが書けなくなって参ってしまうな...

6日目。マップを通りながら、石にぶつかると方向を変えていく。何ステップで脱出できるかという話だが、素直にマップ上をシミュレーションすると回答できる。

問題はPart-Twoで、おそらく現在の場所から、次の場所に石を置いた場合にループが発生するかを見ていけばよいはずなのだが、まだうまくいっていない。 ループの発生は、石にぶつかったときにすでにその場所が訪問済みならば、同じ方向に曲がるはずなのでそれをループとすればよいと思う。

#include <iostream>
#include <vector>

bool out_of_map (std::pair<int, int> v, size_t max) {
    if (v.first < 0 || v.first >= max || v.second < 0 || v.second >= max) {
        return true;
    } else {
        return false;
    }
}


void show_map (std::vector<std::string> map) {
    std::cout << '\n';
    for (auto v: map) {
        std::cout << v << '\n';
    }
}

int main ()
{
    std::string line;
    std::vector <std::string> v_map;
    std::pair <int, int> v_point;
    size_t start_y = 0;

    typedef enum {
        UP = 0, 
        RIGHT = 1   ,
        DOWN = 2,
        LEFT = 3
    } dir_t;

    while (std::cin >> line) {
        v_map.push_back(line);
        for (size_t i = 0; i < line.size(); i++) {
            if (line[i] == '^') {
                v_point.first  = start_y;
                v_point.second = i;
            }
        }
        start_y++;
    }
    size_t map_size = v_map.size();
    dir_t v_dir = UP;
    size_t v_step = 0;
    bool map_finish = false;

    while (!map_finish) {
        if (v_map[v_point.first][v_point.second] != 'X') {
            v_step++;
        }
        v_map[v_point.first][v_point.second] = 'X';
        switch (v_dir) {
            case UP: {
                v_point.first--;
                if (out_of_map (v_point, map_size)) {
                    map_finish = true;
                    break;
                }
                if (v_map[v_point.first][v_point.second] == '#') {
                    v_point.first++; // Role back
                    v_dir = RIGHT;
                    show_map (v_map);
                }
                break;
            }
            case RIGHT: {
                v_point.second++;
                if (out_of_map (v_point, map_size)) {
                    map_finish = true;
                    break;
                }
                if (v_map[v_point.first][v_point.second] == '#') {
                    v_point.second--; // Role back
                    v_dir = DOWN;
                    show_map (v_map);
                }
                break;
            }
            case DOWN: {
                v_point.first++;
                if (out_of_map (v_point, map_size)) {
                    map_finish = true;
                    break;
                }
                if (v_map[v_point.first][v_point.second] == '#') {
                    v_point.first--; // Role back
                    v_dir = LEFT;
                    show_map (v_map);
                }
                break;
            }
            case LEFT: {
                v_point.second--;
                if (out_of_map (v_point, map_size)) {
                    map_finish = true;
                    break;
                }
                if (v_map[v_point.first][v_point.second] == '#') {
                    v_point.second++; // Role back
                    v_dir = UP;
                    show_map (v_map);
                }
                break;
            }
        }
    }

    std::cout << v_step << '\n';

    return 0;
}