You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
2.1 KiB
89 lines
2.1 KiB
#include <iostream>
|
|
#include <fstream>
|
|
#include <vector>
|
|
using namespace std;
|
|
|
|
auto parse_input(char *file)
|
|
{
|
|
ifstream input(file);
|
|
if (!input.is_open()) exit(1);
|
|
|
|
vector<string> parsed;
|
|
for (string line; getline(input, line);) {
|
|
parsed.push_back(line);
|
|
}
|
|
return parsed;
|
|
}
|
|
|
|
// Count the occurences of each bit position
|
|
vector<int> count_occurences(vector<string> input)
|
|
{
|
|
vector<int> counts(input[0].length(), 0);
|
|
for (string line : input) {
|
|
for (size_t i = 0; i < line.length(); i++) {
|
|
if (line[i] == '1') counts[i]++;
|
|
if (line[i] == '0') counts[i]--;
|
|
}
|
|
}
|
|
return counts;
|
|
}
|
|
|
|
unsigned part1(auto input)
|
|
{
|
|
vector<int> counts = count_occurences(input);
|
|
|
|
// Convert the counts array into a binary value
|
|
unsigned out = 0;
|
|
for (int i : counts) {
|
|
out <<= 1;
|
|
if (i > 0) out += 1;
|
|
}
|
|
|
|
return out * (out ^ ((1 << counts.size()) - 1));
|
|
}
|
|
|
|
unsigned part2(auto input)
|
|
{
|
|
size_t pos;
|
|
|
|
vector<string> numbers_ox = input;
|
|
pos = 0;
|
|
while (numbers_ox.size() > 1 && pos < input[0].length()) {
|
|
int count = count_occurences(numbers_ox)[pos];
|
|
char bit = (count >= 0) + '0';
|
|
for (size_t i = 0; i < numbers_ox.size(); i++) {
|
|
if (numbers_ox[i][pos] != bit) {
|
|
numbers_ox.erase(numbers_ox.begin()+i);
|
|
i--;
|
|
}
|
|
}
|
|
pos++;
|
|
}
|
|
unsigned ox = stol(numbers_ox[0], NULL, 2);
|
|
|
|
vector<string> numbers_co = input;
|
|
pos = 0;
|
|
while (numbers_co.size() > 1 && pos < input[0].length()) {
|
|
int count = count_occurences(numbers_co)[pos];
|
|
char bit = (count < 0) + '0';
|
|
for (size_t i = 0; i < numbers_co.size(); i++) {
|
|
if (numbers_co[i][pos] != bit) {
|
|
numbers_co.erase(numbers_co.begin()+i);
|
|
i--;
|
|
}
|
|
}
|
|
pos++;
|
|
}
|
|
unsigned co = stol(numbers_co[0], NULL, 2);
|
|
|
|
return ox * co;
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
if (argc <= 1) return 1;
|
|
auto input = parse_input(argv[1]);
|
|
|
|
cout << part1(input) << endl;
|
|
cout << part2(input) << endl;
|
|
}
|
|
|