aboutsummaryrefslogtreecommitdiff
path: root/2021/day03/day03.cpp
blob: 036cd0701b113de275b6fbe52f628c2946aa533c (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
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

int bin_to_dec (std::string bin) {
	int dec = 0, pow = 1;
	for (std::size_t i=bin.size(); i > 0; i--) {
		dec += pow * (bin[i-1] == '0' ? 0 : 1);
		pow *= 2;
	}
	return dec;
}

std::vector<int> get_freq (std::vector<std::string> bits) { 
	std::vector<int> freq;
	for (std::size_t i=0; i<bits[0].size(); i++) {
		freq.push_back(0);
	}

	for (auto b : bits) {
		for (std::size_t i=0; i< b.size(); i++) {
		 	freq[i] += (b[i] == '0' ? 0 : 1)*2-1;
		}
	}
	return freq;
}

std::vector<std::string> filter (std::vector<std::string> bits, int inv, int sel) {
	std::vector<std::string> res;
	auto freq = get_freq(bits);

	for (auto b : bits) {
		int f = freq[sel] * inv;
		if (f == 0) f += inv;
		if ((f > 0 ? '0' : '1') == b[sel]) {
			res.push_back(b);
		}
	}

	return res;
}

int main (int argc, char *argv[]) {
	if (argc != 2) return 1;

	std::string raw;
	std::getline(std::ifstream(argv[1]), raw, '\0');

	std::vector<std::string> bits;	

	while (1) {
		auto token = raw.find("\n");
		if (token != std::string::npos) {
			bits.push_back(raw.substr(0, token));
			raw = raw.substr(token+1);
		} else {
			if (raw.size() > 0) bits.push_back(raw);
			break;
		}
	}

	auto freq = get_freq(bits);

	std::string gamma = "", epsilon = "";
	for (std::size_t i=0; i<freq.size(); i++) {
		gamma += freq[i] > 0 ? "1" : "0";
		epsilon += freq[i] > 0 ? "0" : "1";
	}

	int g = bin_to_dec(gamma);
	int e = bin_to_dec(epsilon);
	std::cout << "power level " << e*g << ", "
   		<< "epsilon " << e << " (" << epsilon << "), "
		<< "gamma " << g << " (" << gamma << ")" << std::endl;

	std::vector<std::string> o2 = bits;
	for (std::size_t i=0; i<freq.size(); i++) {
		o2 = filter(o2, 1, i);
		if (o2.size() == 1) break;
	}

	std::vector<std::string> co2 = bits;
	for (std::size_t i=0; i<freq.size(); i++) {
		co2 = filter(co2, -1, i);
		if (co2.size() == 1) break;
	}

	int generator = bin_to_dec(o2[0]);
	int scrubber = bin_to_dec(co2[0]);
	std::cout << "oxigen generator rating " << scrubber*generator << ", "
   		<< "epsilon " << generator << " (" << o2[0] << "), "
		<< "gamma " << scrubber << " (" << co2[0] << ")" << std::endl;

	return 0;
}