aboutsummaryrefslogtreecommitdiff
path: root/src/day18.cpp
blob: 3037739a04e8f9ec433b8995ebd4e900876a93cb (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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <fstream>
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

using puzzle_t = vector<pair<long, long>>;

puzzle_t
read_file_part1(string_view filename, long& border_steps)
{
	static map<char, pair<int, int>> movement = {
		{ 'U', { 0, -1 } }, // up
		{ 'D', { 0, 1 } },  // down
		{ 'L', { -1, 0 } }, // left
		{ 'R', { 1, 0 } },  // right
	};

	border_steps = 0;

	fstream  input{ filename };
	puzzle_t data;

	data.emplace_back(0, 0);

	for ( string line; getline(input, line); ) {
		char         dir{};
		long         steps{};
		stringstream sstrm{ line };

		if ( sstrm >> dir >> steps ) {
			data.emplace_back(get<0>(data.back()) + get<0>(movement[dir]) * steps,
			                  get<1>(data.back()) + get<1>(movement[dir]) * steps);

			border_steps += steps;
		}
	}

	return data;
}

puzzle_t
read_file_part2(string_view filename, long& border_steps)
{
	static map<char, pair<int, int>> movement = {
		{ '0', { 1, 0 } },  // right
		{ '1', { 0, 1 } },  // down
		{ '2', { -1, 0 } }, // left
		{ '3', { 0, -1 } }, // up
	};

	border_steps = 0;

	fstream  input{ filename };
	puzzle_t data;

	data.emplace_back(0, 0);

	for ( string line; getline(input, line); ) {
		char         dir{};
		long         steps{};
		string       hexcode;
		stringstream sstrm{ line };

		if ( sstrm >> dir >> steps >> hexcode ) {
			steps = stol(hexcode.substr(2, 5), nullptr, 16);
			dir   = hexcode[7];

			data.emplace_back(get<0>(data.back()) + get<0>(movement[dir]) * steps,
			                  get<1>(data.back()) + get<1>(movement[dir]) * steps);

			border_steps += steps;
		}
	}

	return data;
}

long
shoelace(const puzzle_t& puzzle, const long border_steps)
{
	long area = 0;
	for ( size_t i = 1; i < puzzle.size(); ++i ) {
		const auto [x1, y1] = puzzle[i - 1];
		const auto [x2, y2] = puzzle[i];

		area += (x1 * y2 - y1 * x2);
	}
	return (border_steps + area) / 2 + 1;
}

void
part1()
{
	long border_steps = 0;
	auto puzzle       = read_file_part1("data/day18.txt", border_steps);
	cout << shoelace(puzzle, border_steps) << endl;
}

void
part2()
{
	long border_steps = 0;
	auto puzzle       = read_file_part2("data/day18.txt", border_steps);
	cout << shoelace(puzzle, border_steps) << endl;
}

int
main()
{
	part1();
	part2();
}