aboutsummaryrefslogtreecommitdiff
path: root/2021/day10/day10.cpp
blob: 4fad4ca79842ad497aadffb795e173b1a17e6c44 (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
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
#include <string>
#include <algorithm>

#include "../utils.h"

char map (char a) {
	if (a == '(') return ')';
	if (a == '[') return ']';
	if (a == '{') return '}';
	if (a == '<') return '>';
	return 'A';
}

bool match (char a, char b) {
	if (a == '(' && b == ')') return true;
	if (a == '[' && b == ']') return true;
	if (a == '{' && b == '}') return true;
	if (a == '<' && b == '>') return true;
	return false;
}

int score (char a) {
	if (a == ')') return 3;
	if (a == ']') return 57;
	if (a == '}') return 1197;
	if (a == '>') return 25137;
	return 0;
}

long score (std::string str) {
	long s = 0;
	for (char c : str) {
		s *= 5;
		s += (c == ')' ? 1 : 0);
		s += (c == ']' ? 2 : 0);
		s += (c == '}' ? 3 : 0);
		s += (c == '>' ? 4 : 0);
	}
	return s;
}

bool check (std::string line, std::string &out) {
	std::stack<char> stack;
	for (char c : line) {
		if (c == '(' || c == '[' || c == '{' || c == '<') {
			stack.push(c);
		} else {
			if (!match(stack.top(), c)) {
				out.push_back(c);
				return true;
			} else stack.pop();
		}
	}
	while (!stack.empty()) {
		out.push_back(map(stack.top()));
		stack.pop();
	}
	return false;
}

int main (int argc, char *argv[]) {
	std::string raw;
	std::getline(std::ifstream(argv[1]), raw, '\0');
	std::vector<std::string> lines;
	split(lines, raw, "\n");

	std::vector<long> repairs;
	int sum = 0;
	for (auto line : lines) {
		if (line.size() == 0) continue;
		std::string rep;
		bool corrupt = check(line, rep);
		if (corrupt) sum += score(rep[0]);
		else {
			repairs.push_back(score(rep));
			std::cout << score(rep) << " " << rep << std::endl;
		}
	}
	std::cout << "corrupt score: " << sum << std::endl;
	std::sort(std::begin(repairs), std::end(repairs));
	std::cout << "repairs score: " << repairs[(repairs.size()-1)/2] << std::endl;

	return 0;
}