mid-kid
3 years ago
6 changed files with 1116 additions and 2 deletions
@ -1 +1,22 @@ |
|||
CXXFLAGS := -std=c++20 -O2 -Wall -Wextra |
|||
|
|||
sources := $(wildcard *.cc) |
|||
progs := $(patsubst %.cc,%,$(sources)) |
|||
|
|||
.PHONY: all |
|||
all: $(progs) |
|||
|
|||
.PHONY: clean |
|||
clean: |
|||
rm -f $(progs) $(progs:=_test.txt) |
|||
|
|||
.PHONY: test |
|||
test: $(addprefix test-,$(progs)) |
|||
|
|||
.PHONY: test-% |
|||
test-%: %_test.txt |
|||
@test -f $*_output.txt && (diff -u $*_output.txt $<; rm -f $<) |
|||
@test -f $*_output.txt || cat $< |
|||
|
|||
$(progs:=_test.txt): %_test.txt: % |
|||
./$< $*_input.txt > $@ |
|||
|
@ -0,0 +1,89 @@ |
|||
#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; |
|||
} |
File diff suppressed because it is too large
@ -0,0 +1,2 @@ |
|||
2595824 |
|||
2135254 |
Loading…
Reference in new issue