summaryrefslogtreecommitdiff
path: root/2023/05/src/part1.cpp
blob: d58c0cbdd259e7956233e3c9756b633d1f081eba (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <iostream>
#include <fstream>
#include <sstream>
#include <tuple>
#include <vector>

#include "util.h"

using Seeds   = std::vector<long>;
using Step    = std::vector<std::tuple<long,long,long>>;
using Almanac = std::vector<Step>;

constexpr char SEEDS[] = "seeds:";

std::pair<Seeds,Almanac> parse_input()
{
    Seeds seeds;
    Almanac almanac;

    std::ifstream input{ "resources/input.txt" };
    if (input.is_open())
    {
        std::string line;

        /* Seeds */
        long seed;
        std::getline(input,line);
        std::istringstream sline{ line };
        sline >> util::skip<SEEDS>;
        while (sline >> seed)
        {
            seeds.push_back(seed);
        }

        /* Mappings */
        Step step;
        long from, to, size;
        while (not std::getline(input,line).eof())
        {
            if (line.empty()) continue;

            if (std::isdigit(line[0]))
            {
                std::istringstream sline{ line };
                sline >> to >> from >> size;
                step.push_back(std::make_tuple(from, from + size, to - from));
            }
            else if (not step.empty())
            {
                almanac.push_back(std::move(step));
                step = {};
            }
        }
        almanac.push_back(std::move(step));
    }
    input.close();

    return std::make_pair(std::move(seeds), std::move(almanac));
}

int main(void)
{
    Seeds seeds;
    Almanac almanac;
    std::tie(seeds, almanac) = parse_input();

    for (const auto& step : almanac)
    {
        for (auto& seed : seeds)
        {
            for (const auto& map : step)
            {
                if (std::get<0>(map) <= seed and seed < std::get<1>(map))
                {
                    seed += std::get<2>(map);
                    break; // mappings in a step don't overlap
                }
            }
        }
    }

    std::cout << *std::min_element(seeds.begin(), seeds.end()) << std::endl;
    return 0;
}