aboutsummaryrefslogtreecommitdiff
path: root/2016/src/day15.cpp
blob: ced6102d59729c03efe7748ecdc5ace21c8c6b49 (plain)
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
85
86
87
88
89
#include <algorithm>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <regex>
#include <string>
#include <vector>

using namespace std;

namespace {

struct Disc {
	[[nodiscard]]
	bool zeroAtTime(int time) const
	{
		return (time + num + phase) % positions == 0;
	}

	int num;
	int phase;
	int positions;
};

vector<int>
extractNumbers(const string& text)
{
	static const regex number_regex("\\d+");

	vector<int> numbers;
	smatch      match;

	auto searchStart = text.cbegin();
	while ( regex_search(searchStart, text.cend(), match, number_regex) ) {
		numbers.emplace_back(stoi(match.str()));
		searchStart = match.suffix().first;
	}

	return numbers;
}

vector<Disc>
readFile(const filesystem::path& filename)
{
	ifstream     file{ filename };
	vector<Disc> discs;

	for ( string line; getline(file, line); ) {
		auto numbers = extractNumbers(line);
		discs.emplace_back(numbers.at(0), numbers.at(3), numbers.at(1));
	}

	return discs;
}

void
solve(const vector<Disc>& discs)
{
	for ( int time = 0;; ++time ) {
		auto found = ranges::all_of(discs, [&time](const auto& disc) { return disc.zeroAtTime(time); });
		if ( found ) {
			cout << time << '\n';
			return;
		}
	}
}

void
part1(const vector<Disc>& discs)
{
	solve(discs);
}

void
part2(vector<Disc> discs)
{
	discs.emplace_back(discs.size() + 1, 0, 11);
	solve(discs);
}

} // namespace

int
main()
{
	auto discs = readFile("data/day15.txt");
	part1(discs);
	part2(discs);
}